I know that MPI_SENDRECV
allow to overcome the problem of deadlocks (when we use the classic MPI_SEND
and MPI_RECV
functions).
I would like to know if MPI_SENDRECV(sent_to_process_1, receive_from_process_0)
is equivalent to:
MPI_ISEND(sent_to_process_1, request1)
MPI_IRECV(receive_from_process_0, request2)
MPI_WAIT(request1)
MPI_WAIT(request2)
with asynchronous MPI_ISEND
and MPI_RECV
functions?
From I have seen, MPI_ISEND
and MPI_RECV
creates a fork (i.e. 2 processes). So if I follow this logic, the first call of MPI_ISEND
generates 2 processes. One does the communication and the other calls MPI_RECV
which forks itself 2 processes.
But once the communication of first MPI_ISEND
is finished, does the second process call MPI_IRECV
again? With this logic, the above equivalent doesn't seem to be valid...
Maybe I should change to this:
MPI_ISEND(sent_to_process_1, request1)
MPI_WAIT(request1)
MPI_IRECV(receive_from_process_0, request2)
MPI_WAIT(request2)
But I think that it could be create also deadlocks.
Anyone could give to me another solution using MPI_ISEND
, MPI_IRECV
and MPI_WAIT
to get the same behaviour of MPI_SEND_RECV
?
How I usually do this on node i communicating with node i+1:
mpi_isend(send_to_process_iPlus1, requests(1))
mpi_irecv(recv_from_process_iPlus1, requests(2))
...
mpi_waitall(2, requests)
You can see how ordering your commands this way with non-blocking communication allows you (during the ... above) to perform any computation that does not rely on the send/recv buffers to be done during your communication. Overlapping computation with communication is often crucial for maximizing performance.
mpi_send_recv
on the other hand (while avoiding any deadlock issues) is still a blocking operation. Thus, your program must remain in that routine during the entire send/recv process.
Final points: you can initialize more than 2 requests and wait on all of them the same way using the above structure as dealing with 2 requests. For instance, it's quite easy to start communication with node i-1 as well and wait on all 4 of the requests. Using mpi_send_recv
you must always have a paired send and receive; what if you only want to send?