Мне нужно транспонировать матрицу, распределенную по процессорам, используя MPI. В настоящее время я использую MPI_Alltoall
для распространения данных и подмассивы для указания блоков, которые будут отправляться. Затем мне потребуется реализовать аналогичную перестановку индексов для трехмерного распределенного массива.
Однако я не уверен, должен ли 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 с MPI_Alltoall
, или мне нужно самостоятельно обрабатывать базовый макет данных.