Persistent

Sending

C | Fortran-2008 | Fortran-90

MPI_Send_init

Definition

MPI_Send_init prepares a request handle for sending using persistent communications. The handle request is inactive upon creation because no actual send is issued until the request handle is passed to MPI_Start, at which point it becomes active. An MPI_Send_init followed with an MPI_Start is equivalent to MPI_Isend: the 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_Send_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 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_Send_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_Ssend_init, MPI_Bsend_init and MPI_Rsend_init.

Copy

Feedback

int MPI_Send_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 standard send takes place.

request

The request handle representing the standard send used in persistent communications.

Return value

The error code returned from the standard send.

Example

Copy

Feedback

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

/**
 * @brief Illustrates how to send a message using persistent communications.
 * @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;
            MPI_Request request;
            // Prepare the send request handle
            MPI_Send_init(&buffer_sent, 1, MPI_INT, RECEIVER, 0, MPI_COMM_WORLD, &request);
            for(int i = 0; i < 3; i++)
            {
                buffer_sent = 12345 + i;
                // Launch the send
                MPI_Start(&request);
                // Wait for the send to complete
                MPI_Wait(&request, MPI_STATUS_IGNORE);
                printf("MPI process %d sends value %d for message %d.\n", my_rank, buffer_sent, i);
                
            }
            break;
        }
        case RECEIVER:
        {
            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 received value %d for message %d.\n", my_rank, received, i);
            }
            break;
        }
    }

    MPI_Finalize();

    return EXIT_SUCCESS;
}