我使用过MPI代码,并对这些概念有一些基本的想法,但我自己从未做过任何MPI开发。我从并行化一些python代码开始。下面是我尝试做的一些片段:
IMPORT STUFF
...
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
status = MPI.Status()
comm.Barrier()
## CREATE EMPTY ARRAYS
if rank == 0:
t_start=MPI.Wtime()
tt =np.zeros(nt)
ezp=np.zeros(nt)
ezm=np.zeros(nt)
## NUMBER CRUNCHING LOOP
for it in range(rank,nt,comm.size):
...
DO SOMETHING
...
## IF RANK == 0, POPULATE OWN PARTS OF ARRAY
if rank == 0:
tt[ it] = ltt
ezp[it] = lezp
ezm[it] = lezm
if rank > 0:
## IF RANK != 0, SEND DATA TO PROC 0
snddata=[it,ltt,lezp,lezm]
comm.send(snddata, dest=0, tag=13)
else:
# IF RANK == 0, RECEIEVE THE DATA FROM ALL PROCS AND POPULATE
# CORRESPONDING ARRAY ELEMENTS
for src in range(1,comm.size):
rcvdata=comm.recv(source=src,tag=13,status=status)
tt[ rcvdata[0]] = rcvdata[1]
ezp[rcvdata[0]] = rcvdata[2]
ezm[rcvdata[0]] = rcvdata[3]
comm.Barrier()
...
WRITE THE RESULTS tt[:], ezp[:], ezm[:] TO FILE
我用
运行代码mpirun -np 2 python mycode.py ARGUMENTS
问题是,有时循环分解并没有为过程给出相等大小的循环。例如,如果nt=21并且我使用了2个进程,则proc 0循环:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
和proc1循环:
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
因此,对于it=20,进程0一直等待进程1的消息,而进程1没有做任何事情。显然,对于nt和np的任何组合,只要nt%np不等于0,我就会遇到这个问题。
在这种情况下设置通信的好方法是什么?
谢谢!
想到的第一种方法是在一次(或两次)调用中发送所有数据。
-
如果存在"most possible"状态,则接收most possible。发送方将发送它所拥有的,但接收少于请求的也没关系。
-
如果这是不可行的,使用两个消息:一个发送/接收对交换一个int——在下一个消息中期望的值的数量。然后下一条消息有这么多值
你没有明确地问这个问题,但是你的代码以"将结果写入文件"结束。也许你可以避免发送/接收?如果您所做的只是收集第0级的答案,那么您可能希望研究MPI-IO方法,并让每个进程直接写入文件。