我需要使用MPI转置分布在处理器之间的矩阵。目前,我使用MPI_Alltoall
分发数据,使用子数组来指定要发送的块。然后,我需要为3D分布式数组实现类似的索引排列。
但是,我不确定MPI_Alltoall
是否应该与子数组一起使用。
这是一个最小的工作示例,用c ++。
#include <iostream>
#include "mpi.h"
int main(int argc, char* argv[]) {
MPI_Init(&argc, &argv);
int comm_rank;
int comm_size;
MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_size); // assume 2
// local array size
int arr_size[2] = {4, 2};
int sub_size[2] = {2, 2};
int origin[2] = {0, 0};
// column major data
int data[8] = {0 + 8*comm_rank, 1 + 8*comm_rank, 2 + 8*comm_rank, 3 + 8*comm_rank,
4 + 8*comm_rank, 5 + 8*comm_rank, 6 + 8*comm_rank, 7 + 8*comm_rank};
// construct subarray types
MPI_Datatype send_type;
MPI_Datatype recv_type;
MPI_Type_create_subarray(2, arr_size, sub_size, origin,
MPI_ORDER_FORTRAN, MPI_INT, &send_type);
MPI_Type_create_subarray(2, arr_size, sub_size, origin,
MPI_ORDER_FORTRAN, MPI_INT, &recv_type);
MPI_Type_commit(&send_type);
MPI_Type_commit(&recv_type);
// print
std::cout << "- " << comm_rank << " - \n"
<< data[0] << " " << data[4] << '\n'
<< data[1] << " " << data[5] << '\n'
<< data[2] << " " << data[6] << '\n'
<< data[3] << " " << data[7] << '\n';
// transpose data
MPI_Alltoall(data, 1, send_type, data, 1, send_type, MPI_COMM_WORLD);
// print
std::cout << "- " << comm_rank << " - \n"
<< data[0] << " " << data[4] << '\n'
<< data[1] << " " << data[5] << '\n'
<< data[2] << " " << data[6] << '\n'
<< data[3] << " " << data[7] << '\n';
MPI_Finalize();
}
使用mpic++ mpitest.cpp -o mpitest
进行编译,并使用mpirun -np 2 ./mpitest
运行
- 1 -
8 12
9 13
10 14
11 15
- 0 -
0 4
1 5
2 6
3 7
- 0 -
0 4
1 5
2 6
3 7
- 1 -
203412040 2
1 2
10 14
11 15
其中实际上没有数据交换排名为0,而某些数据损坏排名为1。
我的问题是我是否可以使用MPI_Alltoall
的mpi子数组,或者我是否需要自己处理基础数据布局。