【问题标题】:MPI Scatterv to a "sub"-communicator (using COMM_WORLD.Split() ) does not work as expected [duplicate]MPI Scatterv 到“子”通信器(使用 COMM_WORLD.Split() )无法按预期工作[重复]
【发布时间】: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


【解决方案1】:

问题在于 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)

【讨论】:

    猜你喜欢
    • 2020-04-23
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多