Rookie HPC

About

Docs

Tools

Tests

MPI_Ibsend

Definition

MPI_Ibsend is the asynchronous non-blocking send (the capital ā€˜Iā€™ stands for immediate return); it will make a copy of the buffer passed, and MPI will effectively send this copy to the recipient in future, but the user cannot know when. However, unlike its blocking counterpart MPI_Bsend, MPI_Ibsend will not block until that copy is made, instead it will return immediately. This implies that when MPI_Ibsend returns, the buffer provided may not have been copied yet so reusing this buffer is unsafe. The user must therefore check for completion with MPI_Wait or MPI_Test before safely reusing the buffer passed. Note that the size of the copy is equal to that of the buffer passed plus the memory overhead generated by an MPI_Ibsend, represented by MPI_BSEND_OVERHEAD, which contains for instance the rank of the recipient process. The MPI buffer in which the copy will be made must be allocated by the user and explicitly attached to MPI using MPI_Buffer_attach. If no buffer is attached, the MPI standard states that MPI_Ibsend behaves as if a zero-sized buffer was attached. MPI_Ibsend may be invoked implicitly by the standard non-blocking send (MPI_Isend). Other non-blocking sends are MPI_Isend, MPI_Issend and MPI_Irsend. Refer to MPI_Bsend to see the blocking counterpart of MPI_Ibsend.

Copy

Feedback

int MPI_Ibsend(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 send a message in a non-blocking asynchronous
 * 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 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:
        {
            // Declare the buffer and attach it
            int buffer_attached_size = MPI_BSEND_OVERHEAD + sizeof(int);
            char* buffer_attached = malloc(buffer_attached_size);
            MPI_Buffer_attach(buffer_attached, buffer_attached_size);

            // Issue the MPI_Ibsend
            int buffer_sent = 12345;
            MPI_Request request;
            printf("MPI process %d sends value %d.\n", my_rank, buffer_sent);
            MPI_Ibsend(&buffer_sent, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &request);
            
            // Let's wait for the MPI_Ibsend to complete before progressing further.
            MPI_Wait(&request, MPI_STATUS_IGNORE);

            // Detach the buffer. It blocks until all messages stored are sent.
            MPI_Buffer_detach(&buffer_attached, &buffer_attached_size);
            free(buffer_attached);
            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;
}