OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
CommSplitter.h
Go to the documentation of this file.
1 //
2 // Class CommSplitter
3 // Role assignment according to strategy (that might use hardware
4 // network information).
5 //
6 // The CommSplitter splits the passed (usually MPI_COMM_WORLD) communicator
7 // into several comm groups using the colors provided by the splitting
8 // strategy.
9 // After construction each processor has an assigned role (optimizer, worker
10 // or pilot) and a set of communicators to send and receive tasks.
11 // The expected colors have the following meaning:
12 // - color[0] is shared by all my co-workers
13 // - color[1] is shared by the optimizer leader and the pilot
14 // - color[2] is shared by the worker leader and the pilot
15 // - color[3] is shared by all processors with the same role (used for
16 // broadcasts)
17 //
18 // Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
19 // All rights reserved
20 //
21 // Implemented as part of the PhD thesis
22 // "Toward massively parallel multi-objective optimization with application to
23 // particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
24 //
25 // This file is part of OPAL.
26 //
27 // OPAL is free software: you can redistribute it and/or modify
28 // it under the terms of the GNU General Public License as published by
29 // the Free Software Foundation, either version 3 of the License, or
30 // (at your option) any later version.
31 //
32 // You should have received a copy of the GNU General Public License
33 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
34 //
35 #ifndef __COMM_SPLITTER__
36 #define __COMM_SPLITTER__
37 
38 #include "mpi.h"
39 
40 #include "Comm/types.h"
41 #include "Util/Types.h"
42 #include "Util/CmdArguments.h"
43 #include "Util/OptPilotException.h"
44 
45 //TODO: what is the performance difference between using MPI_COMM_WORLD and
46 // p2p communication vs. communicator groups??
47 template< class Strategy_t >
48 class CommSplitter : public Strategy_t {
49 
50 public:
51 
52  CommSplitter(CmdArguments_t args, MPI_Comm comm = MPI_COMM_WORLD)
53  : Strategy_t(args, comm)
54  , world_comm_(comm)
55  {
56  MPI_Comm_group(world_comm_, &world_group_);
57  MPI_Comm_rank(world_comm_, &global_rank_);
58 
59  // the splitter strategy computes the colorings
60  Strategy_t::split();
61 
62  my_opt_comm_ = MPI_COMM_NULL;
63  my_worker_comm_ = MPI_COMM_NULL;
64  my_coworker_comm_ = MPI_COMM_NULL;
65 
66 
67  MPI_Comm_split(world_comm_, Strategy_t::colorings_[0],
69 
70  MPI_Comm_split(world_comm_, Strategy_t::colorings_[1],
72 
73  MPI_Comm_split(world_comm_, Strategy_t::colorings_[2],
75 
76  MPI_Comm_split(world_comm_, Strategy_t::colorings_[3],
78 
79  // just a precaution to make sure everybody is ready
80  MPI_Barrier(world_comm_);
81  }
82 
83  virtual ~CommSplitter()
84  {
85  MPI_Group_free(&world_group_);
86  if(world_comm_ != MPI_COMM_WORLD)
87  MPI_Comm_free(&world_comm_);
88  }
89 
90  bool isOptimizer() const { return Strategy_t::role_ == OPTIMIZER; }
91  bool isWorker() const { return Strategy_t::role_ == WORKER; }
92  bool isPilot() const { return Strategy_t::role_ == POLLER; }
93 
94  MPI_Comm mpiComm() const { return world_comm_; }
95  int globalRank() const { return global_rank_; }
96  int pilotRank() const { return Strategy_t::poller_; }
97  int getLeader() const { return Strategy_t::leader_; }
98 
99  int getNrWorkerGroups() const { return Strategy_t::getNrWorkerGroups();}
100 
103 
104  Comm::Bundle_t bundle;
105 
106  bundle.island_id = Strategy_t::group_id_;
107 
108  bundle.leader_pid = Strategy_t::leader_;
109  bundle.master_pid = Strategy_t::poller_;
110  //FIXME: is it always 0?
111  bundle.master_local_pid = 0; //poller_local_pid_;
112 
113  bundle.worker = my_worker_comm_;
114  bundle.opt = my_opt_comm_;
115  bundle.coworkers = my_coworker_comm_;
116  bundle.world = my_comm_world_;
117 
118  return bundle;
119  }
120 
121 private:
122 
123  MPI_Comm world_comm_;
124  MPI_Group world_group_;
125 
128 
129  // define various communicators for communication between components
130  MPI_Comm my_worker_comm_;
131  MPI_Comm my_opt_comm_;
133  MPI_Comm my_comm_world_;
134 
137 };
138 
139 #endif
boost::shared_ptr< CmdArguments > CmdArguments_t
Definition: CmdArguments.h:176
@ POLLER
Definition: Types.h:35
@ OPTIMIZER
Definition: Types.h:35
@ WORKER
Definition: Types.h:35
int global_rank_
global MPI PID
Definition: CommSplitter.h:127
MPI_Comm my_opt_comm_
Definition: CommSplitter.h:131
MPI_Comm world_comm_
Definition: CommSplitter.h:123
MPI_Comm my_worker_comm_
Definition: CommSplitter.h:130
Comm::Bundle_t getBundle() const
construct comm bundle and return
Definition: CommSplitter.h:102
MPI_Group world_group_
Definition: CommSplitter.h:124
bool isOptimizer() const
Definition: CommSplitter.h:90
MPI_Comm my_coworker_comm_
Definition: CommSplitter.h:132
CommSplitter(CmdArguments_t args, MPI_Comm comm=MPI_COMM_WORLD)
Definition: CommSplitter.h:52
int pilotRank() const
Definition: CommSplitter.h:96
MPI_Comm mpiComm() const
Definition: CommSplitter.h:94
int poller_local_pid_
local (wrt. the communicator group) rank of the master/pilot process
Definition: CommSplitter.h:136
int globalRank() const
Definition: CommSplitter.h:95
MPI_Comm my_comm_world_
Definition: CommSplitter.h:133
int getLeader() const
Definition: CommSplitter.h:97
int getNrWorkerGroups() const
Definition: CommSplitter.h:99
bool isPilot() const
Definition: CommSplitter.h:92
virtual ~CommSplitter()
Definition: CommSplitter.h:83
bool isWorker() const
Definition: CommSplitter.h:91
bundles all communicators for a specific role/pid
Definition: types.h:32
MPI_Comm world
Definition: types.h:40
MPI_Comm coworkers
Definition: types.h:39
MPI_Comm worker
Definition: types.h:37
int leader_pid
Definition: types.h:34
int island_id
Definition: types.h:33
int master_pid
Definition: types.h:35
MPI_Comm opt
Definition: types.h:38
int master_local_pid
Definition: types.h:36