FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
splitter.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
10#include <kernel/global/gate.hpp>
11#include <kernel/global/muxer.hpp>
12#include <kernel/global/vector.hpp>
13
14namespace FEAT
15{
16 namespace Global
17 {
57 template<typename LocalVector_, typename Mirror_>
59 {
60 public:
63
65 typedef LocalVector_ LocalVectorType;
66
68 typedef Mirror_ MirrorType;
69
72
73 public:
77 LocalVector_ _base_vector_tmpl;
78
79 public:
82 _muxer(),
84 {
85 }
86
88 Splitter(Splitter&& other) :
89 _muxer(std::forward<MuxerType>(other._muxer)),
90 _base_vector_tmpl(std::forward<LocalVector_>(other._base_vector_tmpl))
91 {
92 }
93
94 explicit Splitter(MuxerType&& muxer, LocalVector_&& base_vector_tmpl) :
95 _muxer(std::forward<MuxerType>(muxer)),
96 _base_vector_tmpl(std::forward<LocalVector_>(base_vector_tmpl))
97 {
98 }
99
101 virtual ~Splitter()
102 {
103 }
104
107 {
108 if(this == &other)
109 return *this;
110
111 _muxer = std::forward<MuxerType>(other._muxer);
112 _base_vector_tmpl = std::forward<LocalVector_>(other._base_vector_tmpl);
113
114 return *this;
115 }
116
123 template<typename LVT2_, typename MT2_>
125 {
126 if((void*)this == (void*)&other)
127 return;
128
129 this->_muxer.convert(other._muxer);
130 this->_base_vector_tmpl.convert(other._base_vector_tmpl);
131 }
132
152 template<typename LVT2_>
153 void convert(const Splitter<LVT2_, Mirror_>& other, LocalVector_&& vector, LAFEM::CloneMode mode = LAFEM::CloneMode::Shallow)
154 {
155 if((void*)this == (void*)&other)
156 return;
157
158 this->_muxer.convert(other._muxer, std::forward<LocalVector_>(vector), mode);
159 this->_base_vector_tmpl.clear(); // needs to be supplied later
160 }
161
163 std::size_t bytes() const
164 {
165 return _muxer.bytes() + _base_vector_tmpl.bytes();
166 }
167
176 bool is_root() const
177 {
178 return (_muxer.get_sibling_comm() == nullptr) || _muxer.is_parent();
179 }
180
186 bool is_single() const
187 {
188 return (_muxer.get_sibling_comm() == nullptr) || (_muxer.get_sibling_comm()->size() == 1);
189 }
190
203 void set_root(const Dist::Comm* comm, int root_rank, Mirror_&& root_mirror)
204 {
205 this->_muxer.set_parent(comm, root_rank, std::forward<Mirror_>(root_mirror));
206 }
207
214 void push_patch(Mirror_&& patch_mirror)
215 {
216 _muxer.push_child(std::forward<Mirror_>(patch_mirror));
217 }
218
230 void set_base_vector_template(LocalVector_&& vector_template)
231 {
232 _base_vector_tmpl = std::forward<LocalVector_>(vector_template);
233 }
234
236 const LocalVector_& get_base_vector_template() const
237 {
238 return _base_vector_tmpl;
239 }
240
242 const MuxerType& get_muxer() const
243 {
244 return _muxer;
245 }
246
253 void compile(const LocalVector_& vec_tmp_)
254 {
255 _muxer.compile(vec_tmp_);
256 }
257
264 LocalVector_ create_base_vector() const
265 {
266 XASSERT(!this->_base_vector_tmpl.empty());
267 return this->_base_vector_tmpl.clone(LAFEM::CloneMode::Layout);
268 }
269
283 LocalVector_ join(const Global::Vector<LocalVector_, Mirror_>& vector) const
284 {
285 // are there no other processes involved here?
286 if(is_single())
287 return vector.local().clone();
288
289 // make sure the root rank has a base-vector template
290 if(is_root())
291 {
292 XASSERTM(_base_vector_tmpl.size() > Index(0), "root process must have a base vector template");
293 }
294
295 // create an base-mesh vector (may be empty on all processes except for parent)
296 LocalVector_ vec_base(this->_base_vector_tmpl.clone(LAFEM::CloneMode::Layout));
297
298 // actual join
299 join(vec_base, vector);
300
301 // return local vector
302 return vec_base;
303 }
304
320 void join(LocalVector_& vec_base, const Global::Vector<LocalVector_, Mirror_>& vector) const
321 {
322 // are there no other processes involved here?
323 if(is_single())
324 {
325 vec_base.copy(vector.local());
326 return;
327 }
328
329 // Note: the 'join' of the muxer class works with type-0 vectors, so we need to create a
330 // temporary type-0 conversion of our input vector here, which is assumed to be a type-1
331 // vector. In theory, we also should apply a 'sync_0' on the returned vector, but since
332 // its a 'local' vector on the whole base-mesh domain, it is redundant and it also does
333 // not make sense due to the lack of a gate on the base-mesh, i.e. on the base-mesh
334 // type-0 and type-1 are the same thing.
335
336 // convert input vector to type 0
338 vector_0.from_1_to_0();
339
340 // is this the muxer parent or only a child process?
341 if(_muxer.is_parent())
342 {
343 _muxer.join(vector_0.local(), vec_base);
344 }
345 else
346 {
348 _muxer.join_send(vector_0.local());
349 }
350 }
351
362 void split(Global::Vector<LocalVector_, Mirror_>& vector, const LocalVector_& vec_base) const
363 {
364 // call patch-local version
365 split(vector.local(), vec_base);
366 }
367
378 void split(LocalVector_& vector, const LocalVector_& vec_base) const
379 {
380 // are there no other processes involved here?
381 if(is_single())
382 {
383 // simply copy the local vector contents
384 vector.copy(vec_base);
385 return;
386 }
387
388 // do we have a base muxer?
389 if(_muxer.is_parent())
390 {
391 _muxer.split(vector, vec_base);
392 }
393 else
394 {
396 _muxer.split_recv(vector);
397 }
398 }
399
418 {
419 // actual join
420 LocalVector_ vec_base(join(vector));
421
422 // if we're the parent (rank 0), then we do the actual write out
423 if(this->is_root())
424 {
425 vec_base.write_out(mode, filename);
426 }
427 }
428
444 {
445 split_read_from(vector.local(), filename, mode);
446 }
447
461 void split_read_from(LocalVector_& vector, const String& filename,
463 {
464 // create an empty base-mesh vector
465 LocalVector_ vec_base;
466
467 // if we're the parent (rank 0), then we do the actual read from
468 if(this->is_root())
469 {
470 // read the actual vector
471 vec_base.read_from(mode, filename);
472 }
473
474 // split the vector
475 split(vector, vec_base);
476 }
477 }; // class Splitter<...>
478 } // namespace Global
479} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT Kernel base header.
Communicator class.
Definition: dist.hpp:1349
int size() const
Returns the size of this communicator.
Definition: dist.hpp:1506
Global multiplexer/demultiplexer implementation.
Definition: muxer.hpp:68
bool is_child() const
Specifies whether this process represents a child in the muxer.
Definition: muxer.hpp:225
std::size_t bytes() const
Returns the internal data size in bytes.
Definition: muxer.hpp:211
void join_send(const LocalVector_ &vec_src) const
Sends a join operation to the parent process.
Definition: muxer.hpp:375
void compile(const LocalVector_ &vec_tmp_)
Compiles the muxer.
Definition: muxer.hpp:334
void convert(const Muxer< LVT2_, MT2_ > &other)
Conversion function for same vector container type but with different MDI-Type.
Definition: muxer.hpp:155
const Dist::Comm * get_sibling_comm() const
Returns the sibling communicator.
Definition: muxer.hpp:260
bool is_parent() const
Specifies whether this process represents a parent in the muxer.
Definition: muxer.hpp:236
void split_recv(LocalVector_ &vec_trg) const
Receives a split operation from the parent process.
Definition: muxer.hpp:449
void join(const LocalVector_ &vec_src, LocalVector_ &vec_trg) const
Performs a join operation on the parent process.
Definition: muxer.hpp:401
void push_child(Mirror_ &&child_mirror)
Adds a child rank and mirror for a parent process.
Definition: muxer.hpp:313
void set_parent(const Dist::Comm *sibling_comm_, int parent_rank, Mirror_ &&parent_mirror)
Sets the sibling communicator.
Definition: muxer.hpp:277
void split(LocalVector_ &vec_trg, const LocalVector_ &vec_src) const
Performs a split operation on the parent process.
Definition: muxer.hpp:476
Global base-mesh vector splitter (and joiner) implementation.
Definition: splitter.hpp:59
void set_base_vector_template(LocalVector_ &&vector_template)
Sets the base-vector template on the root process.
Definition: splitter.hpp:230
virtual ~Splitter()
destructor
Definition: splitter.hpp:101
Global::Muxer< LocalVector_, Mirror_ > MuxerType
our internal muxer type
Definition: splitter.hpp:62
LocalVector_ _base_vector_tmpl
our base-mesh vector template; only required for join() but not for split()
Definition: splitter.hpp:77
LocalVector_ join(const Global::Vector< LocalVector_, Mirror_ > &vector) const
Joins a global vector into a base-mesh local vector on the root process.
Definition: splitter.hpp:283
MuxerType _muxer
our internal muxer
Definition: splitter.hpp:75
void set_root(const Dist::Comm *comm, int root_rank, Mirror_ &&root_mirror)
Sets the root communicator.
Definition: splitter.hpp:203
void split_read_from(LocalVector_ &vector, const String &filename, LAFEM::FileMode mode=LAFEM::FileMode::fm_binary) const
Reads in a base-mesh local vector and splits it into a patch-local vector.
Definition: splitter.hpp:461
void split(Global::Vector< LocalVector_, Mirror_ > &vector, const LocalVector_ &vec_base) const
Splits a base-mesh local vector on the root process into a global vector.
Definition: splitter.hpp:362
void compile(const LocalVector_ &vec_tmp_)
Compiles the muxer.
Definition: splitter.hpp:253
std::size_t bytes() const
Returns the internal data size in bytes.
Definition: splitter.hpp:163
Splitter & operator=(Splitter &&other)
move-assign operator
Definition: splitter.hpp:106
Splitter()
standard constructor
Definition: splitter.hpp:81
void convert(const Splitter< LVT2_, MT2_ > &other)
Conversion function for same vector container type but with different MDI-Type.
Definition: splitter.hpp:124
void convert(const Splitter< LVT2_, Mirror_ > &other, LocalVector_ &&vector, LAFEM::CloneMode mode=LAFEM::CloneMode::Shallow)
Conversion function for different vector container type.
Definition: splitter.hpp:153
LocalVector_ LocalVectorType
our local vector type
Definition: splitter.hpp:65
Splitter(Splitter &&other)
move-constructor
Definition: splitter.hpp:88
Global::Vector< LocalVector_, Mirror_ > GlobalVectorType
our global vector type
Definition: splitter.hpp:71
void join(LocalVector_ &vec_base, const Global::Vector< LocalVector_, Mirror_ > &vector) const
Joins a global vector into a base-mesh local vector on the root process.
Definition: splitter.hpp:320
void split(LocalVector_ &vector, const LocalVector_ &vec_base) const
Splits a base-mesh local vector on the root process into a patch-local vector.
Definition: splitter.hpp:378
Mirror_ MirrorType
our mirror type
Definition: splitter.hpp:68
void split_read_from(Global::Vector< LocalVector_, Mirror_ > &vector, const String &filename, LAFEM::FileMode mode=LAFEM::FileMode::fm_binary) const
Reads in a base-mesh local vector and splits it into a global vector.
Definition: splitter.hpp:442
void push_patch(Mirror_ &&patch_mirror)
Adds a child rank and mirror for the parent process.
Definition: splitter.hpp:214
void join_write_out(const Global::Vector< LocalVector_, Mirror_ > &vector, const String &filename, LAFEM::FileMode mode=LAFEM::FileMode::fm_binary) const
Joins a global vector into a base-mesh local vector and writes it to a file.
Definition: splitter.hpp:416
LocalVector_ create_base_vector() const
Creates a new base-mesh vector.
Definition: splitter.hpp:264
bool is_single() const
Checks whether there is only one process in the communicator.
Definition: splitter.hpp:186
bool is_root() const
Checks whether this is the root process.
Definition: splitter.hpp:176
const LocalVector_ & get_base_vector_template() const
Returns the base vector template.
Definition: splitter.hpp:236
const MuxerType & get_muxer() const
Returns the internal muxer.
Definition: splitter.hpp:242
Global vector wrapper class template.
Definition: vector.hpp:68
void from_1_to_0()
Converts a type-1 vector into a type-0 vector.
Definition: vector.hpp:172
Vector clone(LAFEM::CloneMode mode=LAFEM::CloneMode::Weak) const
Creates and returns a clone of this global vector.
Definition: vector.hpp:269
LocalVector_ & local()
Returns a reference to the internal local LAFEM vector object.
Definition: vector.hpp:121
String class implementation.
Definition: string.hpp:46
LAFEM common type definitions.
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.