Collectives

Reduction

C | Fortran-2008 | Fortran-90

MPI_Exscan

Definition

MPI_Exscan is an exclusive scan: it performs a prefix reduction across all MPI processes in the given communicator, excluding the calling MPI process. In other words, each MPI process receives the result of the reduction operation on the values passed by the MPI processes with a lower rank. It implies that the result on the first MPI process is undefined, and that the buffer passed by the last MPI process for sending is not significant. MPI_Exscan is a collective operation; it must be called by all MPI processes in the communicator concerned. The variant of MPI_Exscan is the inclusive version MPI_Scan.

Copy

Feedback

MPI_Exscan(void* send_buffer,
           void* receive_buffer,
           int count,
           MPI_Datatype datatype,
           MPI_Op operation,
           MPI_Comm communicator);

Parameters

send_buffer

The buffer containing the value to send to scan. To use the in-place version, where the buffer in which store the result is also the buffer from which read the value to send, set the send_buffer to MPI_IN_PLACE.

receive_buffer

The variable in which store the result of the scan.

count

The number of elements in the scan.

datatype

The datatype of an element.

operation

The operation to apply to combine messages received in the scan. This operation must be associative, and commutative for predefined operations while user-defined operations may be non-commutative.

communicator

The communicator in which the scan takes places. MPI_Scan is not valid on inter-communicators.

Return value

The error code returned from the exclusive scan.

Example

Copy

Feedback

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

/**
 * @brief Illustrate how to use an MPI_Exscan.
 * @details This program uses MPI_Exscan to compute a progressive sum of ranks. It
 * can be visualised as follows:
 *
 * +---------------+   +---------------+   +---------------+   +---------------+
 * | MPI process 0 |   | MPI process 1 |   | MPI process 2 |   | MPI process 3 |
 * +---------------+   +---------------+   +---------------+   +---------------+
 * |       0       |   |       1       |   |       2       |   |       3       |
 * +-------+-------+   +-------+-------+   +-------+-------+   +-------+-------+
 *         |                   |                   |                    
 *         |                +--+--+                |                    
 *         +----------------| SUM |                |                    
 *         |                +--+--+                |                    
 *         |                   |                +--+--+                 
 *         |                   +----------------| SUM |                 
 *         |                   |                +--+--+                 
 *         |                   |                   |                    
 *         |                   |                   |                    
 *          \                   \                   \                      
 *           \                   \                   \                  
 *            \                   \                   \                 
 *             \_______________    \_______________    \_______________ 
 *                             |                   |                   |
 *                             |                   |                   |
 * +-------+-------+   +-------+-------+   +-------+-------+   +-------+-------+
 * |   undefined   |   |       0       |   |       1       |   |       3       |
 * +---------------+   +---------------+   +---------------+   +---------------+
 * | MPI process 0 |   | MPI process 1 |   | MPI process 2 |   | MPI process 3 |
 * +---------------+   +---------------+   +---------------+   +---------------+
 *                                       
 **/
int main(int argc, char* argv[])
{
    MPI_Init(&argc, &argv);

    // Get my rank
    int my_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

    // Get the sum of all ranks up to the one before mine and print it
    int total;
    MPI_Exscan(&my_rank, &total, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

    // The result on MPI process 0 is undefined, do not print it
    if(my_rank == 0)
    {
        printf("[MPI process 0] Total = undefined.\n");
    }
    else
    {
        printf("[MPI process %d] Total = %d.\n", my_rank, total);
    }

    MPI_Finalize();

    return EXIT_SUCCESS;
}