Rookie HPC

Sending

Non-blocking

C | FORTRAN-legacy | FORTRAN-2008

MPI_Issend

Definition

MPI_Issend is the synchronous non-blocking send (the capital ’I’ standing for immediate return). Unlike its blocking counterpart MPI_Ssend, MPI_Issend will not block until the recipient has received the message. In other words, when MPI_Issend returns, the buffer passed may not have been sent yet, and it must be considered unsafe to reuse the buffer passed. The user must therefore check for completion with MPI_Wait or MPI_Test before safely reusing the buffer passed. Note that MPI_Issend may be implicitly invoked by the standard non-blocking send (MPI_Isend). Other non-blocking sends are MPI_Isend, MPI_Ibsend and MPI_Irsend. Refer to MPI_Ssend to see the blocking counterpart of MPI_Issend.

Copy

Feedback

int MPI_Issend(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 broadcast takes place.
request
The request handle on the non-blocking communication taking place.

Returned value

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

MPI_SUCCESS
The routine successfully completed.

Example

Copy

Feedback

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

/**
 * @brief Illustrates how to send a message in a non-blocking synchronous
 * fashion.
 * @details This program is meant to be run with 2 processes: a sender and a
 * receiver.
 **/
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:
        {
            int buffer_sent = 12345;
            MPI_Request request;
            printf("MPI process %d sends value %d.\n", my_rank, buffer_sent);
            MPI_Issend(&buffer_sent, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &request);
            
            // Do other things while the MPI_Issend completes
            // <...>

            // Let's wait for the MPI_Issend to complete before progressing further.
            MPI_Status status;
            MPI_Wait(&request, &status);
            break;
        }
        case RECEIVER:
        {
            int received;
            MPI_Recv(&received, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            printf("MPI process %d received value: %d.\n", my_rank, received);
            break;
        }
    }

    MPI_Finalize();

    return EXIT_SUCCESS;
}