繁体   English   中英

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.bcast(...)失败的原因,如果comm是通过comm=MPI.Comm.Get_parent() 实际上,通过查看此通信器的大小和等级,它看起来与MPI.COMM_WORLD非常相似。 但是,恰恰相反, commMPI.COMM_WORLD非常不同:它是一个互通者 更确切地说,这是父母可以与孩子交谈的方式。 可以使用集体通信,但所有进程(父进程及其子进程)都必须调用该函数。 请仔细阅读MPI标准 ,特别是关于Intercommunicator Collective Operations的5.2.2和5.2.3节。 关于bcast() ,使用MPI.ROOTMPI.PROC_NULL而不是广播者root的等级来指定方向(子到父的子节点)和发送过程。 最后,可以使用Merge() (对应于MPI_Intercomm_merge() )在内部通信器的基础上定义一个内部通信器。 在这个内部通信器中,父母和孩子不属于两个不同的群体:他们是像往常一样以其独特等级为特征的过程。

以下是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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM