Wenn Sie nur die Childs miteinander reden wollen, können Sie MPI.COMM_WORLD
verwenden:
a = MPI.COMM_WORLD.bcast(MPI.COMM_WORLD.Get_rank(), root=0)
Durch Drucken von MPI.COMM_WORLD.Get_rank(), ' of ',MPI.COMM_WORLD.Get_size()
können Sie überprüfen, ob die Kinder MPI.COMM_WORLD
auf die Kinder beschränkt ist.
Jetzt untersuchen wir den Grund, warum comm.bcast(...)
fehlgeschlagen ist, wenn comm
von comm=MPI.Comm.Get_parent()
erhalten wird. Wenn man sich die Größe und die Ränge dieses Kommunikators anschaut, sieht es in der Tat sehr ähnlich zu MPI.COMM_WORLD
aus. Aber im Gegensatz comm
ist sehr verschieden von MPI.COMM_WORLD
: es ist ein intercommunicator. Genauer gesagt ist es die Art, wie ein Elternteil mit seinen Kindern sprechen kann. Kollektive Kommunikationen können verwendet werden, aber alle Prozesse, sowohl der Vater als auch die Kinder, müssen die Funktion aufrufen. Bitte lesen Sie sorgfältig die MPI standards, insbesondere die Abschnitte 5.2.2 und 5.2.3 über Intercommunicator Collective Operations. In Bezug auf bcast()
, MPI.ROOT
und MPI.PROC_NULL
werden anstelle des Rangs des Broadcasters root
verwendet, um die Richtung (Eltern zu Kind des Kindes zu Eltern) und den Sendeprozess anzugeben. Schließlich kann ein Intra-Kommunikator auf der Basis eines Interkommunikators unter Verwendung von Merge()
(entsprechend MPI_Intercomm_merge()
) definiert werden. In diesem Intra- kommunikator gehören Eltern und Kinder nicht zwei verschiedenen Gruppen an: Sie sind wie üblich durch ihren einzigartigen Rang charakterisiert.
Hier sind die modifizierten Versionen von t1.py und t2.py, wo ein bcast()
für einen Interkommunikator durchgeführt wird. Dann wird der Interkommunikator Merge()
und ein bcast()
über den resultierenden Intra-Communicator wie üblich aufgerufen.
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
Ich erinnere mich schwach, dass MPISpawn gibt einen Inter-Communicator im Gegensatz zu den Intra-Kommunikatoren, die wir gewohnt sind (oder andersrum runden). Sie können jedoch einen Typ in den anderen konvertieren. Bitte konsultieren Sie dazu den MPI-Standard. –
Rufen Sie jemals MPI_Finalize() an? In allen Prozessen? –
Ich denke, der Elternprozess muss an der Sendung teilnehmen. –