ECOGEN 6.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
45 public:
46 static constexpr int Dim = 3;
48
49 public: //Ctors
50 Decomposition() = default;
51 Decomposition(const Decomposition& /*other*/) = default;
52 Decomposition(Decomposition&& /*other*/) = default;
53 Decomposition& operator=(const Decomposition& /*other*/) & = default;
54 Decomposition& operator=(Decomposition&& /*other*/) & = default;
55 ~Decomposition() = default;
56
57 Decomposition(std::array<int, Dim> _nCells) : nCells_global_(_nCells) {}
58
59 void printDomainDecomposition(std::ofstream& fileStream) const noexcept
60 {
61 fileStream << key_rank_map_.size() << " ";
62 auto it = key_rank_map_.begin();
63 while (it != key_rank_map_.end()) {
64 fileStream << it->first.getIndex() << " " << it->second << " ";
65 ++it;
66 }
67 }
68
69 void readDomainDecomposition(std::ifstream& fileStream) noexcept
70 {
71 int sizeKeyRankMap(0), rank(0);
72 fileStream >> sizeKeyRankMap;
73 typename key_type::value_type key(0);
74 for (int i = 0; i < sizeKeyRankMap; ++i) {
75 fileStream >> key;
76 fileStream >> rank;
77 key_rank_map_.emplace(key, rank);
78 }
79 }
80
81 void updatePhysicalDomainSizes(std::array<int, Dim> _nCells) noexcept { nCells_global_ = _nCells; }
82
83 std::vector<key_type> initialize(int nProcs, int _rank, int resumeSimulation) noexcept
84 {
85 std::vector<key_type> keys;
86
87 if (resumeSimulation == 0) {
88 auto nCells_t = std::accumulate(nCells_global_.begin(), nCells_global_.end(), 1, std::multiplies<int>());
89
90 float chunks = static_cast<float>(nCells_t + 0.5) / nProcs;
91 key_type key(0, 0, 0);
92 std::vector<int> nCells_per_rank;
93 for (int i = 0; i < nProcs; ++i) {
94 size_t start = (size_t)(i * chunks);
95 size_t end = std::min(static_cast<int>((i + 1) * chunks), nCells_t);
96 const int nlocal = end - start;
97 int count = 0;
98 key_rank_map_.emplace(key, i);
99 nCells_per_rank.emplace_back(nlocal);
100
101 while (count < nlocal) {
102 if (is_valid(key)) ++count;
103 ++key;
104 }
105
106 //Store also end, to check validity:
107 if (i == nProcs - 1) {
108 nCells_per_rank.emplace_back(0);
109 key_rank_map_.emplace(--key, i);
110 }
111 }
112
113 auto key_it = key_rank_map_.begin();
114 std::advance(key_it, _rank);
115 key = key_it->first;
116 auto nCells = nCells_per_rank[_rank];
117 keys.resize(nCells);
118
119 for (int i = 0; i < nCells; ++i) {
120 bool valid = false;
121 while (!valid) {
122 if (is_valid(key)) {
123 valid = true;
124 keys[i] = key;
125 }
126 ++key;
127 }
128 }
129 }
130 else {
131 auto map_key = key_rank_map_.begin();
132 auto map_key_next = std::next(map_key);
133 while (map_key->first != key_rank_map_.rbegin()->first) {
134 if (map_key->second == _rank) {
135 auto key = map_key->first;
136 while (key != map_key_next->first) {
137 if (is_valid(key) || (key == key_rank_map_.rbegin()->first)) {
138 keys.push_back(key);
139 }
140 ++key;
141 }
142 }
143 ++map_key;
144 ++map_key_next;
145 }
146 }
147
148 return keys;
149 }
150
152 {
153 while (true) {
154 ++_key0;
155 if (is_valid(_key0)) {
156 return _key0 == _key1;
157 }
158 }
159 }
160
161 int get_rank(const key_type& _key)
162 {
163 auto range = key_rank_map_.equal_range(_key);
164 if (range.first->first == range.second->first) {
165 auto it = range.first;
166 return (--it)->second;
167 }
168 else {
169 return range.first->second;
170 }
171 }
172
173 bool is_valid(const key_type& _key) const noexcept
174 {
175 return (_key.coordinate()[0] < nCells_global_[0] && _key.coordinate()[1] < nCells_global_[1] && _key.coordinate()[2] < nCells_global_[2]);
176 }
177
178 template <class Coord> bool is_inside(const Coord& _coord)
179 {
180 for (int d = 0; d < Dim; ++d) {
181 if (_coord[d] < 0 || _coord[d] >= nCells_global_[d]) return false;
182 }
183 return true;
184 }
185
187 {
188 auto it = key_rank_map_.begin(), itPrev = it++;
189 while (it != --(key_rank_map_.end())) {
190 if (it->second == itPrev->second) {
191 it = key_rank_map_.erase(it);
192 }
193 else {
194 itPrev = it;
195 ++it;
196 }
197 }
198 }
199
200 void communicateMaps(int _nCpu, std::vector<typename key_type::value_type>& localKeys, std::vector<int>& localRanks)
201 {
202 //Decompose local map into keys and values (ranks)
203 int localMapSize = localKeys.size();
204
205 //All gather sizes of maps
206 std::vector<int> mapSizes(_nCpu);
207 MPI_Allgather(&localMapSize, 1, MPI_INT, &mapSizes[0], 1, MPI_INT, MPI_COMM_WORLD);
208
209 //All gather maps (keys and ranks)
210 std::vector<int> displacements(_nCpu);
211 int sumMapSizes = 0;
212 for (int i = 0; i < _nCpu; ++i) {
213 displacements[i] = sumMapSizes;
214 sumMapSizes += mapSizes[i];
215 }
216 std::vector<typename key_type::value_type> globalKeys(sumMapSizes);
217 std::vector<int> globalRanks(sumMapSizes);
218 MPI_Allgatherv(
219 &localKeys[0], localMapSize, MPI_UNSIGNED_LONG_LONG, &globalKeys[0], &mapSizes[0], &displacements[0], MPI_UNSIGNED_LONG_LONG, MPI_COMM_WORLD);
220 MPI_Allgatherv(&localRanks[0], localMapSize, MPI_INT, &globalRanks[0], &mapSizes[0], &displacements[0], MPI_INT, MPI_COMM_WORLD);
221
222 //Compose global map from keys and ranks
223 auto keyRankEnd = *(key_rank_map_.rbegin());
224 key_rank_map_.clear();
225 key_rank_map_.emplace(keyRankEnd);
226 for (std::size_t i = 0; i < globalKeys.size(); ++i) {
227 key_rank_map_.emplace(globalKeys[i], globalRanks[i]);
228 }
229 }
230
231 private:
232 std::array<int, Dim> nCells_global_;
233 std::map<key_type, int> key_rank_map_;
234};
235} //namespace decomposition
236
237#endif
long nCells
Definition Tools.cpp:39
Class for a coordinate system object such as coordinates of the vertex or a vector.
Definition Coord.h:43
void printDomainDecomposition(std::ofstream &fileStream) const noexcept
Definition decomposition.hpp:59
void communicateMaps(int _nCpu, std::vector< typename key_type::value_type > &localKeys, std::vector< int > &localRanks)
Definition decomposition.hpp:200
std::array< int, Dim > nCells_global_
Definition decomposition.hpp:232
bool is_inside(const Coord &_coord)
Definition decomposition.hpp:178
void readDomainDecomposition(std::ifstream &fileStream) noexcept
Definition decomposition.hpp:69
Decomposition(const Decomposition &)=default
bool is_valid(const key_type &_key) const noexcept
Definition decomposition.hpp:173
bool areConsecutive(key_type _key0, key_type _key1)
Definition decomposition.hpp:151
std::map< key_type, int > key_rank_map_
Definition decomposition.hpp:233
static constexpr int Dim
Definition decomposition.hpp:46
Decomposition(Decomposition &&)=default
std::vector< key_type > initialize(int nProcs, int _rank, int resumeSimulation) noexcept
Definition decomposition.hpp:83
Decomposition & operator=(Decomposition &&) &=default
void updatePhysicalDomainSizes(std::array< int, Dim > _nCells) noexcept
Definition decomposition.hpp:81
int get_rank(const key_type &_key)
Definition decomposition.hpp:161
Key< Dim > key_type
Definition decomposition.hpp:47
Decomposition(std::array< int, Dim > _nCells)
Definition decomposition.hpp:57
Decomposition & operator=(const Decomposition &) &=default
void recombineStarts()
Definition decomposition.hpp:186
Definition decomposition.hpp:40
Definition key.hpp:43
unsigned long long int value_type
Definition key.hpp:46