Non-blocking

Sending

C | Fortran-2008 | Fortran-90

MPI_Irsend

Definition

MPI_Irsend is a standard non-blocking send. The difference with MPI_Isend is the capital 'R'that stands for Ready. Indeed, MPI_Irsend requires the corresponding receive (MPI_Recv or MPI_Irecv) to have been issued first. This particularity may improve performance by saving the time normally spent hand-shaking with the receiving MPI process (since the receiver is already ready to receive the message). An MPI_Irsend has the same semantics as MPI_Isend; it will decide whether to use the synchronous or asynchronous mode using the same decision flow that MPI_Isend. As a non-blocking send, MPI_Irsend will immediately return and the buffer passed must not be seen as safe to reuse until the completion of MPI_Irsend has been checked with MPI_Wait or MPI_Test. Other non-blocking sends are MPI_Isend, MPI_Issend, MPI_Ibsend. Refer to MPI_Rsend to see the blocking counterpart of MPI_Irsend.

Copy

Feedback

int MPI_Irsend(const void* buffer,
               int count,
               MPI_Datatype datatype,
               int recipient,
               int tag,
               MPI_Comm communicator,
               MPI_Request* request);

Parameters

buffer

The buffer to send.

count

The number of elements to send.

datatype

The type of one buffer element.

recipient

The rank of the recipient MPI process.

tag

The tag to assign to the message.

communicator

The communicator in which the buffered send takes place.

request

The request handle on the non-blocking communication taking place.

Return value

The error code returned from the non-blocking ready send.

Example

Copy

Feedback

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

/**
 * @brief Illustrates how to issue a message as soon as possible in a
 * non-blocking fashion.
 * @details This program is meant to be run with 2 processes: a sender and a
 * receiver.
 *
 * (Note to readers: the use of an MPI barrier is to ensure that the MPI_Irsend 
 * is issued after the corresponding MPI receive is issued.)
 **/
int main(int argc, char* argv[])
{
    MPI_Init(&argc, &argv);

    // Get the number of processes and check only 2 processes are used
    int size;
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    if(size != 2)
    {
        printf("This application is meant to be run with 2 processes.\n");
        MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
    }

    // Get my rank and do the corresponding job
    enum role_ranks { SENDER, RECEIVER };
    int my_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    switch(my_rank)
    {
        case SENDER:
        {
            MPI_Barrier(MPI_COMM_WORLD);

            int buffer_sent = 12345;
            MPI_Request request;
            printf("MPI process %d sends value %d.\n", my_rank, buffer_sent);
            MPI_Irsend(&buffer_sent, 1, MPI_INT, RECEIVER, 0, MPI_COMM_WORLD, &request);

            // Do something else while the MPI_Irsend progresses
            // <...>

            // Wait for the underlying MPI_Rsend to complete.
            MPI_Wait(&request, MPI_STATUS_IGNORE);
            break;
        }
        case RECEIVER:
        {
            int received;
            MPI_Request request;
            MPI_Irecv(&received, 1, MPI_INT, SENDER, 0, MPI_COMM_WORLD, &request);

            // Tell the other process that the receive is posted, so the ready send can be issued
            MPI_Barrier(MPI_COMM_WORLD);

            // Wait for the underlying MPI_Recv to complete.
            MPI_Wait(&request, MPI_STATUS_IGNORE);
            printf("MPI process %d receives value %d.\n", my_rank, received);
            break;
        }
    }

    MPI_Finalize();

    return EXIT_SUCCESS;
}