Persistent

Sending

C | Fortran-2008 | Fortran-90

MPI_Bsend_init

Definition

MPI_Bsend_init prepares a request handle for buffered sending using persistent communications. The handle request is inactive upon creation because no actual buffered send is issued until the request handle is passed to MPI_Start, at which point it becomes active. An MPI_Bsend_init followed with an MPI_Start is equivalent to MPI_Ibsend: the buffered send is issued, but completion must still be explicitly checked. Therefore, a wait such as MPI_Wait or a test such as MPI_Test is required before the buffers passed to MPI_Bsend_init can be safely reused. Once the request handle of a persistent communication has been waited upon, or successfully tested, it becomes inactive and can be passed again to MPI_Start to issue that same buffered send again. This is how persistent communications save time; they decrease the overhead about argument processing since the list of arguments passed is already known. Using an MPI_Bsend_init does not require the corresponding receive on the receiver MPI process to be done via persistent communications, and vice-versa. Other persistent communications are: MPI_Recv_init, MPI_Send_init, MPI_Ssend_init and MPI_Rsend_init.

Copy

Feedback

int MPI_Bsend_init(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 representing the buffered send used in persistent communications.

Return value

The error code returned from the buffered send.

Example

Copy

Feedback

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

/**
 * @brief Illustrates how to send a message in a blocking asynchronous fashion
 * using persistent communications.
 * @details This application is meant to be used with 2 processes; 1 sender and
 * 1 receiver.
 **/
int main(int argc, char* argv[])
{
    MPI_Init(&argc, &argv);

    // Get the number of processes and check only 2 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 = (char*)malloc(buffer_attached_size);
            MPI_Buffer_attach(buffer_attached, buffer_attached_size);

            // Prepare the MPI_Bsend
            int buffer_sent;
            MPI_Request request;
            MPI_Bsend_init(&buffer_sent, 1, MPI_INT, RECEIVER, 0, MPI_COMM_WORLD, &request);

            for(int i = 0; i < 3; i++)
            {
                buffer_sent = 12345 + i;
                printf("[MPI process %d] I send value %d for message %d.\n", my_rank, buffer_sent, i);
                // Launch the buffered send
                MPI_Start(&request);
                // Wait for the completion of the buffered send
                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:
        {
            // Receive the message and print it.
            int received;
            for(int i = 0; i < 3; i++)
            {
                MPI_Recv(&received, 1, MPI_INT, SENDER, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
                printf("[MPI process %d] I received value %d for message %d.\n", my_rank, received, i);
            }
            break;
        }
    }

    MPI_Finalize();

    return EXIT_SUCCESS;
}