Non-blocking

Sending

C | Fortran-2008 | Fortran-90

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 non-blocking synchronous send takes place.

request

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

Return value

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

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;
}