为什么AllGather()无法使用不同的迭代值进行循环?

时间:2016-05-11 21:35:35

标签: python parallel-processing mpi mpi4py

我编写了以下代码来试验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

我看不出为什么第二个处理器卡住了。如果我设置a = 2,它会正确运行 在两个处理器中。我做错了什么?

1 个答案:

答案 0 :(得分: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