Discontinuous Galerkin Library
#include "dg/algorithm.h"
Loading...
Searching...
No Matches
mpi_cart.h
Go to the documentation of this file.
1#pragma once
2#include <algorithm>
3
4
5namespace dg
6{
7
8// Wrap all MPI_Cart functions such that Cartesian topology becomes column
9// major ordering instead of row major
10//
11// Motivation: usually MPI process ranks fill HPC compute nodes in sequence,
12// e.g. the first four ranks are on node 0, the next four on node 1 and so on.
13// At the same time we want that in our 3d tokamak simulations all processes
14// that partition a 2d plane lie on the same node (to reduce communication
15// times for perp derivatives). However, \c MPI_Cart_create assigns ranks to
16// dimensions in row-major ordering such that the last direction is the fastest
17// varying one, e.g. in 1 2 4 the first four ranks all have different z-values
18// Pinning processes differently is possible but usually a hassle (and we
19// should make our GPU assignment more sophisticated in mpi_init.h). This
20// solution simply makes the ordering column major by reversing the order to
21// dimensions for all MPI_Cart_* calls.
22//
23// Rationale: The following functions capture the transposition and handle it
24// correctly for the user. If they are always used instead of the originals one
25// does not need to think about the transposition and simply ignore it.
27
28inline int mpi_cart_coords( MPI_Comm comm, int rank, int maxdims, int coords[])
29{
30 int re = MPI_Cart_coords( comm, rank, maxdims, coords);
31 std::reverse( coords, coords + maxdims);
32 return re;
33}
34
35inline int mpi_cart_create( MPI_Comm comm_old, int ndims, int dims[],
36 const int periods[], int reorder, MPI_Comm * comm_cart
37)
38{
39 std::vector<int> rev_dims(ndims), rev_periods(ndims);
40 std::reverse_copy( dims, dims + ndims, rev_dims.begin());
41 std::reverse_copy( periods, periods + ndims, rev_periods.begin());
42 return MPI_Cart_create( comm_old, ndims, &rev_dims[0], &rev_periods[0], reorder, comm_cart);
43}
44
45inline int mpi_cart_get( MPI_Comm comm, int maxdims, int dims[], int periods[], int coords[])
46{
47 int re = MPI_Cart_get( comm, maxdims, dims, periods, coords);
48 std::reverse( dims, dims + maxdims);
49 std::reverse( periods, periods + maxdims);
50 std::reverse( coords, coords + maxdims);
51 return re;
52}
53
54inline int mpi_cart_rank( MPI_Comm comm, int coords[], int *rank)
55{
56 int ndims;
57 MPI_Cartdim_get( comm, &ndims);
58 std::vector<int> rev_coords(ndims);
59 std::reverse_copy( coords, coords + ndims, rev_coords.begin());
60 return MPI_Cart_rank( comm, &rev_coords[0], rank);
61}
62
63inline int mpi_cart_shift( MPI_Comm comm, int direction, int disp, int *rank_source, int *rank_dest)
64{
65 int ndims;
66 MPI_Cartdim_get( comm, &ndims);
67 direction = ndims - 1 - direction;
68 return MPI_Cart_shift( comm, direction, disp, rank_source, rank_dest);
69}
70
71inline int mpi_cart_sub( MPI_Comm comm, const int remain_dims[], MPI_Comm *comm_new)
72{
73 int ndims;
74 MPI_Cartdim_get( comm, &ndims);
75 std::vector<int> rev_remains(ndims);
76 std::reverse_copy( remain_dims, remain_dims + ndims, rev_remains.begin());
77 return MPI_Cart_sub( comm, &rev_remains[0], comm_new);
78}
79
80inline int mpi_cartdim_get( MPI_Comm comm, int *ndims) { return MPI_Cartdim_get( comm, ndims);}
82
83} // namespace dg
direction
Direction of a discrete derivative.
Definition enums.h:97
MPI_Comm mpi_cart_sub(MPI_Comm comm, std::vector< int > remain_dims, bool duplicate=false)
Call and register a call to MPI_Cart_sub with the dg library.
Definition mpi_kron.h:116
MPI_Comm mpi_cart_create(MPI_Comm comm_old, std::vector< int > dims, std::vector< int > periods, bool reorder=false)
Convenience call to MPI_Cart_create preceded by MPI_Dims_create.
Definition mpi_init.h:202
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...