Persistent

C | Fortran-2008 | Fortran-90

MPI_Start

Definition

MPI_Start launches the communication represented by the request handle passed, obtained from MPI_Recv_init, MPI_Send_init, MPI_Ssend_init, MPI_Bsend_init or MPI_Rsend_init. When the request handle is passed to MPI_Start it is inactive, it becomes active after MPI_Start returns. To check for the completion of the underlying communication, a wait such as MPI_Wait or a test such as MPI_Test must be used. Once a wait, or successful test, has been done, the request handle becomes inactive and can be passed to MPI_Start to launch that same communication again. This allows MPI_Start to leverage persistent communications by launching a given communication multiple times without having to pass the arguments to the corresponding communication routine every time. This is an optimisation that allows MPI to save time by not having to process the argument list since it is already known and has been processed once for all during the preparation. For convenience, a variation of MPI_Start is MPI_Startall where an array of request handles is passed and launched.

Copy

Feedback

int MPI_Start(MPI_Request* request);

Parameters

request

The request handle representing the communication to launch.

Return value

The error code returned from the launch.

Example

Copy

Feedback

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

/**
 * @brief Illustrates how to launch the communication represented with a request
 * handle.
 * @details This program is meant to be run with 2 processes: a sender and a
 * receiver. The sender prepares an MPI_Send with MPI_Send_init, then launches
 * it with MPI_Start before waiting for its completion with MPI_Wait. The
 * receiver only issues a common MPI_Recv. This communication is repeated three
 * times to illustrate the use of the same request handle by MPI_Start, that is,
 * persistent communications.
 **/
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;
}