Rookie HPC

About

Docs

Tools

Tests

MPI_Allgatherv

Definition

MPI_Allgatherv is a variant of MPI_Allgather; it collects data from all processes in a given communicator and stores the data collected in the receive buffer of each process. Unlike MPI_Allgather however, MPI_Allgatherv allows the messages received to have different lengths and be stored at arbitrary locations in the receive buffer. MPI_Allgatherv is a collective operation; all processes in the communicator must invoke this routine. Other variants of MPI_Allgatherv are MPI_Gather, MPI_Gatherv and MPI_Allgather. Refer to MPI_Iallgatherv to see the non-blocking counterpart of MPI_Allgatherv.

Copy

Feedback

int MPI_Allgatherv(void* buffer_send,
                   int count_send,
                   MPI_Datatype datatype_send,
                   void* buffer_recv,
                   const int* count_recv,
                   const int* displacements,
                   MPI_Datatype datatype_recv,
                   MPI_Comm communicator);

Parameters

buffer_send
The buffer containing the data to send.
count_send
The number of elements in the send buffer.
datatype_send
The type of one send buffer element.
buffer_recv
The buffer in which store the gathered data for the root process. For other processes, the receiving parameters like this one are ignored.
count_recv
An array containing the number of elements in the message to receive from each process, not the total number of elements to receive from all processes altogether. For non-root processes, the receiving parameters like this one are ignored.
displacements
An array containing the displacement to apply to the message received by each process. Displacements are expressed in number of elements, not bytes. For non-root processes, the receiving parameters like this one are ignored.
datatype_recv
The type of one receive buffer element. For non-root processes, the receiving parameters like this one are ignored.
communicator
The communicator in which the gather takes place.

Returned value

MPI_SUCCESS
The routine successfully completed.

Example

Copy

Feedback

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

/**
 * @brief Illustrates how to use the variable version of an all gather.
 * @details This application is meant to be run with 3 MPI processes. Every MPI
 * process begins with a value, each process will gather all these values and
 * print them. The example is designed to cover all cases:
 * - Different displacements
 * - Different receive counts
 * It can be visualised as follows:
 *
 * +-----------+ +-----------+ +-------------------+ 
 * | Process 0 | | Process 1 | |     Process 2     |
 * +-+-------+-+ +-+-------+-+ +-+-------+-------+-+
 *   | Value |     | Value |     | Value | Value |
 *   |  100  |     |  101  |     |  102  |  103  |
 *   +-------+     +-------+     +-------+-------+
 *      |                |            |     |
 *      |                |            |     |
 *      |                |            |     |
 *      |                |            |     |
 *      |                |            |     |
 *      |                |            |     |
 *   +-----+-----+-----+-----+-----+-----+-----+
 *   | 100 |  0  |  0  | 101 |  0  | 102 | 103 |
 *   +-----+-----+-----+-----+-----+-----+-----+
 *   |                Process 0                |
 *   +-----------------------+-----+-----+-----+
 **/
int main(int argc, char* argv[])
{
    MPI_Init(&argc, &argv);

    // Get number of processes and check only 3 processes are used
    int size;
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    if(size != 3)
    {
        printf("This application is meant to be run with 3 processes.\n");
        MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
    }

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

    // Define the receive counts
    int counts[3] = {1, 1, 2};

    // Define the displacements
    int displacements[3] = {0, 3, 5};

    // Buffer in which receive the data collected
    int buffer[7] = {0};

    // Buffer containing our data to send
    int* my_values;
    int my_values_count;

    switch(my_rank)
    {
        case 0:
        {
            // Define my values
            my_values_count = 1;
            my_values = (int*)malloc(sizeof(int) * my_values_count);
            *my_values = 100;
            printf("Value sent by process %d: %d.\n", my_rank, *my_values);
            break;
        }
        case 1:
        {
            // Define my values
            my_values_count = 1;
            my_values = (int*)malloc(sizeof(int) * my_values_count);
            *my_values = 101;
            printf("Value sent by process %d: %d.\n", my_rank, *my_values);
            break;
        }
        case 2:
        {
            // Define my values
            my_values_count = 2;
            my_values = (int*)malloc(sizeof(int) * my_values_count);
            my_values[0] = 102;
            my_values[1] = 103;
            printf("Values sent by process %d: %d and %d.\n", my_rank, my_values[0], my_values[1]);
            break;
        }
    }

    MPI_Allgatherv(my_values, my_values_count, MPI_INT, buffer, counts, displacements, MPI_INT, MPI_COMM_WORLD);

    printf("Values gathered in the buffer on process %d:", my_rank);
    for(int i = 0; i < 7; i++)
    {
        printf(" %d", buffer[i]);
    }
    printf("\n");
    free(my_values);

    MPI_Finalize();

    return EXIT_SUCCESS;
}