Persistent

Receiving

C | Fortran-2008 | Fortran-90

MPI_Recv_init

Definition

MPI_Recv_init prepares a request handle for reception using persistent communications. The handle request is inactive upon creation because no actual reception is issued until the request handle is passed to MPI_Start, at which point it becomes active. An MPI_Recv_init followed with an MPI_Start is equivalent to MPI_Irecv: the receive 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_Recv_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 reception 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_Recv_init does not require the corresponding send on the sender MPI process to be done via persistent communications, and vice-versa. Other persistent communications are: MPI_Send_init, MPI_Ssend_init, MPI_Bsend_init and MPI_Rsend_init.

Copy

Feedback

int MPI_Recv_init(void* buffer,
                  int count,
                  MPI_Datatype datatype,
                  int sender,
                  int tag,
                  MPI_Comm communicator,
                  MPI_Request* request);

Parameters

buffer

The buffer in which receive the message.

count

The number of elements in the buffer given. The number of elements in the message to receive must therefore be less than or equal to that value.

datatype

The type of one buffer element.

sender

The rank of the sender MPI process. If there is no restriction on the sender's rank, MPI_ANY_SOURCE can be passed.

tag

The tag to require from the message. If no tag is required, MPI_ANY_TAG can be passed.

communicator

The communicator in which the communication takes place.

request

The request handle representing the reception used in persistent communications.

Return value

The error code returned from the receive.

Example

Copy

Feedback

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

/**
 * @brief Illustrates how to receive 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:
        {
            // The "master" MPI process issues the MPI_Ssend.
            int buffer_sent;
            for(int i = 0; i < 3; i++)
            {
                buffer_sent = 12345 + i;
                printf("MPI process %d sends value %d for message %d.\n", my_rank, buffer_sent, i);
                MPI_Ssend(&buffer_sent, 1, MPI_INT, RECEIVER, 0, MPI_COMM_WORLD);
            }
            break;
        }
        case RECEIVER:
        {
            // The "slave" MPI process receives the message.
            int received;
            MPI_Request request;
            // Fill a request handle describing the arguments to pass for reception
            MPI_Recv_init(&received, 1, MPI_INT, SENDER, 0, MPI_COMM_WORLD, &request);
            for(int i = 0; i < 3; i++)
            {
                // Launch the reception
                MPI_Start(&request);
                // Wait for the reception to complete
                MPI_Wait(&request, MPI_STATUS_IGNORE);
                printf("MPI process %d received value %d for message %d.\n", my_rank, received, i);
            }
            break;
        }
    }

    MPI_Finalize();

    return EXIT_SUCCESS;
}