OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
MasterNode.h
Go to the documentation of this file.
1//
2// Class MasterNode
3// Implements a node in the network of all pilots, exposing store and
4// collect operations on a specific set of neighbors.
5//
6// Using the neighbor strategy a set of neighbors we collect solution state
7// from (and they collect from us) is defined. Using this set of neighbors the
8// solution states propagate throughout the network. The store and collect
9// operations are implemented using one sided MPI communication methods
10// (simulating shared memory).
11// A revision number is used to prevent receiving previously collected
12// solution states from neighbors.
13//
14// Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
15// All rights reserved
16//
17// Implemented as part of the PhD thesis
18// "Toward massively parallel multi-objective optimization with application to
19// particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
20//
21// This file is part of OPAL.
22//
23// OPAL is free software: you can redistribute it and/or modify
24// it under the terms of the GNU General Public License as published by
25// the Free Software Foundation, either version 3 of the License, or
26// (at your option) any later version.
27//
28// You should have received a copy of the GNU General Public License
29// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
30//
31#ifndef __MASTER_NODE__
32#define __MASTER_NODE__
33
34#include <set>
35#include <cmath>
36#include <vector>
37
38#include <string>
39#include <sstream>
40
41#include "mpi.h"
42
43#include <boost/archive/text_oarchive.hpp>
44#include <boost/archive/text_iarchive.hpp>
45#include <boost/serialization/vector.hpp>
46#include <boost/serialization/utility.hpp>
47
48
49//XXX: SolutionState_t must be serializable! (call
50// SerializableSolutionState_t?)
51template <
52 class SolutionState_t
53 , class NeighborStrategy_t
54>
55class MasterNode : public NeighborStrategy_t {
56
57
58public:
59
60 MasterNode(MPI_Comm master_comm, size_t buf_size_upper_bound, size_t dim,
61 int island_id)
62 : buf_size_upper_bound_(buf_size_upper_bound)
63 , master_comm_(master_comm) {
64
65 int tmp = 0;
66 MPI_Comm_rank(master_comm, &tmp);
67 myID_ = static_cast<size_t>(tmp);
68
69 MPI_Comm_size(master_comm, &tmp);
70 numMasters_ = static_cast<size_t>(tmp);
72
73 // better to use MPI-2 memory allocation methods
74 MPI_Alloc_mem(sizeof(char) * buf_size_upper_bound,
75 MPI_INFO_NULL, &serialized_best_values_);
76
77 // expose our shared memory holding our best values
78 MPI_Win_create(serialized_best_values_, buf_size_upper_bound,
79 sizeof(char), MPI_INFO_NULL, master_comm, &win_);
80
81 MPI_Win_create(&revision_, 1, sizeof(size_t), MPI_INFO_NULL,
82 master_comm, &win_rev_);
83
84
85 // execute neighbor strategy to learn which neighbors have to be
86 // updated with our solution state (and we collect from)
87 collectFrom_ = this->execute(numMasters_, dim, myID_, island_id);
88 }
89
91 MPI_Win_free(&win_);
92 MPI_Free_mem(serialized_best_values_);
93 MPI_Win_free(&win_rev_);
94 }
95
96
98 void store(char *local_state, size_t buffer_size) {
99
100 revision_++;
101 MPI_Win_fence(MPI_MODE_NOPUT, win_rev_);
102
103 size_t buf_size = buffer_size;
104 if(buf_size > buf_size_upper_bound_)
105 std::cout << "windows too small: " << buffer_size << " / "
107
108 memcpy(serialized_best_values_, local_state, buf_size);
109 MPI_Win_fence(MPI_MODE_NOPUT, win_);
110 //MPI_Win_fence((MPI_MODE_NOPUT | MPI_MODE_NOPRECEDE), win_);
111 }
112
113
115 void collect(std::ostringstream &states) {
116
117 char *buffer;
118 MPI_Alloc_mem(buf_size_upper_bound_, MPI_INFO_NULL, &buffer);
119 SolutionState_t tmp_states;
120
121
122 for(size_t i=0; i < numMasters_; i++) {
123 // ignore all except for selected master PIDs
124 if(i == myID_) continue;
125 if(collectFrom_.count(i) == 0) continue;
126
127 // only continue if new values are available on master i
128 size_t revision = 0;
129 MPI_Get(&revision, 1, MPI_UNSIGNED_LONG, i, 0, 1, MPI_UNSIGNED_LONG, win_rev_);
130 MPI_Win_fence(0, win_rev_);
131
132 if(revision <= revision_state_[i]) continue;
133 revision_state_[i] = revision;
134
135 MPI_Get(buffer, buf_size_upper_bound_, MPI_CHAR, i, 0,
136 buf_size_upper_bound_, MPI_CHAR, win_);
137 MPI_Win_fence(0, win_);
138
139 std::istringstream is(buffer);
140 boost::archive::text_iarchive ia(is);
141
142 //XXX: ugly that we have to know the SolutionState_t here
143 SolutionState_t state;
144 ia >> state;
145 tmp_states.insert(tmp_states.end(), state.begin(), state.end());
146 }
147
148 boost::archive::text_oarchive oa(states);
149 oa << tmp_states;
150
151 MPI_Free_mem(buffer);
152 }
153
154
155private:
156
159
163 MPI_Comm master_comm_;
164
165 // windows for storing revision and solution state
166 MPI_Win win_;
167 MPI_Win win_rev_;
168
169 size_t myID_;
170
172 std::set<size_t> collectFrom_;
174 size_t revision_;
176 std::vector<size_t> revision_state_;
177};
178
179#endif
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
boost::python::object execute(PyOpalObjectNS::PyOpalObject< TrackRun > &trackRun)
void collect(std::ostringstream &states)
collect all best values from all other masters
Definition: MasterNode.h:115
char * serialized_best_values_
pointer to MPI window holding current best solution state
Definition: MasterNode.h:158
std::vector< size_t > revision_state_
revision numbers of my neighbors
Definition: MasterNode.h:176
void store(char *local_state, size_t buffer_size)
store my best values
Definition: MasterNode.h:98
MPI_Win win_
Definition: MasterNode.h:166
MPI_Comm master_comm_
Definition: MasterNode.h:163
MasterNode(MPI_Comm master_comm, size_t buf_size_upper_bound, size_t dim, int island_id)
Definition: MasterNode.h:60
size_t myID_
Definition: MasterNode.h:169
size_t revision_
my solution state revision number
Definition: MasterNode.h:174
MPI_Win win_rev_
Definition: MasterNode.h:167
size_t buf_size_upper_bound_
and upper bound on the allocated memory in the MPI window
Definition: MasterNode.h:161
std::set< size_t > collectFrom_
neighbors we collect solution states from
Definition: MasterNode.h:172
size_t numMasters_
Definition: MasterNode.h:162