Блокировка - это правильное поведение; у вас тупик в вашем коде.
Спецификация MPI позволяет MPI_Send
вести себя как MPI_Ssend
, то есть блокировать. Блокирующий коммуникационный примитив не возвращается до тех пор, пока связь в некотором смысле «не завершится», что (в случае блокирующей отправки), вероятно, означает, что прием начался.
Ваш код выглядит так:
If Processor 0:
Send to processor 1
If Processor 1:
Send to processor 0
Receive
То есть - получение не начинается до тех пор, пока отправка не будет завершена. Вы отправляете, но они никогда не вернутся, потому что никто не получает! (Тот факт, что это работает для маленьких сообщений, является артефактом реализации - большинство реализаций mpi используют так называемый «нетерпеливый протокол» для «достаточно маленьких» сообщений; но на это вообще нельзя рассчитывать.)
Обратите внимание, что здесь присутствуют и другие логические ошибки - эта программа также заблокируется более чем для 2 процессоров, поскольку процессоры с рангом> = 2 будут ожидать сообщения, которое никогда не поступит.
Вы можете исправить свою программу, чередуя отправку и получение по рангу:
if (processor_rank == 0) {
MPI_Send(buff_send_H, n*n*N_p0+1, MPI_DOUBLE, 1, 163, MPI_COMM_WORLD);
MPI_Recv(buff_H, n*n*N_p0+1, MPI_DOUBLE, MPI_ANY_SOURCE, 163, MPI_COMM_WORLD, &status);
} else if (processor_rank == 1) {
MPI_Recv(buff_H, n*n*N_p0+1, MPI_DOUBLE, MPI_ANY_SOURCE, 163, MPI_COMM_WORLD, &status);
MPI_Send(buff_send_H, n*n*N_p0+1, MPI_DOUBLE, 0, 163, MPI_COMM_WORLD);
}
или с помощью MPI_Sendrecv (который является блокирующим (отправка + получение), а не блокирующим отправкой + блокирующее получение):
int sendto;
if (processor_rank == 0)
sendto = 1;
else if (processor_rank == 1)
sendto = 0;
if (processor_rank == 0 || processor_rank == 1) {
MPI_Sendrecv(buff_send_H, n*n*N_p0+1, MPI_DOUBLE, sendto, 163,
buff_H, n*n*N_p0+1, MPI_DOUBLE, MPI_ANY_SOURCE, 163,
MPI_COMM_WORLD, &status);
}
Или с помощью неблокирующих отправок и приемов:
MPI_Request reqs[2];
MPI_Status statuses[2];
if (processor_rank == 0) {
MPI_Isend(buff_send_H, n*n*N_p0+1, MPI_DOUBLE, 1, 163, MPI_COMM_WORLD, &reqs[0]);
} else if (processor_rank == 1) {
MPI_Isend(buff_send_H, n*n*N_p0+1, MPI_DOUBLE, 0, 163, MPI_COMM_WORLD, &reqs[0]);
}
if (processor_rank == 0 || processor_rank == 1)
MPI_Irecv(buff_H, n*n*N_p0+1, MPI_DOUBLE, MPI_ANY_SOURCE, 163, MPI_COMM_WORLD, &reqs[1]);
MPI_Waitall(2, reqs, statuses);