我使用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)
答案 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)