2016-05-11 8 views
0

私はAllGatherで実験するには、次のコード()コード化されました:次のように私はそれを実行異なる繰り返し値を持つforループでAllGather()が失敗するのはなぜですか?

from mpi4py import MPI 

comm = MPI.COMM_WORLD 
rank = comm.Get_rank() 

a = None 
if rank == 0: 
    a = 2 
if rank == 1: 
    a = 3 
z = 2 
for i in range(0, a): 
    z = comm.allgather(z) 

print(z, rank) 
comm.barrier() 

を:

のmpiexec -n 2のpython3 allgather.py

私が手次の出力:

[[2,2]、[2,2]] 0

2番目のプロセッサがスタックしており、プログラムが終了しません。

出力は次のようになります

[2,2]、[2,2] 0

[2,2]、[2,2]、[2,2 ]] 1

なぜ2番目のプロセッサーがスタックしているのか分かりません。両方のプロセッサで= 2 を設定すると正しく動作します。私は間違って何をしていますか?

答えて

1

すべてのプロセスから収集しようとしているために2番目のプロセスが停止し、2番目のプロセスは最初にallgather()オペレーションでそのプロセスに参加するのを待機しており、無期限に待機します。

実用的なアプリケーションを知らなくてもこれを修正する良い方法を伝えるのは難しいです。 しかし、一般的に、すべてのプロセスが集まる操作に参加する必要がありますが、簡単な修正だけで結果を使用せずに、プロセス0相伴をさせることです。

from mpi4py import MPI 

comm = MPI.COMM_WORLD 
rank = comm.Get_rank() 

a = None 
if rank == 0: 
    a = 2 
if rank == 1: 
    a = 3 
z = 2 
old_z = None 
for i in range(0, a): 
    if i == a-1: 
     old_z = z 
    z = comm.allgather(z) 

if rank == 0: 
    comm.allgather(old_z) 

print(z, rank) 
comm.barrier() 

は、これは非常にエレガントなソリューションではありませんが、それはあなたの所望の出力を提供してい。以前のプロセスの反復処理からzの値を保存して、目的の動作に近いものを取得しなければならなかったことに注意してください。

我々は、zの前の値を格納しない場合、我々は次のような結果を得る:

[[2、2]、[2、2]] 0

[[[2、 2]、[2,2]]、[[2,2]、[2,2]]]

+0

ああ、私は今それを参照してください!私もz = comm.gather(z、root = rank)を試しましたが失敗します。その上の任意のアイデア? – SpiderRico

+0

'' gather''とは、1つのプロセスすべてからデータを収集するだけです。つまり、それぞれのプロセスで送信する必要がありますが、受信者は1人だけです。私は知っている、命名は少し混乱している。悲しいことに、mpi4pyには正確な文書はありません。http://mpi4py.readthedocs.io/en/stable/overview.html あなたが探しているものがあれば、そこには書かれていません。 MPIのC-API – H2O

関連する問題