在MPI中,如何传达“a”的一部分;“共享”;所有其他级别的数组?

在MPI中,如何传达“a”的一部分;“共享”;所有其他级别的数组?,mpi,broadcast,Mpi,Broadcast,我有一个MPI程序和一些数据数组。每个等级都需要所有阵列来完成其工作,但只能在阵列的一个补丁上工作。在一个计算步骤之后,我需要每个列组将其计算出的数组块传递给所有其他列组 如何有效地实现这一目标? 在伪代码中,我将这样做作为第一种方法: if rank == 0: // only master rank initialise_data() end if MPI_Bcast(all_data,0) // from master to every rank compute which par

我有一个MPI程序和一些数据数组。每个等级都需要所有阵列来完成其工作,但只能在阵列的一个补丁上工作。在一个计算步骤之后,我需要每个列组将其计算出的数组块传递给所有其他列组

如何有效地实现这一目标?

在伪代码中,我将这样做作为第一种方法:

if rank == 0: // only master rank
  initialise_data()
end if

MPI_Bcast(all_data,0) // from master to every rank

compute which part of the data to work on

for ( several steps ): // each rank
  execute_computation(part_of_data)

  for ( each rank ):
    MPI_Bcast(part_of_data, rank_number) // from every rank to every rank
  end for
end for
缺点是广播的数量与等级一样多,即障碍。那么,我将如何替换MPI_BCAST


编辑:我可能找到了一个提示。。。我要找的是MPI\u Allgather吗?

是的,您要找的是
MPI\u Allgather
。请注意,
recvcount
不是整个接收缓冲区的长度,而是从一个进程接收的数据量。类似地,在
MPI\u allgatrov
recvcount[i]
中,是您希望从第i个进程接收的数据量。此外,
recvcount
应等于(而不是小于)相应的
sendcount
。我在我的implementation(OpenMPI)上测试了它,如果我尝试接收较少的发送元素,我会得到
MPI\u ERR\u TRUNCATE
error

此外,在一些罕见的情况下,我使用了
MPI\u Allreduce
。例如,如果我们有以下阵列:

process0: AA0000
process1: 0000BB
process2: 00CC00

然后我们可以使用
MPI\u SUM
操作进行所有reduce,并在所有过程中获得
AACCBB
。显然,同样的技巧可以用1代替0,用
MPI\u PROD
代替
MPI\u SUM

是的,您正在寻找
MPI\u Allgather
。请注意,
recvcount
不是整个接收缓冲区的长度,而是从一个进程接收的数据量。类似地,在
MPI\u allgatrov
recvcount[i]
中,是您希望从第i个进程接收的数据量。此外,
recvcount
应等于(而不是小于)相应的
sendcount
。我在我的implementation(OpenMPI)上测试了它,如果我尝试接收较少的发送元素,我会得到
MPI\u ERR\u TRUNCATE
error

此外,在一些罕见的情况下,我使用了
MPI\u Allreduce
。例如,如果我们有以下阵列:

process0: AA0000
process1: 0000BB
process2: 00CC00

然后我们可以使用
MPI\u SUM
操作进行所有reduce,并在所有过程中获得
AACCBB
。显然,同样的技巧也可以用1代替0,用MPI_PROD代替MPI_SUM。。。还有一个问题:recvcount是否总是与sendcount相同?还有一条评论:我不能使用Allreduce,因为在其他字段中有“旧”数据。当然我可以设置为0…@steffen我更新了答案。是的,它应该总是相同的,否则你会得到错误。现在,我也在MPICH上测试了它,得到了相同的错误。如果阵列的修补程序在不同的进程中具有不同的大小,请使用allgatherv,但保持第i个进程的
recvcount[i]
等于
sendcount
。为此目的使用allreduce是非常少见的,在大多数情况下,它的工作速度比allgather慢。如果缓冲区中有“旧”数据,当然不应该使用它。发送的基本数据项的数量应该与接收的基本数据项的数量相匹配,而不是
sendcount
recvcount
的值。例如,可以发送100个
MPI_INT
元素,并接收由100个
MPI_INT
元素组成的用户定义向量类型的1个元素。确定。。。还有一个问题:recvcount是否总是与sendcount相同?还有一条评论:我不能使用Allreduce,因为在其他字段中有“旧”数据。当然我可以设置为0…@steffen我更新了答案。是的,它应该总是相同的,否则你会得到错误。现在,我也在MPICH上测试了它,得到了相同的错误。如果阵列的修补程序在不同的进程中具有不同的大小,请使用allgatherv,但保持第i个进程的
recvcount[i]
等于
sendcount
。为此目的使用allreduce是非常少见的,在大多数情况下,它的工作速度比allgather慢。如果缓冲区中有“旧”数据,当然不应该使用它。发送的基本数据项的数量应该与接收的基本数据项的数量相匹配,而不是
sendcount
recvcount
的值。例如,您可以发送100个
MPI\u INT
元素,然后接收由100个
MPI\u INT
元素组成的用户定义向量类型的1个元素。您要查找的是
MPI\u Allgather
(或者
MPI\u Allgatherv
,如果块大小不同)就地模式。您要查找的是就地模式下的
MPI\u Allgather
(或者
MPI\u Allgatherv
,如果块大小不同)。