3

我正在尝试使用 C++ 在超立方体网络上实现 All-To-All(即 MPI_Allgather)操作。

例如,对于 n(即处理器数量)= 8,我将初始数据存储为

p0: [00, 01, 02, ..., 07]; 
p1: [10, 11, 12, ..., 17],
...
... 
p7: [70, 71, 72, ..., 77]. 

最终在运行 All-To-All 之后,数据应该变成

p0: [00, 10, 20, ..., 70], 
P1: [01, 11, 21, ..., 71],
..., 
p7: [07, 17, 27, ..., 77]. 

(换句话说,每个处理器都从其他人那里获取数据)。

我虽然使用一些掩码和循环的算法,其中涉及在两个处理器之间交换数据的步骤,例如,将 p0 的最后 4 个元素与 p3 的前 4 个元素交换(将 p0 的最后 4 个元素发送到 p3 并发送前 4 个元素p3 到 p0)。使用 MPI_Send 和 MPI_Recv 无法实现这一点,因为接收者的半数组在发送数据之前将被覆盖。谁能帮助我用什么技术来做到这一点?我考虑过使用中间缓冲区,但仍然不确定如何编写发送和接收 MPI 代码。

或者,如果有人可以告诉我实现 All-to-All 的任何其他方式。非常感谢。非常感谢!

4

1 回答 1

1

MPI 中的 All-to-all 由MPI_ALLTOALL或执行MPI_ALLTOALLV。常规调用需要两个不同的缓冲区来发送和接收数据。MPI 标准还为这两种操作定义了“就地”选项。在您的情况下,此代码应该这样做:

double p[8];

MPI_Alltoall(MPI_IN_PLACE, 1, MPI_DOBLE,  // send count and datatype are ignored
             p, 1, MPI_DOUBLE,
             MPI_COMM_WORLD);

不幸的是,一些 MPI 实现不支持这种“就地”模式。一个值得注意的例子是 Open MPI。MPICH2 支持它。

这是实现它的一种方法:MPICH2 alltoall.c

于 2012-10-31T09:29:41.470 回答