mpi4py - 如何避免通讯阻止

时间:2015-10-25 16:53:49

标签: python parallel-processing communication mpi4py

我使用过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

问题是有时循环分解不会为procs提供相同大小的循环。例如。如果nt = 21并且我使用2个proc,则proc 0循环遍历:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

和proc 1循环遍历:

[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

因此,对于它= 20,proc 0一直等待从proc 1听到没有做任何事情。显然,对于没有nt%np = 0的nt和np的任何组合,我遇到了这个问题。

在这种情况下设置通信的好方法是什么?

谢谢!

1 个答案:

答案 0 :(得分:0)

首先想到的方法是在一次(或两次)调用中发送所有数据。

  • 如果有最可能的""国家,然后收到最可能的。发件人将发送它拥有的内容,但收到的请求少于请求。

  • 如果这不可行,请使用两条消息:一个发送/接收对交换一个int - 下一条消息中预期的值数。然后下一条消息就有很多值。

您没有明确询问此问题,但您的代码以&#34结尾;将结果写入文件"。也许你可以完全避免发送/接收?如果你所做的只是收集排名0的答案,也许你想要研究MPI-IO方法并让每个进程直接写入文件。