Я пытаюсь реализовать операцию All-To-All (т.е. MPI_Allgather) в сети гиперкубов с использованием C ++.
Например, для 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].
(Другими словами, каждый процессор получает данные от всех остальных).
Хотя алгоритм использует некоторую маску и цикл, который включает в себя этап обмена данными между двумя процессорами, например, поменяйте местами последние 4 элемента p0 с первыми 4 элементами p3 (отправив последние 4 элемента p0 в p3 и отправив первые 4 элемента от p3 до p0 одновременно). использование MPI_Send и MPI_Recv не может этого достичь, потому что половина массива получателей будет перезаписана до того, как он отправит свои данные. Может ли кто-нибудь помочь мне с методами, которые я мог бы использовать для этого? Я думал об использовании промежуточного буфера, но все еще не совсем уверен, как написать код отправки и получения MPI.
Или, если кто-то может сказать мне любой другой способ реализации All-to-All. Я был бы очень признателен. Большое спасибо!
Все в все в MPI выполняется 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
Других решений пока нет …