ECOGEN 4.0
Evolutive, Compressible, Open, Genuine, Easy, N-phase
Loading...
Searching...
No Matches
decomposition.hpp
Go to the documentation of this file.
1//
2// ,---. ,--, .---. ,--, ,---. .-. .-.
3// | .-' .' .') / .-. ) .' .' | .-' | \| |
4// | `-. | |(_) | | |(_) | | __ | `-. | | |
5// | .-' \ \ | | | | \ \ ( _) | .-' | |\ |
6// | `--. \ `-. \ `-' / \ `-) ) | `--. | | |)|
7// /( __.' \____\ )---' )\____/ /( __.' /( (_)
8// (__) (_) (__) (__) (__)
9//
10// This file is part of ECOGEN.
11//
12// ECOGEN is the legal property of its developers, whose names
13// are listed in the copyright file included with this source
14// distribution.
15//
16// ECOGEN is free software: you can redistribute it and/or modify
17// it under the terms of the GNU General Public License as published
18// by the Free Software Foundation, either version 3 of the License,
19// or (at your option) any later version.
20//
21// ECOGEN is distributed in the hope that it will be useful,
22// but WITHOUT ANY WARRANTY; without even the implied warranty of
23// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24// GNU General Public License for more details.
25//
26// You should have received a copy of the GNU General Public License
27// along with ECOGEN (file LICENSE).
28// If not, see <http://www.gnu.org/licenses/>.
29
30#ifndef INCLUDED_DECOMP_HPP
31#define INCLUDED_DECOMP_HPP
32
33#include <algorithm>
34#include <numeric>
35#include <functional>
36#include "key.hpp"
37#include <map>
38
40{
41
43{
44
45public:
46 static constexpr int Dim=3;
48
49
50public: //Ctors
51 Decomposition() = default;
52 Decomposition(const Decomposition& /*other*/) = default;
53 Decomposition(Decomposition&& /*other*/) = default;
54 Decomposition& operator=(const Decomposition& /*other*/) & = default;
55 Decomposition& operator=(Decomposition&& /*other*/) & = default;
56 ~Decomposition() = default;
57
58
59
60 Decomposition(std::array<int,Dim> _nCells)
61 :nCells_global_(_nCells)
62 {}
63
64 void printDomainDecomposition(std::ofstream &fileStream) const noexcept
65 {
66 fileStream << key_rank_map_.size() << " ";
67 auto it = key_rank_map_.begin();
68 while (it != key_rank_map_.end()) {
69 fileStream << it->first.getIndex() << " " << it->second << " ";
70 ++it;
71 }
72 }
73
74 void readDomainDecomposition(std::ifstream &fileStream) noexcept
75 {
76 int sizeKeyRankMap(0), rank(0);
77 fileStream >> sizeKeyRankMap;
78 typename key_type::value_type key(0);
79 for (int i = 0; i < sizeKeyRankMap; ++i)
80 {
81 fileStream >> key;
82 fileStream >> rank;
83 key_rank_map_.emplace(key, rank);
84 }
85 }
86
87 void updatePhysicalDomainSizes(std::array<int,Dim> _nCells) noexcept
88 {
89 nCells_global_ = _nCells;
90 }
91
92 std::vector<key_type> initialize(int nProcs, int _rank, int restartSimulation) noexcept
93 {
94 std::vector<key_type> keys;
95
96 if (restartSimulation == 0) {
97 auto nCells_t = std::accumulate(nCells_global_.begin(),nCells_global_.end(),1,
98 std::multiplies<int>());
99
100 float chunks = static_cast<float>(nCells_t+0.5)/nProcs;
101 key_type key(0,0,0);
102 std::vector<int> nCells_per_rank;
103 for (int i = 0; i < nProcs; ++i)
104 {
105 size_t start = (size_t)(i*chunks);
106 size_t end = std::min(static_cast<int>((i+1)*chunks), nCells_t);
107 const int nlocal = end-start;
108 int count = 0;
109 key_rank_map_.emplace(key, i);
110 nCells_per_rank.emplace_back(nlocal);
111
112 while (count < nlocal)
113 {
114 if (is_valid(key)) ++count;
115 ++key;
116 }
117
118 //Store also end, to check validity:
119 if (i == nProcs-1)
120 {
121 nCells_per_rank.emplace_back(0);
122 key_rank_map_.emplace(--key, i);
123 }
124 }
125
126 auto key_it = key_rank_map_.begin();
127 std::advance(key_it, _rank);
128 key = key_it->first;
129 auto nCells = nCells_per_rank[_rank];
130 keys.resize(nCells);
131
132 for (int i = 0; i < nCells; ++i)
133 {
134 bool valid = false;
135 while (!valid)
136 {
137 if (is_valid(key))
138 {
139 valid = true;
140 keys[i] = key;
141 }
142 ++key;
143 }
144 }
145 }
146 else {
147 auto map_key = key_rank_map_.begin();
148 auto map_key_next = std::next(map_key);
149 while (map_key->first != key_rank_map_.rbegin()->first) {
150 if (map_key->second == _rank) {
151 auto key = map_key->first;
152 while (key != map_key_next->first) {
153 if (is_valid(key) || (key == key_rank_map_.rbegin()->first)) {
154 keys.push_back(key);
155 }
156 ++key;
157 }
158 }
159 ++map_key;
160 ++map_key_next;
161 }
162 }
163
164 return keys;
165 }
166
168 {
169 while (true)
170 {
171 ++_key0;
172 if (is_valid(_key0))
173 {
174 return _key0 == _key1;
175 }
176 }
177 }
178
179 int get_rank(const key_type& _key)
180 {
181 auto range = key_rank_map_.equal_range(_key);
182 if (range.first->first == range.second->first) {
183 auto it = range.first;
184 return (--it)->second;
185 }
186 else {
187 return range.first->second;
188 }
189 }
190
191 bool is_valid(const key_type& _key) const noexcept
192 {
193 return (_key.coordinate()[0] < nCells_global_[0] &&
194 _key.coordinate()[1] < nCells_global_[1] &&
195 _key.coordinate()[2] < nCells_global_[2] ) ;
196 }
197
198 template<class Coord>
199 bool is_inside(const Coord& _coord)
200 {
201 for (int d = 0; d < Dim; ++d)
202 {
203 if (_coord[d]<0 || _coord[d] >= nCells_global_[d])
204 return false;
205 }
206 return true;
207 }
208
210 {
211 auto it = key_rank_map_.begin(), itPrev = it++;
212 while (it != --(key_rank_map_.end())) {
213 if (it->second == itPrev->second) {
214 it = key_rank_map_.erase(it);
215 }
216 else {
217 itPrev = it;
218 ++it;
219 }
220 }
221 }
222
223 void communicateMaps(int _nCpu, std::vector<typename key_type::value_type>& localKeys, std::vector<int>& localRanks)
224 {
225 //Decompose local map into keys and values (ranks)
226 int localMapSize = localKeys.size();
227
228 //All gather sizes of maps
229 std::vector<int> mapSizes(_nCpu);
230 MPI_Allgather(&localMapSize, 1, MPI_INT, &mapSizes[0], 1, MPI_INT, MPI_COMM_WORLD);
231
232 //All gather maps (keys and ranks)
233 std::vector<int> displacements(_nCpu);
234 int sumMapSizes = 0;
235 for (int i = 0; i < _nCpu; ++i)
236 {
237 displacements[i] = sumMapSizes;
238 sumMapSizes += mapSizes[i];
239 }
240 std::vector<typename key_type::value_type> globalKeys(sumMapSizes);
241 std::vector<int> globalRanks(sumMapSizes);
242 MPI_Allgatherv(&localKeys[0], localMapSize, MPI_UNSIGNED_LONG_LONG, &globalKeys[0], &mapSizes[0], &displacements[0], MPI_UNSIGNED_LONG_LONG, MPI_COMM_WORLD);
243 MPI_Allgatherv(&localRanks[0], localMapSize, MPI_INT, &globalRanks[0], &mapSizes[0], &displacements[0], MPI_INT, MPI_COMM_WORLD);
244
245 //Compose global map from keys and ranks
246 auto keyRankEnd = *(key_rank_map_.rbegin());
247 key_rank_map_.clear();
248 key_rank_map_.emplace(keyRankEnd);
249 for (std::size_t i = 0; i < globalKeys.size(); ++i)
250 {
251 key_rank_map_.emplace(globalKeys[i], globalRanks[i]);
252 }
253 }
254
255
256private:
257 std::array<int,Dim> nCells_global_;
258 std::map<key_type, int> key_rank_map_;
259
260};
261}
262
263#endif
Class for a coordinate system object such as coordinates of the vertex or a vector.
Definition Coord.h:43
Definition decomposition.hpp:43
void printDomainDecomposition(std::ofstream &fileStream) const noexcept
Definition decomposition.hpp:64
void communicateMaps(int _nCpu, std::vector< typename key_type::value_type > &localKeys, std::vector< int > &localRanks)
Definition decomposition.hpp:223
bool is_inside(const Coord &_coord)
Definition decomposition.hpp:199
void readDomainDecomposition(std::ifstream &fileStream) noexcept
Definition decomposition.hpp:74
Decomposition(const Decomposition &)=default
bool is_valid(const key_type &_key) const noexcept
Definition decomposition.hpp:191
bool areConsecutive(key_type _key0, key_type _key1)
Definition decomposition.hpp:167
std::map< key_type, int > key_rank_map_
Definition decomposition.hpp:258
static constexpr int Dim
Definition decomposition.hpp:46
Decomposition(Decomposition &&)=default
std::vector< key_type > initialize(int nProcs, int _rank, int restartSimulation) noexcept
Definition decomposition.hpp:92
Decomposition & operator=(Decomposition &&) &=default
void updatePhysicalDomainSizes(std::array< int, Dim > _nCells) noexcept
Definition decomposition.hpp:87
int get_rank(const key_type &_key)
Definition decomposition.hpp:179
Decomposition(std::array< int, Dim > _nCells)
Definition decomposition.hpp:60
Decomposition & operator=(const Decomposition &) &=default
std::array< int, Dim > nCells_global_
Definition decomposition.hpp:257
void recombineStarts()
Definition decomposition.hpp:209
Definition decomposition.hpp:40
Definition key.hpp:50
unsigned long long int value_type
Definition key.hpp:54