2016-05-11 20 views
0

我編寫以下代碼AllGather()實驗:爲什麼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]] 0

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

我不明白爲什麼第二個處理器卡住了。如果我在兩個處理器中設置了= 2 ,它會正確運行。我究竟做錯了什麼?

回答

1

第二個進程卡住了,因爲它試圖從所有進程中收集,第二個進程正在等待第一個在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]]] 1

+0

啊,我現在看到了!我也試過z = comm.gather(z,root = rank),但也失敗了。有關於此的任何想法? – SpiderRico

+0

「收集」功能只是將所有進程中的數據收集在一箇中,這意味着您仍然必須發送每個進程中的數據,但只有一個收件人。我知道,命名有點混亂。可悲的是,mpi4py並不完全具有良好的文檔,請看看:http://mpi4py.readthedocs.io/en/stable/overview.html 如果你想找的東西沒有記錄在那裏,請看看MPI的C-API。 – H2O

相關問題