Rookie HPC

About

Docs

Tools

Tests

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 apply to the message.
communicator
The communicator in which the communication takes place.
request
The request handle on the non-blocking communication taking place.

Returned value

MPI_SUCCESS
The routine successfully completed.

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, 1, 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, 0, 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;
}