mpi4py:在生成的进程之间进行通信

mpi4py: Communicating between spawned processes

我有一个进程 运行 正在运行一个名为 t1.py 的程序,该程序会生成 3 个其他进程,所有这些 运行 t2.py。我想从等级为 0 的衍生进程向其他两个衍生进程广播一个值。但是,当调用 bcast 时,程序会阻塞。知道为什么会这样吗?我该如何解决?

t1.py

from mpi4py import MPI
import sys

sub_comm = MPI.COMM_SELF.Spawn(sys.executable, args=['t2.py'], maxprocs=3)
print 'hi'

t2.py

from mpi4py import MPI

comm = MPI.Comm.Get_Parent()

print 'ho ', comm.Get_rank()
a = comm.bcast(comm.Get_rank(), root=0)
print a

输出

hi
ho  2
ho  0
ho  1

如果你只是想让孩子们互相交谈,你可以使用MPI.COMM_WORLD:

a = MPI.COMM_WORLD.bcast(MPI.COMM_WORLD.Get_rank(), root=0)

通过打印MPI.COMM_WORLD.Get_rank(), ' of ',MPI.COMM_WORLD.Get_size(),您可以检查子MPI.COMM_WORLD是否仅限于子

现在,我们来研究一下comm=MPI.Comm.Get_parent()得到commcomm.bcast(...)失败的原因。确实,看这个通讯器的大小和等级,和MPI.COMM_WORLD很像。 但是,相反,commMPI.COMM_WORLD 非常不同:它是一个 intercommunicator. More precisely, it is the way a parent can talk to its childs. Collective communications can be used, but all processes, both the parent and its childs, must call the function. Please carrefully read the MPI standards, in particular the sections 5.2.2 and 5.2.3 about Intercommunicator Collective Operations. Regarding bcast(), MPI.ROOT and MPI.PROC_NULL are used instead of the rank of the broadcaster root to specify the direction (parent to child of child to parent) and the sending process. Lastly, an intracommunicator can be defined on the base of an intercommunicator by using Merge() (corresponding to MPI_Intercomm_merge())。在这个 intracommunicator 中,parents 和 childs 不属于两个不同的组:像往常一样,它们是具有独特等级特征的进程。

这里是 t1.py 和 t2.py 的修改版本,其中执行了一个 bcast() 的内部通信器。然后内部通信器是 Merge() 并且像往常一样调用结果内部通信器上的 bcast()

t1.py

from mpi4py import MPI
import sys

sub_comm = MPI.COMM_SELF.Spawn(sys.executable, args=['t2.py'], maxprocs=3)

val=42
sub_comm.bcast(val, MPI.ROOT)

common_comm=sub_comm.Merge(False)
print 'parent in common_comm ', common_comm.Get_rank(), ' of  ',common_comm.Get_size()
#MPI_Intercomm_merge(parentcomm,1,&intracomm);

val=13
c=common_comm.bcast(val, root=0)
print "value from rank 0 in common_comm", c

t2.py

from mpi4py import MPI

comm = MPI.Comm.Get_parent()

print 'ho ', comm.Get_rank(), ' of  ',comm.Get_size(),' ', MPI.COMM_WORLD.Get_rank(), ' of  ',MPI.COMM_WORLD.Get_size()
a = MPI.COMM_WORLD.bcast(MPI.COMM_WORLD.Get_rank(), root=0)
print "value from other child", a

print "comm.Is_inter", comm.Is_inter()
b = comm.bcast(comm.Get_rank(), root=0)
print "value from parent", b

common_comm=comm.Merge(True)
print "common_comm.Is_inter", common_comm.Is_inter()
print 'common_comm ', common_comm.Get_rank(), ' of  ',common_comm.Get_size()

c=common_comm.bcast(0, root=0)
print "value from rank 0 in common_comm", c