2018年2月1日木曜日

mpi4pyを使い、pythonでMPIプログラミング

PythonでMPIを使うライブラリとして、mpi4pyがあります。
その使い方を簡単に紹介します。

インストールは、例えばUbuntuなら以下のようにインストールできます。

$ sudo apt-get install python-mpi4py

mpi4pyを使ったプログラムについて紹介していきます。

from mpi4py import MPI

comm = MPI.COMM_WORLD

rank = comm.Get_rank()
print("rank " + str(rank))

numCores = comm.Get_size()
print("num cores " + str(numCores))

MPI.COMM_WORLDを実行すると、並列処理が始まります。
Get_rankメソッドで、スレッドのID (rank)を取得できます。IDは0始まりです。

if rank == 0:
  xxxx
else:
  yyyy

このように、スレッドIDに応じて処理を分けることができます。
また、Get_sizeメソッドで、いくつのスレッドが実行されているかを取得できます。

スレッド間で同期を取りたい場合は、barrierメソッドを使います。

comm.barrier()

これで、スレッドの処理がここ(barrierメソッドの内部)でいったん止まります。全てのスレッドが、barrierメソッドを呼び出すまで、処理が先に進みません。全てのスレッドがここに到達すると、せーので全スレッドが次の処理に向けて動き出します。

スレッド間でデータを交換する方法として最も単純なのは、sendメソッドとrecvメソッドです。

if rank == 0:
   data1 = 50
   comm.send(data1, dest=1, tag=23)
if rank == 1:
   data2 = comm.recv(source=0, tag=23)

sendメソッドで、データを送れます。上の例では、data1という変数を送っています。どのスレッドに送るかは、IDで指定します。上の例だと、スレッド0からスレッド1に送っています。tagは、交換するデータのIDです。たくさんのデータをやりとりする場合はデータにIDを振っておくと、recvする側は、受け取りたいデータを指定して受け取れます。

recvメソッドでデータを受け取ります。誰から受け取るかを、引数sourceで指定します。上の例だと、スレッド0からのデータ(ID=23)を受け取ろうとします。

これで、スレッド1の変数data2には、50という値が格納されます。

mpi4pyを使ったプログラムは、以下のようにmpiexecコマンドを使って実行できます。
以下は、run-mpi-app.pyというプログラムを、4スレッドで実行する例になります。

mpiexec -n 4 python run-mpi-app.py

0 件のコメント:

コメントを投稿

JavaScriptで10進数と16進数を変換する方法

JavaScriptで10進数と16進数を変換する方法を紹介します。 まず、16進数を、10進数に変換する方法です。 以下のサンプルコードでは、16進数の"DB"や"0A"を、10進数に変換しています。 var a = pa...