У меня есть следующий код C / C ++ с Microsoft MPI
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"int main (int argc, char *argv[])
{
int err, numtasks, taskid;
int out=0,val;
MPI_Status status;
MPI_Request req;
err=MPI_Init(&argc, &argv);
err=MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
err=MPI_Comm_rank(MPI_COMM_WORLD, &taskid);int receiver=(taskid+1)% numtasks;
int sender= (taskid-1+numtasks)% numtasks;
printf("sender %d, receiver %d, rank %d\n",sender,receiver, taskid);
val=50;
MPI_Isend(&val, 1, MPI_INT, receiver, 1, MPI_COMM_WORLD, &req);
MPI_Irecv(&out, 1, MPI_INT, sender, 1, MPI_COMM_WORLD, &req);
printf ("Rank: %d , Value: %d\n", taskid, out );
err=MPI_Finalize();
return 0;
}
Приложение заходит в тупик, если запущено более двух процессов.
С 2 процессами приложение работает, но запись «out» не выполняется.
Этот код работает с дистрибутивом Linux linux, проблема, кажется, только в версии Microsoft. Любая помощь ?
Во-первых, каждый процесс MPI выполняет две связи: одну отправку и один прием. Так что вам нужно иметь хранилище для двух запросов (MPI_Request req[2]
) и две проверки статуса (MPI_Status status[2]
).
Во-вторых, вам нужно подождать после вызова неблокирующих send / recvs, чтобы убедиться, что они завершаются правильно.
MPI_Isend(&val, 1, MPI_INT, receiver, 1, MPI_COMM_WORLD, &req[0]);
MPI_Irecv(&out, 1, MPI_INT, sender, 1, MPI_COMM_WORLD, &req[1]);
// While the communication is happening, here you can overlap computation
// on data that is NOT being currently communicated, with the communication of val/out
MPI_Waitall(2, req, status);
// Now both the send and receive have been finished for this process,
// and we can access out, assured that it is valid
printf ("Rank: %d , Value: %d\n", taskid, out);
Что касается того, почему это работает в дистрибутиве Linux, а не в Microsoft … Я могу только предположить, что внутренняя реализация Linux эффективно реализует неблокирующую коммуникацию как блокирующую коммуникацию. То есть они «обманывают» и заканчивают ваше общение за вас до того, как это должно быть завершено. Это облегчает им задачу, поскольку им не нужно отслеживать как можно больше информации об обмене информацией, но также лишает вас возможности перекрывать вычисления и обмен данными. Вы не должны полагаться на это, чтобы работать.
Других решений пока нет …