Rookie HPC

Sending

C | FORTRAN-legacy | FORTRAN-2008

MPI_Bsend

Definition

MPI_Bsend is the asynchronous blocking send (the capital ‘B’ standing for buffered); it will block until a copy of the buffer passed is made. MPI will effectively send the buffer copied at a later point, but the user cannot know when. As a blocking send, MPI_Bsend guarantees that the buffer passed can be safely reused once MPI_Bsend returns. Note that the size of the copy is equal to that of the buffer passed plus the memory overhead generated by an MPI_Bsend, 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_Bsend behaves as if a zero-sized buffer was attached. MPI_Bsend may be invoked implicitly by the standard blocking send (MPI_Send). Other blocking sends are MPI_Send, MPI_Ssend and MPI_Rsend. Refer to MPI_Ibsend to see the non-blocking counterpart of MPI_Bsend.

Copy

Feedback

int MPI_Bsend(const void* buffer,
              int count,
              MPI_Datatype datatype,
              int recipient,
              int tag,
              MPI_Comm communicator);

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.

Returned value

The error code returned from the buffered 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 blocking asynchronous fashion.
 * @details This application is meant to be used with 2 processes; 1 sender and
 * 1 receiver. The sender will declare a buffer containing enough space for 1
 * message that will contain 1 integer. It then attaches the buffer to MPI and
 * issues the MPI_Bsend. Finally, it detaches the buffer and frees it, while the
 * receiver prints the message received.
 **/
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);

            // Issue the MPI_Bsend
            int buffer_sent = 12345;
            printf("[MPI process %d] I send value %d.\n", my_rank, buffer_sent);
            MPI_Bsend(&buffer_sent, 1, MPI_INT, RECEIVER, 0, MPI_COMM_WORLD);

            // 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;
            MPI_Recv(&received, 1, MPI_INT, SENDER, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            printf("[MPI process %d] I received value: %d.\n", my_rank, received);
            break;
        }
    }

    MPI_Finalize();

    return EXIT_SUCCESS;
}