我编写了以下代码来试验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,它会正确运行 在两个处理器中。我做错了什么?
答案 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