Как минимальная проблема, я пытаюсь отправить целое число между 4 процессорами: 0 -> 3 (ранг 0
отправляет и получает ранг 3
), 2 -> 1, 1 -> 2,3 -> 0. Он никогда не завершает выполнение и зависает, вероятно, ожидая ответа от других потоков.
Я компилирую код с mpif90 ...
и запускаю с mpiexec -np 4 ...
.Ниже приведен минимальный фрагмент:
program sendrecv
implicit none
include "mpif.h"
integer :: foo, bar
integer :: mpi_rank, mpi_size, ierr
integer :: mpi_sendto, mpi_recvfrom
integer :: istat(MPI_STATUS_SIZE), status, i
call MPI_INIT(ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, mpi_size, ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, mpi_rank, ierr)
print *, "SENDING..."
if (mpi_rank .eq. 0) then
mpi_sendto = 3; mpi_recvfrom = 3
else if (mpi_rank .eq. 1) then
mpi_sendto = 2; mpi_recvfrom = 2
else if (mpi_rank .eq. 2) then
mpi_sendto = 1; mpi_recvfrom = 1
else
mpi_sendto = 0; mpi_recvfrom = 0
end if
foo = mpi_rank
do i = 1, 5
foo = mpi_rank
call MPI_SENDRECV(foo, 1,&
& MPI_INTEGER, mpi_sendto, mpi_rank * 10 + i,&
& bar, 1,&
& MPI_INTEGER, mpi_recvfrom, mpi_rank * 10 + i,&
& MPI_COMM_WORLD, istat, ierr)
end do
print *, "...DONE"
call MPI_FINALIZE(ierr)
end
Я не совсем понимаю, почему эта программа зависает, может быть, я что-то упускаю или что-то действительно неправильно.Если я правильно понимаю, MPI_SENDRECV
это просто неблокирующая send
и recv
с двумя wait
-ами.В этом случае, скажем, если rank=0
отправляет rank=3
, у него не должно возникнуть проблем с получением, верно?
Я пытался отправлять / получать из разных потоков, т. Е. Делал это:
if (mpi_rank .eq. 0) then
mpi_sendto = 1; mpi_recvfrom = 3
else if (mpi_rank .eq. 1) then
mpi_sendto = 2; mpi_recvfrom = 0
else if (mpi_rank .eq. 2) then
mpi_sendto = 3; mpi_recvfrom = 1
else
mpi_sendto = 0; mpi_recvfrom = 2
end if
все еще не работает.
UPD Как было указано, теги должны быть одинаковыми при выполнении SENDRECV
, однако в случае, когда этот вызов выполняется внутрицикл, похожие теги мало помогают (см. модифицированный код).Старая версия:
call MPI_SENDRECV(foo, 1,&
& MPI_INTEGER, mpi_sendto, 200,&
& bar, 1,&
& MPI_INTEGER, mpi_recvfrom, 100,&
& MPI_COMM_WORLD, status, ierr)
UPD # 2 На самом деле, если кому-то интересно, я нашел обсуждение именно о проблеме, с которой я столкнулся, почему SENDRECV
-s может иногда тупиковая