I am not able to understand the difference between MPI_Send()
and MPI_Isend()
followed by MPI_Wait()
.
Isn't that when we use MPI_Wait()
after MPI_Isend()
we are turning it into a Blocking call? As we must wait till all the elements are copied in the buffer.
I know that this configuration(given below) may lead to a deadlock
P1--> MPI_Send() MPI_Recv()
P2--> MPI_Send() MPI_Recv()
But can this configuration(given below) also lead to deadlock?
P1--> MPI_Isend() MPI_Wait() MPI_Recv()
P2--> MPI_Isend() MPI_Wait() MPI_Recv()
TL;DR: You need to use the MPI_Wait
(or use MPI_Test to test for the completion of the request) to ensure that the message is completed, and that the data in the send/receive buffer can be again safely manipulated.
More detailed answer:
Begins a nonblocking send
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
Let us imagine that you send an array of int
s using MPI_Isend
without calling MPI_Wait
; in such case you are not really sure when you can safely modify (or deallocate the memory of) that array. The same applies to MPI_Irecv
. Nonetheless, calling MPI_Wait
ensures that from that point onwards one case read/write (or deallocate the memory of) the buffer without risks of undefined behavior or inconsistent data.
During the MPI_Isend
the content of the buffer (e.g., the array of int
s) has to be read and sent; like-wise during the MPI_Irecv
the content of the receiving buffer has to arrive. In the meantime, one can overlap some computation with the ongoing process, however this computation cannot change (or read) the contend of the send/recv buffer. Then one calls the MPI_Wait
to ensure that from that point onwards the data send/recv can be safely read/modified without any issues.
I am not able to understand the difference between MPI_Send() and MPI_Isend() followed by MPI_Wait().
From this SO Thread one can read:
These functions do not return (i.e., they block) until the communication is finished. Simplifying somewhat, this means that the buffer passed to MPI_Send() can be reused, either because MPI saved it somewhere, or because it has been received by the destination.
Finally:
I know that this configuration(given below) may lead to a deadlock
P1--> MPI_Send() MPI_Recv()
P2--> MPI_Send() MPI_Recv()
But can this configuration(given below) also lead to deadlock?
P1--> MPI_Isend() MPI_Wait() MPI_Recv()
P2--> MPI_Isend() MPI_Wait() MPI_Recv()
If the exchange of messages only happens between the processes P1
and P2
, then yes. Semantically a call to MPI_Isend(
) followed by a call to MPI_Wait()
is the same as calling MPI_Send()
.
P1
sends a message to P2
and waits for the completion of that message, however P2
sends a message to P1
and also waits. Since, each process is waiting on each other this leads to a deadlock.