XGC1
my_mpi.hpp
Go to the documentation of this file.
1 #ifndef MY_MPI_HPP
2 #define MY_MPI_HPP
3 
4 #include <mpi.h>
5 #include <vector>
6 #include <cstdio>
7 
8 extern MPI_Comm SML_COMM_WORLD;
9 extern int SML_COMM_RANK;
10 extern int SML_COMM_SIZE;
11 
12 void create_comm_world(int color);
13 void destroy_comm_world();
14 
15 /* To illustrate the different communicators: Imagine SML_COMM_WORLD has 12 ranks:
16  * 0 1 2 3 4 5 6 7 8 9 10 11
17  */
18 
19 struct MyMPI{
20  // General communicator
21  MPI_Comm comm;
22  MPI_Group group;
23  int nranks;
24  int my_rank;
25  /* Reorders SML_COMM_WORLD e.g. (with 12 ranks, 4 planes):
26  * 0 3 6 9
27  * 1 4 7 10
28  * 2 5 8 11
29  * So e.g. processes with ranks 0 and 3 in SML_COMM_WORLD are reordered to be
30  * consecutive in comm
31  * Not sure why this transpose is done; maybe the order affects some MPI algorithms
32  * but not clear when/why this would be better.
33  * Also, in the Fortran code comm overwrites SML_COMM_WORLD in the setup (both
34  * called sml_comm), so something similar could be done here. - ALS
35  */
36 
37  // Intraplane communicator
38  MPI_Comm plane_comm;
41  /* Takes a column from comm, e.g. (with 12 ranks, 4 planes, this is rank 4):
42  * 3
43  * 4
44  * 5
45  */
46 
47  // Interplane communicator
48  MPI_Comm intpl_comm;
51  /* Takes a row from comm, e.g. (with 12 ranks, 4 planes, this is rank 4):
52  *
53  * 1 4 7 10
54  *
55  */
56 
57  MyMPI(){}
58 
59  // Spoofed MPI for dry run
60  MyMPI(int nranks_in)
61  : nranks(nranks_in),
62  my_rank(0) {}
63 
64  MyMPI(const MPI_Comm& comm_world, int nplanes);
65 };
66 
67 // Some useful debugging tools
68 template <typename F>
69 void execute_in_rank_order(const MPI_Comm& comm, F func){
70  int my_rank;
71  int n_ranks;
72  MPI_Comm_rank( comm, &my_rank );
73  MPI_Comm_size( comm, &n_ranks );
74 
75  // double to make sure *every* rank is flushing at *every* barrier
76  fflush(stdout);
77  MPI_Barrier(comm);
78  fflush(stdout);
79  MPI_Barrier(comm);
80  for(int i=0; i<n_ranks; i++){
81  if(my_rank==i) func(i);
82  fflush(stdout);
83  MPI_Barrier(comm);
84  fflush(stdout);
85  MPI_Barrier(comm);
86  }
87 };
88 
89 template <typename T>
90 MPI_Datatype get_mpi_type() {
91  if constexpr(std::is_same<T, double>::value) {
92  return MPI_DOUBLE;
93  } else if constexpr(std::is_same<T, int>::value) {
94  return MPI_INT;
95  } else if constexpr(std::is_same<T, float>::value) {
96  return MPI_FLOAT;
97  } else if constexpr(std::is_same<T, long long int>::value) {
98  return MPI_LONG_LONG_INT;
99  } else {
100  // Fallback for unsupported types
101  static_assert(!std::is_same<T, T>::value, "Unsupported MPI data type");
102  return MPI_DATATYPE_NULL;
103  }
104 }
105 
106 // Function overload for Kokkos Views
107 template <typename ViewType>
108 MPI_Datatype get_mpi_type(const ViewType& view) {
109  using value_type = typename ViewType::value_type;
110  return get_mpi_type<value_type>();
111 }
112 
113 
114 #endif
void destroy_comm_world()
Definition: my_mpi.cpp:141
int SML_COMM_RANK
Definition: my_mpi.cpp:5
void execute_in_rank_order(const MPI_Comm &comm, F func)
Definition: my_mpi.hpp:69
MPI_Comm SML_COMM_WORLD
Definition: my_mpi.cpp:4
MPI_Datatype get_mpi_type()
Definition: my_mpi.hpp:90
int SML_COMM_SIZE
Definition: my_mpi.cpp:6
void create_comm_world(int color)
Definition: my_mpi.cpp:126
Definition: my_mpi.hpp:19
MyMPI()
Definition: my_mpi.hpp:57
int n_plane_ranks
Definition: my_mpi.hpp:40
MyMPI(int nranks_in)
Definition: my_mpi.hpp:60
int nranks
Definition: my_mpi.hpp:23
int n_intpl_ranks
Definition: my_mpi.hpp:50
int my_plane_rank
Definition: my_mpi.hpp:39
int my_intpl_rank
Definition: my_mpi.hpp:49
MPI_Comm intpl_comm
Definition: my_mpi.hpp:48
int my_rank
Definition: my_mpi.hpp:24
MPI_Comm comm
Definition: my_mpi.hpp:21
MPI_Comm plane_comm
Definition: my_mpi.hpp:38
MPI_Group group
Definition: my_mpi.hpp:22