各プロセスが送信するメッセージの数を知っている場合は、以下の手順で問題が解決するように設計することができる。
1)ルートプロセスに送信されるメッセージの数を減らします。各プロセスは、後に送信するメッセージの数をルートに送信します。この操作は、削減と呼ばれ、それはトリックを行う必要があり、あなたに基づいてコードがある。ここ
プロセス0上のすべてのメッセージを受信機能comm.reduce(...)
2)により行うことができます。これは、そうでない場合、クロックから入手可能であるか、またはシードdocumentation of numpy.random()
メルセンヌツイスター擬似乱数生成器が最初/dev/urandom
から抽出された数(またはWindowsアナログ)によって播種される場合による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]
によって実行することができます。したがって、最後のケースでは、すべてのプロセスが同じシードを受け取り、同じ乱数を生成することができます。これを防ぐため、次の行を追加しました:
np.random.seed(np.random.randint(np.iinfo(np.uint32).min,np.iinfo(np.uint32).max)+rank)
明確にする/確認するだけです。ランク自体でも、各ランクがどれくらいのメッセージを送信するかを手前で知る機会がないと仮定していますか? – Zulan
理想的には、ランクが送信するメッセージの数を知らなくても、各ランクからメッセージを送信したいと考えています。これが不可能な場合、ランク内で送信されるメッセージの数を計算することは可能ですが、これは各ランクごとに異なります。 – 218