如果每個過程知道要發送的消息的數量,下面的步驟可以被設計爲解決該問題:
1)減少消息的數量將被髮送到根的過程。每個進程都會向根發送稍後將發送的消息數。此操作被稱爲還原,它可以由函數comm.reduce(...)
2)來執行接收所有工藝0
在這裏,消息是基於你應該做的伎倆的碼。它可以通過mpirun -np 4 python main.py
#passRandomDraw.py
import numpy
from mpi4py import MPI
from mpi4py.MPI import ANY_SOURCE
import numpy as np
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
#just in case, if numpy.random is seed with
np.random.seed(np.random.randint(np.iinfo(np.uint32).min,np.iinfo(np.uint32).max)+rank)
if rank == 0:
randNum = numpy.zeros(1)
print "Process before receiving random numbers"
nb=np.empty((1,),dtype=int)
nb0=np.zeros((1,),dtype=int)
comm.Reduce([nb0, MPI.INT],[nb, MPI.INT],op=MPI.SUM, root=0) #sums the total number of random number from every process on rank 0, in nb.
#print "rank"+str(rank)+" nb "+str(nb)
else:
nb=np.empty((1,),dtype=int)
nb[0]=np.random.randint(1,10)
#print "rank"+str(rank)+" nb "+str(nb)
comm.Reduce([nb, MPI.INT],None,op=MPI.SUM, root=0)
for i in range(0,nb[0],1):
randNum = numpy.zeros(1)
randNum = numpy.random.random_sample(1)
print "Process", rank, "iteration", i, "drew the number", randNum[0]
comm.Send(randNum, dest=0)
if rank == 0:
for i in range(nb[0]): #receives nb message, each one with its int.
comm.Recv(randNum, ANY_SOURCE)
print "Process", rank, "received the number", randNum[0]
跑出按照documentation of numpy.random()
Mersenne扭曲僞隨機數生成器最初由從/dev/urandom
提取的號碼(或Windows類似物)接種如果可用或種子從否則時鐘。因此,在最後一種情況下,所有進程都可以接收相同的種子並生成相同的隨機數。爲防止這種情況發生,我添加了以下行:
np.random.seed(np.random.randint(np.iinfo(np.uint32).min,np.iinfo(np.uint32).max)+rank)
只是爲了澄清/確認。我是否正確地假設你沒有機會事先知道每個級別將發送多少消息,即使是在等級本身上? – Zulan
理想情況下,我想從每個等級發送消息,而不必知道等級將發送多少消息。如果這是不可能的,則可以在等級內計算將發送多少消息,但這對每個等級都是不同的。 – 218