OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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"
44
45//TODO: what is the performance difference between using MPI_COMM_WORLD and
46// p2p communication vs. communicator groups??
47template< class Strategy_t >
48class CommSplitter : public Strategy_t {
49
50public:
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_;
116 bundle.world = my_comm_world_;
117
118 return bundle;
119 }
120
121private:
122
123 MPI_Comm world_comm_;
124 MPI_Group world_group_;
125
128
129 // define various communicators for communication between components
131 MPI_Comm my_opt_comm_;
134
137};
138
139#endif
@ POLLER
Definition: Types.h:35
@ OPTIMIZER
Definition: Types.h:35
@ WORKER
Definition: Types.h:35
boost::shared_ptr< CmdArguments > CmdArguments_t
Definition: CmdArguments.h:176
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