XGCa
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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  MyMPI(const MPI_Comm& comm_world, int nplanes){
60  // Get total number of processors
61  MPI_Comm_size( comm_world, &nranks );
62 
63  // Assumes check that nranks is divisible by nplanes has already happened - move check here?
64  int ranks_per_plane = nranks/nplanes;
65 
66  if(false/*sml_plane_major*/){
67  // get the group underlying sml_comm
68  //mpi_comm_group(sml_comm, sml_comm_group, ierr)
69  }else{
70  // redefine sml_comm pe ordering from consecutive within planes
71  // (Plane_Major) to consecutive across planes (Interplane-Major)
72  std::vector<int> new_sml_comm_ranks(nranks);
73  int k = 0;
74  for(int j=0; j<ranks_per_plane; j++){
75  for(int i=0; i<nplanes; i++){
76  new_sml_comm_ranks[ranks_per_plane*i + j] = k;
77  k++;
78  }
79  }
80 
81  // get the group underlying sml_comm (== mpi_comm_world)
82  // Use sml_comm_world instead of MPI_COMM_WORLD (for MPMD/staging execution)
83  MPI_Group mpi_comm_world_group;
84  MPI_Comm_group(comm_world, &mpi_comm_world_group);
85 
86  // create new group permuting sml_comm pe ordering to Interplane-Major
87  MPI_Group_incl(mpi_comm_world_group, nranks, new_sml_comm_ranks.data(), &group);
88 
89  // Create the new communicator
90  MPI_Comm_create(comm_world, group, &comm);
91  MPI_Comm_rank( comm, &my_rank );
92  }
93 
94  // INTRA-PLANE MPI COMMUNICATOR
95  //checkpoint("\nPlane mpi communication");
96  int plane_0_pe=int(my_rank/ranks_per_plane)*ranks_per_plane;
97  std::vector<int> plane_ranks(ranks_per_plane);
98  for(int j=0; j<ranks_per_plane; j++){
99  plane_ranks[j]=plane_0_pe + j;
100  }
101 
102  // Create the new plane group
103  MPI_Group plane_group;
104  MPI_Group_incl(group, ranks_per_plane, plane_ranks.data(), &plane_group);
105 
106  // Create the new plane communicator
107  MPI_Comm_create(comm, plane_group, &plane_comm);
108 
109  //call mpi_comm_size(plane_comm, plane_nranks, ierr)
110  MPI_Comm_rank(plane_comm, &my_plane_rank);
111  MPI_Comm_size(plane_comm, &n_plane_ranks);
112 
113  // INTER-PLANE MPI COMMUNICATOR
114  //checkpoint("\nInter-plane mpi communication");
115  std::vector<int> intpl_ranks(nplanes);
116  for(int i=0; i<nplanes; i++){
117  intpl_ranks[i]=my_plane_rank + i*ranks_per_plane;
118  }
119 
120  // Create the new inter-plane group
121  MPI_Group intpl_group;
122  MPI_Group_incl(group, nplanes, intpl_ranks.data(), &intpl_group);
123 
124  // Create the new inter-plane communicator
125  MPI_Comm_create(comm, intpl_group, &intpl_comm);
126 
127  MPI_Comm_rank(intpl_comm, &my_intpl_rank);
128  MPI_Comm_size(intpl_comm, &n_intpl_ranks );
129 
130  /*
131  call check_point('adios mpi communication?')
132  do i=0, sml_intpl_nranks-1
133  adios_ranks(i)= i*ranks_per_plane
134  enddo
135  call mpi_group_incl(sml_comm_group, sml_intpl_nranks, adios_ranks, sml_adios_group, ierr)
136  call mpi_comm_create(sml_comm, sml_adios_group, sml_adios_comm, ierr)
137 
138 
139  //#ifndef NO_TASKMAP
140  // output task-to-node mapping
141  write(c_color,'(i8)') sml_comm_color
142  if (sml_mype .eq. 0) then
143  open(unit=14, file='TASKMAP_Color'//trim(adjustl(c_color))//'.txt', &
144  status='OLD', access='SEQUENTIAL', position='APPEND' )
145  endif
146  call taskmap_write(14, sml_comm, &
147  'SML_COMM COLOR #'//trim(adjustl(c_color)), sml_plane_mype, sml_intpl_mype, .false.)
148  if (sml_mype .eq. 0) close(14)
149  //#endif
150  //#ifdef XGC1
151  //jyc print mpi placement info
152  if (sml_verbose) then
153  call mpi_get_processor_name(nodename, len, ierr)
154  print *, sml_mype, 'Process (plane,node,color):', sml_plane_index, trim(nodename), ' ', sml_comm_color
155  endif
156  //#endif
157  */
158  }
159 };
160 
161 // Some useful debugging tools
162 template <typename F>
163 void execute_in_rank_order(const MPI_Comm& comm, F func){
164  int my_rank;
165  int n_ranks;
166  MPI_Comm_rank( comm, &my_rank );
167  MPI_Comm_size( comm, &n_ranks );
168 
169  // double to make sure *every* rank is flushing at *every* barrier
170  fflush(stdout);
171  MPI_Barrier(comm);
172  fflush(stdout);
173  MPI_Barrier(comm);
174  for(int i=0; i<n_ranks; i++){
175  if(my_rank==i) func(i);
176  fflush(stdout);
177  MPI_Barrier(comm);
178  fflush(stdout);
179  MPI_Barrier(comm);
180  }
181 };
182 
183 #endif
MPI_Comm SML_COMM_WORLD
Definition: my_mpi.cpp:4
MPI_Comm plane_comm
Definition: my_mpi.hpp:38
MyMPI(const MPI_Comm &comm_world, int nplanes)
Definition: my_mpi.hpp:59
int my_intpl_rank
Definition: my_mpi.hpp:49
int my_rank
Definition: my_mpi.hpp:24
Definition: my_mpi.hpp:19
void create_comm_world(int color)
Definition: my_mpi.cpp:13
int SML_COMM_SIZE
Definition: my_mpi.cpp:6
MPI_Comm comm
Definition: my_mpi.hpp:21
int my_plane_rank
Definition: my_mpi.hpp:39
int n_plane_ranks
Definition: my_mpi.hpp:40
int SML_COMM_RANK
Definition: my_mpi.cpp:5
void execute_in_rank_order(const MPI_Comm &comm, F func)
Definition: my_mpi.hpp:163
MyMPI()
Definition: my_mpi.hpp:57
MPI_Comm intpl_comm
Definition: my_mpi.hpp:48
void destroy_comm_world()
Definition: my_mpi.cpp:28
MPI_Group group
Definition: my_mpi.hpp:22
int nranks
Definition: my_mpi.hpp:23
int n_intpl_ranks
Definition: my_mpi.hpp:50