MPI Scatterv到" sub" -communicator(使用COMM_WORLD.Split())无法按预期工作

时间:2018-06-13 09:10:30

标签: python python-3.x mpi mpi4py

我使用mpirun -n 40 python script.py运行下面的脚本。目的是并行化函数func。这里发生的是40名工人和#34;被分为5个街区的8个工人" (每个街区都有自己的颜色)。 我为每个块生成参数(gen_args)并将它们展平为1D numpy数组。然后我使用ScatterV将这个扁平化的数组分散到" worker"在一个块中。散乱值在变量recv_args中捕获。

一切运作良好(基于我见过的打印输出),除了block_comm.Scatterv([send_data,counts,displacement, MPI.DOUBLE], recv_args, root=0)以某种方式它将recv_args的所有数组元素(在所有等级中)设置为零(请记住,它们是是最初在所有级别的人) 我在这里缺少什么?

这是MCVE:

import numpy as np
from mpi4py import MPI

def func(arg1, arg2,arg3):
  return arg1+arg2+arg3

def gen_args(const, n_iter):     #More complicated ofcourse in reality
  return const*np.arange(n_iter*3).reshape((n_iter,3))

if __name__ == '__main__':
    world_comm = MPI.COMM_WORLD
    world_size = world_comm.Get_size()    #  normally 40
    world_rank = world_comm.Get_rank()

    block_size = 8
    blocks = int(world_size/block_size)

    color = int(world_rank/block_size)
    key = int(world_rank%block_size)

    block_comm = world_comm.Split(color,key)
    #Effectively world_comm (size=40) is now split in 5 blocks of size=8

    block_rank = block_comm.Get_rank()
    print("WORLD RANK/SIZE: {}/{} \t BLOCK RANK/SIZE: {}/{}".format(world_rank, world_size, block_rank, block_size))

    recv_args= np.ones(3)
    counts = tuple(np.ones(block_size)*3)
    displacement = tuple(np.arange(block_size)*3)

    if block_rank==0:
      send_data = gen_args(color, block_size).flatten()
      print(send_data)
    else:
      send_data = None

    block_comm.Scatterv([send_data,counts,displacement, MPI.DOUBLE], recv_args, root=0)
    print(block_rank,recv_args)

1 个答案:

答案 0 :(得分:0)

问题在于send_data和recv_args的数据类型(这里也可以看到:How to scattering a numpy array in python using comm.Scatterv)。当我将数据类型声明为Scatterv的MPI.DOUBLE时,它们必须是数据类型np.float64。

进行了以下更改:

def gen_args(const, n_iter):  
  return const*np.arange(n_iter*3,dtype=np.float64).reshape((n_iter,3))

recv_args= np.ones(3,dtype=np.float64)