【发布时间】:2018-11-22 19:22:29
【问题描述】:
我使用mpirun -n 40 python script.py 运行下面的脚本。目的是并行化函数func。这里发生的是 40 个“工人”池被分成 5 个块,每块 8 个“工人”(当然每个块都有自己的颜色)。
我为每个块生成参数(gen_args)并将它们展平为一维 numpy 数组。然后我使用 ScatterV 将这个扁平数组分散到 one 块中的“工人”。分散的值被变量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)
【问题讨论】:
-
color=0在前 8 个任务上,所以recv_args在这里应该为零。如果你block_size=2运行 4 个任务怎么办?你能上传输出吗?请注意,严格来说这不是minimal reproducible example,因为您不验证输出(例如recv_args)。mpi4py建立在哪个 MPI 库之上? -
@GillesGouaillardet 你是对的,该链接的答案对我有帮助。我以为我在拆分方面做错了,但问题出在我的 numpy 数组的自动数据类型上。我总是不得不强迫他们使用 numpy.float64。
标签: python python-3.x mpi mpi4py