Используйте MPI_Scatterv для рассеяния перекрывающихся областей массива
У меня есть представление 1D-массива 2D-массива: ниже приведен пример 6x6:
[00000012300456700890100234500000] => [------]
[|0123|]
[|4567|]
[|8901|]
[|2345|]
[------]
Типичный размер будет 514 * 514 элементов (512 + 2 ячейки гало). Я должен распределить данные между, скажем, четырьмя процессорами:
Rank 0: Rank 1: Rank 2: Rank 3:
[----] [----] [|456] [567|]
[|012] [123|] [|890] [901|]
[|456] [567|] [|234] [345|]
[|890] [901|] [----] [----]
то есть таким образом, что крайняя правая часть данных, которая переходит в ранг 0, также должна перейти в левую часть данных, идущую в ранг 1, и так далее со всеми другими парами соседей.
Я знаю, как создать тип данных размером 4x4, но не знаю, как повторно отправить последний элемент этого массива в качестве начала нового элемента в другой ранг.
Как я могу распространять данные с таким перекрытием?
=== РЕДАКТИРОВАТЬ ===
После использования вашей реализации этого Джонатон ...
Я пытаюсь сделать это в настоящее время с массивом символов (2D), но я получаю «мусор» при сборе их из процессоров / рангов. Я изменил тип и все, но не могу понять, где проблема в данный момент.
void distributeBySend_c(unsigned char **global, const int globalrows, const int globalcols,
const int localrows, const int localcols,
const int rank, const int size,
MPI_Comm cartcomm, const int dims[2], const int coords[2]) {
MPI_Request reqs[dims[0]*dims[1]];
const int tag = 1;
if (rank == 0) {
MPI_Datatype block;
int starts[2] = {0,0};
int subsizes[2] = {localrows, localcols};
int sizes[2] = {globalrows, globalcols};
MPI_Type_create_subarray(2, sizes, subsizes, starts, MPI_ORDER_C, MPI_CHAR, &block);
MPI_Type_commit(&block);
int reqno=0;
for (int i=0; i<dims[0]; i++) {
int startrow = i*datasize;
int destcoords[2];
destcoords[0] = i;
for (int j=0; j<dims[1]; j++) {
int startcol = j*datasize;
destcoords[1] = j;
int dest;
MPI_Cart_rank(cartcomm, destcoords, &dest);
MPI_Isend(&(global[startrow][startcol]), 1, block, dest, tag, cartcomm, &reqs[reqno++]);
}
}
}
unsigned char **local = alloc2dImage(localrows, localcols);
MPI_Recv(&(local[0][0]), localrows*localcols, MPI_CHAR, 0, tag, cartcomm, MPI_STATUS_IGNORE);
if (rank == 0)
MPI_Waitall(dims[0]*dims[1], reqs, MPI_STATUS_IGNORE);
eachprintarr_c(local, localrows, localcols, rank, size);
}
Результат, который я получаю:
---
Rank 0: ? ? ? ?
Rank 0: � ' V �
Rank 0: � ' V �
Rank 0: � ' V �
---
Rank 1: ? ? ? ?
Rank 1: � � � %
Rank 1: � � � %
Rank 1: � � � %
---
Rank 2: ? + + +
Rank 2: � � � �
Rank 2: � � � �
Rank 2: � � � �
---
Rank 3: + + + ?
Rank 3: � � �
Rank 3: � � �
Rank 3: � � �