Eyo*_*aye 2 python mpi python-2.7 mpi4py
我有一个进程运行一个名为 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'
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
输出
hi
ho 2
ho 0
ho 1
Run Code Online (Sandbox Code Playgroud)
如果你只是想让孩子们互相交谈,你可以使用MPI.COMM_WORLD
:
a = MPI.COMM_WORLD.bcast(MPI.COMM_WORLD.Get_rank(), root=0)
Run Code Online (Sandbox Code Playgroud)
通过打印MPI.COMM_WORLD.Get_rank(), ' of ',MPI.COMM_WORLD.Get_size()
,您可以检查孩子MPI.COMM_WORLD
是否仅限于孩子。
现在,让我们调查comm.bcast(...)
失败的原因ifcomm
是由 获得的comm=MPI.Comm.Get_parent()
。的确,从这个通讯器的大小和级别来看,它似乎与MPI.COMM_WORLD
. 但是,恰恰相反,comm
它非常不同MPI.COMM_WORLD
:它是一个互通者。更准确地说,这是父母与孩子交谈的方式。可以使用集体通信,但所有进程,包括父进程和它的子进程,都必须调用该函数。请仔细阅读MPI 标准,特别是关于 Intercommunicator Collective Operations 的 5.2.2 和 5.2.3 节。关于bcast()
,MPI.ROOT
和MPI.PROC_NULL
用于代替广播公司的等级root
指定方向(父到子的子到父)和发送过程。最后,可以通过使用Merge()
(对应于MPI_Intercomm_merge()
)在内部通信器的基础上定义内部通信器。在这个内部沟通者中,父母和孩子不属于两个不同的群体:他们是以其独特的等级为特征的过程,像往常一样。
以下是 t1.py 和 t2.py 的修改版本,其中执行了bcast()
用于内部通信器的 a。然后内部通信器是,Merge()
并且bcast()
像往常一样调用生成的内部通信器上的a 。
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1326 次 |
最近记录: |