One-sided

C | Fortran-2008 | Fortran-90

MPI_Win_allocate

Definition

MPI_Win_allocate allocates a memory area of at least the size demanded, then makes it accessible one-sidedly to other MPI processes in the communicator through a window. The call returns an opaque object that represents the attributes of each window (as specified by the initialisation call), and the group of processes that own and access the set of windows. MPI_Win_allocate is a collective operation; it must be called on all MPI processes in the communicator concerned. Windows created must be freed with MPI_Win_free once all pending RMA communications with that window are complete. Other variants of MPI_Win_allocate are MPI_Win_allocate_shared, MPI_Win_create are MPI_Win_create_dynamic.

Copy

Feedback

int MPI_Win_allocate(MPI_Aint size,
                     int displacement_unit,
                     MPI_Info info,
                     MPI_Comm communicator,
                     void* base,
                     MPI_Win window);

Parameters

size

The size of the memory area exposed through the window, in bytes.

displacement_unit

The displacement unit is used to provide an indexing feature during RMA operations. Indeed, the target displacement specified during RMA operations is multiplied by the displacement unit on that target. The displacement unit is expressed in bytes, so that it remains identical in an heterogeneous environment.

info

The info argument provides optimisation hints to the runtime about the expected usage pattern of the window.

  • no_locks: if set to true, then the implementation may assume that passive target synchronisation (that is, MPI_Win_lock, MPI_Win_lock_all) will not be used on the given window. This implies that this window is not used for 3-party communication, and RMA can be implemented with no (less) asynchronous agent activity at this process.
  • accumulate_ordering: controls the ordering of accumulate operations at the target. The default value is rar,raw,war,waw.
  • accumulate_ops: if set to same_op, the implementation will assume that all concurrent accumulate calls to the same target address will use the same operation. If set to same_op_no_op, then the implementation will assume that all concurrent accumulate calls to the same target address will use the same operation or MPI_NO_OP. This can eliminate the need to protect access for certain operation types where the hardware can guarantee atomicity. The default is same_op_no_op.
  • same_size: if set to true, then the implementation may assume that the argument size is identical on all processes, and that all processes have provided this info key with the same value.
  • same_disp_unit: if set to true, then the implementation may assume that the argument displacement_unit is identical on all processes, and that all processes have provided this info key with the same value.
communicator

The communicator containing all MPI processes involved in RMA communications. The various processes in the corresponding group may specify completely different target windows, in location, size, displacement units and info arguments. As long as all the get, put and accumulate accesses to a particular process fit their specific target window this should pose no problem. The same area in memory may appear in multiple windows, each associated with a different window object. However, concurrent communications to distinct, overlapping windows may lead to undefined results.

base

The address of the start of the memory space making the window.

window

A pointer to the variable in which store the window created.

Return value

The error code returned from the window creation:

Example

Copy

Feedback

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

/**
 * @brief Illustrate how to create a window with an automatically allocated
 * memory area.
 * @details This application consists in creating a window and destroying it.
 **/
int main(int argc, char* argv[])
{
    MPI_Init(&argc, &argv);

    // Check that only 2 MPI processes are spawn
    int comm_size;
    MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
    if(comm_size != 2)
    {
        printf("This application is meant to be run with 2 MPI processes, not %d.\n", comm_size);
        MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
    }

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

    // Create the window
    const int ARRAY_SIZE = 2;
    int* window_buffer;
    MPI_Win window;
    MPI_Win_allocate(ARRAY_SIZE * sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &window_buffer, &window);
    printf("[MPI process %d] Window created.\n", my_rank);

    // Issue RMA communications
    // ...
    // Wait for all RMA communications to complete

    // Destroy the window
    printf("[MPI process %d] Window destroyed.\n", my_rank);
    MPI_Win_free(&window);

    MPI_Finalize();

    return EXIT_SUCCESS;
}