MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
acaobserverdatacollector.h
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#ifndef ACAOBSERVERDATACOLLECTOR_H_
8#define ACAOBSERVERDATACOLLECTOR_H_
9
10#include <algorithm>
11#include <limits>
12#include <numeric>
13#include <type_traits>
14#include <vector>
15#include "INCLUDE/maiamacro.h"
16#include "INCLUDE/maiatypes.h"
17#include "MEMORY/container.h"
18#include "UTIL/functions.h"
19#include "compiler_config.h"
20
21// The following macro enables the "Structure-of-Arrays" memory layout for multi-dimensional node
22// variables. This might be beneficial for GPU computations. Default is "Array-of-Structures".
23// Examples (for nodes nN with four children cM each)
24// Array-of-Structures (AOS): n0c0, n0c1, n0c2, n0c3, n1c0, n1c1, n1c2, n1c3, n2c0, n2c1, ...
25// Structure-of-Arrays (SOA): n0c0, n1c0, n2c0, n3c0, ..., n0c1, n1c1, n2c1, n3c1, ..., n0c2, ...
26// #define ACACOLLECTOR_SOA_MEMORY_LAYOUT
27
28// The macro 'ACACOLLECTOR_SANITY_CHECKS_ACCESSORS' enables (potentially very expensive) sanity
29// checks
30// for all accessors. It is enabled for build type "extra_debug".
31//#ifdef MAIA_EXTRA_DEBUG
32// NOTE: enable checks in normal debug mode until everything is working correctly!
33#ifndef NDEBUG
34#define ACACOLLECTOR_SANITY_CHECKS_ACCESSORS
35#endif
36
37// Sanity-checking macros for accessors
38#if defined(ACACOLLECTOR_SANITY_CHECKS_ACCESSORS) || defined(MAIA_ASSERT_ACCESSORS)
39#define ENSURE_VALID_ID_ACCESSOR(id) \
40 do { \
41 MAIA_CONTAINER_ENSURE_VALID_ID(id); \
42 } while(false)
43#define ENSURE_VALID_VARIABLE_ID_ACCESSOR(id) \
44 do { \
45 MAIA_CONTAINER_ENSURE( \
46 id >= 0 && id < noVars(), \
47 "variable id " + std::to_string(id) + " out-of-bounds [0, " + std::to_string(noVars()) + ")", AT_); \
48 } while(false)
49#define ENSURE_VALID_SAMPLE_ID_ACCESSOR(id) \
50 do { \
51 MAIA_CONTAINER_ENSURE( \
52 id >= 0 && id < noSamples(), \
53 "sample id " + std::to_string(id) + " out-of-bounds [0, " + std::to_string(noSamples()) + ")", AT_); \
54 } while(false)
55#define ENSURE_CONDITION(condition, message) \
56 do { \
57 MAIA_CONTAINER_ENSURE(condition, message, AT_); \
58 } while(false)
59#else
60#define ENSURE_VALID_ID_ACCESSOR(id) \
61 do { \
62 } while(false)
63#define ENSURE_VALID_VARIABLE_ID_ACCESSOR(id) \
64 do { \
65 } while(false)
66#define ENSURE_VALID_SAMPLE_ID_ACCESSOR(id) \
67 do { \
68 } while(false)
69#define ENSURE_CONDITION(condition, message) \
70 do { \
71 } while(false)
72#endif
73
74
76namespace maia {
77namespace acoustic_analogy {
78namespace observer_collector {
79
80// Type traits for invalid values. These values are used to initialize/erase nodes
81template <class T>
82struct Invalid {};
83
84// Invalid value for ids is 'INT_MIN'
85template <>
86struct Invalid<MInt> {
87 static constexpr MInt value() { return std::numeric_limits<MInt>::min(); }
88};
89
90// Invalid value for longs is 'INT_MIN'
91template <>
92struct Invalid<MLong> {
93 static constexpr MLong value() { return std::numeric_limits<MLong>::min(); }
94};
95
96// Invalid value for floats is 'NaN'
97template <>
98struct Invalid<MFloat> {
99 static constexpr MFloat value() {
100#ifdef MAIA_PGI_COMPILER
101 return std::numeric_limits<MFloat>::quiet_NaN();
102#else
103 return std::numeric_limits<MFloat>::signaling_NaN();
104#endif
105 }
106};
107
108
110template <MInt nDim>
111class ObserverDataCollector : public maia::container::Container<ObserverDataCollector<nDim>, Invalid> {
112 // Necessary for CRTP
114
115 // Make base class functions known to use without this pointer
117 using Base::resetStorage;
118 template <class T>
119 using Storage = typename Base::template Storage<T>;
120
121 public:
122 // Types
123 template <class T>
125
126 // Constructor
128 constexpr ObserverDataCollector() = default;
129
130 // Ensure that base class method is found when called from outside
131 using Base::copyData;
132 using Base::fill_invalid;
133 using Base::reset;
134
135 // Accessors
137 MFloat observerCoordinates(const MInt id) const;
138 MFloat observerCoordinates(const MInt id, const MInt component) const;
139
140 MFloat& variables(const MInt id, const MInt var);
141 MFloat& variables(const MInt id) { return variables(id, 0); };
142
143 MFloat& variables(const MInt id, const MInt var, const MInt sample);
144 MFloat variables(const MInt id, const MInt var, const MInt sample) const;
145
146 MFloat& complexVariables(const MInt id, const MInt var);
147 MFloat& complexVariables(const MInt id) { return complexVariables(id, 0); };
148
149 MFloat& complexVariables(const MInt id, const MInt var, const MInt sample, const MInt component);
150 MFloat complexVariables(const MInt id, const MInt var, const MInt sample, const MInt component) const;
151
152 // Auxiliary methods
153
155 MInt noVars() { return m_noVars; }
157 void setNoVars(const MInt noVars_) {
158 ENSURE_CONDITION(noVars_ > 0 && noVars_ <= s_maxNoVars, "Invalid number of variables.");
159 m_noVars = noVars_;
160 };
161
165 void setNoComplexVars(const MInt noComplexVars_) {
166 ENSURE_CONDITION(noComplexVars_ > 0 && noComplexVars_ <= s_maxNoComplexVars,
167 "Invalid number of complex variables.");
168 m_noComplexVars = noComplexVars_;
169 };
170
174 void setNoSamples(const MInt noSamples_) {
175 ENSURE_CONDITION(noSamples_ > 0 && noSamples_ <= s_maxNoSamples, "Invalid number of samples.");
176 m_noSamples = noSamples_;
177 };
178
179 private:
180 // Methods required by base class for CRTP
181 void reset();
182 void invalidate(const MInt begin, const MInt end);
183 template <class Functor, class T>
184 void rawCopyGeneric(Functor&& c, const T& source, const MInt begin, const MInt end, const MInt destination);
185
186 private:
187 // Member variables
188
189 // Number of (local) surface elements for each surface
190 /* std::vector<MInt> m_noSurfaceElements{}; */
191
192 // Number of variables
194
195 // Number of complex variables
197
198 // Number of samples
200
201 // Data containers
205
207 static constexpr MInt s_maxNoVars = 10; // TODO labels:ACA
209 static constexpr MInt s_maxNoComplexVars = 5;
211 static constexpr MInt s_maxNoSamples = 1048576; // 2^20
212};
213
214
216template <MInt nDim>
218 const MInt varSize = noVars() * noSamples();
219 const MInt complexVarSize = 2 * noComplexVars() * noSamples();
220
221 resetStorage(nDim, m_observerCoordinates);
222 resetStorage(varSize, m_variables);
223 resetStorage(complexVarSize, m_complexVariables);
224}
225
226
228template <MInt nDim>
230// Prevent accidental compilation without support for SoA layout
231#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
232#error Missing implementation for structure-of-arrays memory layout.
233#endif
234 ENSURE_VALID_ID_ACCESSOR(id);
235 return m_observerCoordinates[id * nDim];
236}
238template <MInt nDim>
240// Prevent accidental compilation without support for SoA layout
241#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
242#error Missing implementation for structure-of-arrays memory layout.
243#endif
244 ENSURE_VALID_ID_ACCESSOR(id);
245 return m_observerCoordinates[id * nDim];
246}
248template <MInt nDim>
250// Prevent accidental compilation without support for SoA layout
251#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
252#error Missing implementation for structure-of-arrays memory layout.
253#endif
254 ENSURE_VALID_ID_ACCESSOR(id);
255 return m_observerCoordinates[id * nDim + component];
256}
257
258
260template <MInt nDim>
262// Prevent accidental compilation without support for SoA layout
263#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
264#error Missing implementation for structure-of-arrays memory layout.
265#endif
266 ENSURE_VALID_ID_ACCESSOR(id);
267 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
268 return m_variables[id * noVars() * noSamples() + var * noSamples()];
269}
270
271
275template <MInt nDim>
276MFloat& ObserverDataCollector<nDim>::variables(const MInt id, const MInt var, const MInt sample) {
277// Prevent accidental compilation without support for SoA layout
278#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
279#error Missing implementation for structure-of-arrays memory layout.
280#endif
281 ENSURE_VALID_ID_ACCESSOR(id);
282 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
283 ENSURE_VALID_SAMPLE_ID_ACCESSOR(sample);
284 return m_variables[id * noVars() * noSamples() + var * noSamples() + sample];
285}
287template <MInt nDim>
288MFloat ObserverDataCollector<nDim>::variables(const MInt id, const MInt var, const MInt sample) const {
289// Prevent accidental compilation without support for SoA layout
290#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
291#error Missing implementation for structure-of-arrays memory layout.
292#endif
293 ENSURE_VALID_ID_ACCESSOR(id);
294 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
295 ENSURE_VALID_SAMPLE_ID_ACCESSOR(sample);
296 return m_variables[id * noVars() * noSamples() + var * noSamples() + sample];
297}
298
299
301template <MInt nDim>
303// Prevent accidental compilation without support for SoA layout
304#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
305#error Missing implementation for structure-of-arrays memory layout.
306#endif
307 ENSURE_VALID_ID_ACCESSOR(id);
308 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
309 return m_complexVariables[id * 2 * noComplexVars() * noSamples() + var * 2 * noSamples()];
310}
311
312
316template <MInt nDim>
318 const MInt component) {
319// Prevent accidental compilation without support for SoA layout
320#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
321#error Missing implementation for structure-of-arrays memory layout.
322#endif
323 ENSURE_VALID_ID_ACCESSOR(id);
324 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
325 ENSURE_VALID_SAMPLE_ID_ACCESSOR(sample);
326 return m_complexVariables[id * 2 * noComplexVars() * noSamples() + var * 2 * noSamples() + 2 * sample + component];
327}
329template <MInt nDim>
331 const MInt component) const {
332// Prevent accidental compilation without support for SoA layout
333#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
334#error Missing implementation for structure-of-arrays memory layout.
335#endif
336 ENSURE_VALID_ID_ACCESSOR(id);
337 ENSURE_VALID_VARIABLE_ID_ACCESSOR(var);
338 ENSURE_VALID_SAMPLE_ID_ACCESSOR(sample);
339 return m_complexVariables[id * 2 * noComplexVars() * noSamples() + var * 2 * noSamples() + 2 * sample + component];
340}
341
342
344template <MInt nDim>
346// Prevent accidental compilation without support for SoA layout
347#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
348#error Missing implementation for structure-of-arrays memory layout.
349#endif
350
351 const MInt varSize = noVars() * noSamples();
352 const MInt complexVarSize = 2 * noComplexVars() * noSamples();
353
354 // Observer coordinates
355 fill_invalid(m_observerCoordinates, begin, end, nDim);
356
357 // Variables
358 fill_invalid(m_variables, begin, end, varSize);
359
360 // Complex variables
361 fill_invalid(m_complexVariables, begin, end, complexVarSize);
362}
363
364
366template <MInt nDim>
367template <class Functor, class T>
368void ObserverDataCollector<nDim>::rawCopyGeneric(Functor&& c, const T& source, const MInt begin, const MInt end,
369 const MInt destination) {
370// Prevent accidental compilation without support for SoA layout
371#ifdef ACACOLLECTOR_SOA_MEMORY_LAYOUT
372#error Missing implementation for structure-of-arrays memory layout.
373#endif
374
375 const MInt varSize = noVars() * noSamples();
376 const MInt complexVarSize = 2 * noComplexVars() * noSamples();
377
378 // Observer coordinates
379 copyData(source.m_observerCoordinates, m_observerCoordinates, c, begin, end, destination, nDim);
380
381 // Variables
382 copyData(source.m_variables, m_variables, c, begin, end, destination, varSize);
383
384 // Variables
385 copyData(source.m_complexVariables, m_complexVariables, c, begin, end, destination, complexVarSize);
386}
387
388
389} // namespace observer_collector
390} // namespace acoustic_analogy
391} // namespace maia
392
393
394// Undefine macros that should not be used outside this file
395#undef ACACOLLECTOR_SANITY_CHECKS_ACCESSORS
396#undef ENSURE_VALID_ID_ACCESSOR
397#undef ENSURE_VALID_VARIABLE_ID_ACCESSOR
398#undef ENSURE_VALID_SAMPLE_ID_ACCESSOR
399#undef ENSURE_CONDITION
400
401#endif // ifndef DGELEMENTCOLLECTOR_H_
static constexpr MInt s_maxNoVars
Maximum number of variables (in the time domain)
MFloat & complexVariables(const MInt id, const MInt var)
Accessor for complex variables.
static constexpr MInt s_maxNoSamples
Maximum number of samples.
typename maia::acoustic_analogy::observer_collector::Invalid< T > Invalid
void rawCopyGeneric(Functor &&c, const T &source, const MInt begin, const MInt end, const MInt destination)
Helper function for rawCopy(). Destination may refer to beginning or end of target range.
void setNoComplexVars(const MInt noComplexVars_)
Set number of complex variables.
void invalidate(const MInt begin, const MInt end)
Erase range of nodes such that they contain no sensible values anymore.
MInt noSamples()
Return number of samples (i.e. number of time steps)
MFloat & variables(const MInt id, const MInt var)
Accessor for variables (return a reference to the start of the given variable in memory).
constexpr ObserverDataCollector()=default
Default c'tor does nothing.
void reset()
Reset, re-create data structures with given capacity, and set size to zero.
static constexpr MInt s_maxNoComplexVars
Maximum number of complex variables (in the frequency domain)
void setNoSamples(const MInt noSamples_)
Set number of samples.
MFloat & observerCoordinates(const MInt id)
Accessor for surface element coordinates.
void copyData(const Container_ &source, Container_ &target, Functor &&f, const MInt begin, const MInt end, const MInt dest, const MInt solverSize=1)
Copy [begin, end) range with given solver size from source to dest position of target.
Definition: container.h:138
void fill_invalid(Container_ &c, const MInt begin, const MInt end, const MInt solverSize=1, const T value=Invalid< T >::value())
Definition: container.h:131
void resetStorage(const MInt n, Storage< T > &c)
Create new container with given size and replace original one.
Definition: container.h:420
void reset(const MInt capacity)
Reset tree, re-create data structures with given capacity, and set size to zero.
Definition: container.h:187
int32_t MInt
Definition: maiatypes.h:62
double MFloat
Definition: maiatypes.h:52
int64_t MLong
Definition: maiatypes.h:64
Namespace for auxiliary functions/classes.