0

私は MPI コードを使用したことがあり、概念の基本的な考え方はいくつかありますが、自分で MPI 開発を行ったことはありません。Pythonコードのいくつかを並列化することから始めています。ここに私がやろうとしていることのスニペットがあります:

IMPORT STUFF
...
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
status = MPI.Status()
comm.Barrier()
## CREATE EMPTY ARRAYS
if rank == 0:
   t_start=MPI.Wtime()
   tt =np.zeros(nt)
   ezp=np.zeros(nt)
   ezm=np.zeros(nt)
## NUMBER CRUNCHING LOOP
for it in range(rank,nt,comm.size):
   ...
   DO SOMETHING
   ...
## IF RANK == 0, POPULATE OWN PARTS OF ARRAY
   if rank == 0:
      tt[ it] = ltt
      ezp[it] = lezp
      ezm[it] = lezm
   if rank > 0:
   ## IF RANK != 0, SEND DATA TO PROC 0
      snddata=[it,ltt,lezp,lezm]
      comm.send(snddata, dest=0, tag=13)
   else:
#  IF RANK == 0, RECEIEVE THE DATA FROM ALL PROCS AND POPULATE
#  CORRESPONDING ARRAY ELEMENTS
      for src in range(1,comm.size):
         rcvdata=comm.recv(source=src,tag=13,status=status)
         tt[ rcvdata[0]] = rcvdata[1]
         ezp[rcvdata[0]] = rcvdata[2]
         ezm[rcvdata[0]] = rcvdata[3]
comm.Barrier()
...
WRITE THE RESULTS tt[:], ezp[:], ezm[:] TO FILE

私はコードを実行します

mpirun -np 2 python mycode.py ARGUMENTS

問題は、ループ分解によってプロシージャーのループのサイズが等しくならない場合があることです。たとえば、nt=21 で 2 つの proc を使用すると、proc 0 がループします。

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

そしてproc 1ループオーバー:

[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

したがって、it=20 の場合、proc 0 は、何もしていない proc 1 からの通知を待機し続けます。明らかに、nt%np=0 を持たない nt と np の組み合わせでは、この問題が発生します。

このような場合、どのように通信を設定するのが良いでしょうか?

ありがとう!

4

1 に答える 1

0

頭に浮かぶ最初のアプローチは、すべてのデータを 1 回 (または 2 回) の呼び出しで送信することです。

  • 「可能性が最も高い」状態がある場合は、可能性が最も高い状態を受け取ります。送信者は持っているものを送信しますが、要求されたよりも少ないものを受信して​​も問題ありません。

  • それが不可能な場合は、2 つのメッセージを使用します。1 つの送信/受信ペアが int を交換します。つまり、次のメッセージで期待される値の数です。次に、次のメッセージにはその数の値があります。

これを明示的に要求しませんでしたが、コードは「結果をファイルに書き込む」で終わります。送受信をまとめて回避できるのではないでしょうか?ランク 0 への回答を収集するだけの場合は、MPI-IO アプローチを調べて、各プロセスがファイルに直接書き込むようにすることをお勧めします。

于 2015-10-27T16:10:11.447 に答える