OpenLB 1.8.1
Loading...
Searching...
No Matches
data.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2022 Adrian Kummerlaender
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef CORE_DATA_H
25#define CORE_DATA_H
26
27#include "platform/platform.h"
28
29#include "fieldArrayD.h"
30#include "fieldParametersD.h"
32
33#include <optional>
34
35namespace olb {
36
37template <typename T, Platform PLATFORM> class ConcreteBlockMask;
38template <typename T, typename DESCRIPTOR> class BlockLattice;
39template <typename T, typename DESCRIPTOR> class BlockD;
40template <typename T, typename DESCRIPTOR> class Cell;
41
44
46
49template <typename FIELD>
50struct Array final : public field_type_of_field_array_tag {
51 using field_t = FIELD;
52
53 template <typename T, typename DESCRIPTOR, Platform PLATFORM>
55};
56
58
61template <typename OPERATOR>
63 template <typename T, typename DESCRIPTOR, Platform PLATFORM>
65};
66
68
71template <typename DYNAMICS>
73 template <typename T, typename DESCRIPTOR, Platform PLATFORM>
75};
76
77namespace fields {
78
80template <typename FIELD>
81constexpr bool isArray() {
82 return std::is_base_of_v<field_type_of_field_array_tag, FIELD>;
83}
84
85}
86
88
94template<typename T, typename DESCRIPTOR>
96private:
98 const std::string _name;
99
101 std::optional<unsigned> _dim = std::nullopt;
102
104 std::function<void(BlockLattice<T,DESCRIPTOR>&)> _allocateInLattice;
106 std::function<void(BlockD<T,DESCRIPTOR>&)> _allocateInBlockD;
107
108 std::function<void(Cell<Expr,DESCRIPTOR>&, std::vector<Expr>&)> _setPlaceholderExpr;
109 std::function<std::vector<Expr>(Cell<Expr,DESCRIPTOR>&)> _getPlaceholderExpr;
110
111public:
112 template <typename FIELD_TYPE>
114 _name{fields::name<FIELD_TYPE>()},
115 _allocateInLattice([](BlockLattice<T,DESCRIPTOR>& block) {
117 block.template getData<FIELD_TYPE>();
118 }
119 }),
120 _allocateInBlockD([](BlockD<T,DESCRIPTOR>& block) {
121 block.template getData<FIELD_TYPE>();
122 }),
123 _setPlaceholderExpr([](Cell<Expr,DESCRIPTOR>& cell, std::vector<Expr>& expr) {
124 if constexpr (concepts::LatticeDescriptor<DESCRIPTOR>) {
125 if constexpr (fields::isArray<FIELD_TYPE>()) {
126 if constexpr (std::is_same_v<Expr, typename FieldD<Expr,DESCRIPTOR,typename FIELD_TYPE::field_t>::value_t>) {
128 for (unsigned iD=0; iD < placeholder.d; ++iD) {
129 placeholder[iD] = expr[iD];
130 }
131 cell.template setField<typename FIELD_TYPE::field_t>(placeholder);
132 } else {
133 throw std::runtime_error("Can not set placeholder for non-T types");
134 }
135 } else {
136 throw std::runtime_error("Can not set placeholder for non-FieldArray types");
137 }
138 }
139 }),
140 _getPlaceholderExpr([](Cell<Expr,DESCRIPTOR>& cell) {
141 std::vector<Expr> expressions;
142 if constexpr (concepts::LatticeDescriptor<DESCRIPTOR>) {
143 if constexpr (fields::isArray<FIELD_TYPE>()) {
144 if constexpr (std::is_same_v<Expr, typename FieldD<Expr,DESCRIPTOR,typename FIELD_TYPE::field_t>::value_t>) {
146 placeholder = cell.template getFieldPointer<typename FIELD_TYPE::field_t>();
147 for (unsigned iD=0; iD < placeholder.d; ++iD) {
148 expressions.push_back(placeholder[iD]);
149 }
150 } else {
151 throw std::runtime_error("Can not get placeholder for non-T types");
152 }
153 } else {
154 throw std::runtime_error("Can not get placeholder for non-FieldArray types");
155 }
156 }
157 return expressions;
158 })
159 {
160 if constexpr (fields::isArray<FIELD_TYPE>()) {
161 _dim = std::optional<unsigned>{DESCRIPTOR::template size<typename FIELD_TYPE::field_t>()};
162 }
163 }
164
165 std::string name() const {
166 return _name;
167 }
168
169 std::optional<unsigned> dimension() const {
170 return _dim;
171 }
172
174 _allocateInLattice(block);
175 }
176
178 _allocateInBlockD(block);
179 }
180
181 void setPlaceholderExpression(Cell<Expr,DESCRIPTOR>& cell, std::vector<Expr>& expr) {
182 _setPlaceholderExpr(cell, expr);
183 }
184
186 return _getPlaceholderExpr(cell);
187 }
188
190 return name() < rhs.name();
191 }
192
193};
194
196
199template<typename T, typename DESCRIPTOR, Platform PLATFORM>
201private:
202 const std::string _name;
203 const FieldTypePromise<T,DESCRIPTOR> _promise;
204
205 std::unique_ptr<Serializable> _data;
206 std::function<void(ProcessingContext)> _setProcessingContext;
207
208public:
209 template<typename FIELD_TYPE, typename... ARGS>
211 _name(fields::name<FIELD_TYPE>()),
212 _promise(id),
213 _data(new typename FIELD_TYPE::template type<T,DESCRIPTOR,PLATFORM>(
214 std::forward<decltype(args)>(args)...)),
215 _setProcessingContext([&](ProcessingContext context) {
216 static_cast<typename FIELD_TYPE::template type<T,DESCRIPTOR,PLATFORM>*>(_data.get())->setProcessingContext(context);
217 })
218 { }
219
220 std::string getName() const {
221 return _name;
222 }
223
225 return _promise;
226 }
227
228 template<typename FIELD_TYPE>
229 const auto* as() const {
230 return static_cast<const typename FIELD_TYPE::template type<T,DESCRIPTOR,PLATFORM>*>(_data.get());
231 }
232 template<typename FIELD_TYPE>
233 auto* as() {
234 return static_cast<typename FIELD_TYPE::template type<T,DESCRIPTOR,PLATFORM>*>(_data.get());
235 }
236
238 return _data.get();
239 }
240
241 template<typename TYPE>
242 std::optional<TYPE*> tryAs() {
243 if (TYPE* ptr = dynamic_cast<TYPE*>(_data.get())) {
244 return std::optional<TYPE*>(ptr);
245 } else {
246 return std::nullopt;
247 }
248 }
249
251 _setProcessingContext(context);
252 }
253
254};
255
257
260template<typename T, typename DESCRIPTOR, Platform PLATFORM>
262private:
264
265public:
267
270 template <typename FIELD_TYPE>
271 bool provides() const {
272 return _index.template provides<FIELD_TYPE>();
273 }
274
276
279 template <typename FIELD_TYPE>
281 return _index.template get<FIELD_TYPE>();
282 }
284
287 template <typename FIELD_TYPE>
289 return _index.template get<FIELD_TYPE>();
290 }
291
293 template <typename FIELD_TYPE>
295 _index.template set<FIELD_TYPE>(fieldType);
296 }
297
298};
299
300
301template<typename T, typename DESCRIPTOR> class Data;
302template<typename T, typename DESCRIPTOR, Platform PLATFORM> class ConcreteData;
303
305template<typename T, typename DESCRIPTOR>
307
308using value_t = T;
309
311
312template <Platform PLATFORM>
314
315};
316
318template<typename T, typename DESCRIPTOR>
319class Data : public Serializable {
320protected:
322
324 template<typename F>
325 auto dispatch(F&& f) const {
327 _platform,
328 this,
329 f);
330 }
331 template<typename F>
332 auto dispatch(F&& f) {
334 _platform,
335 this,
336 f);
337 }
338
339public:
340 Data(Platform platform):
341 _platform{platform}
342 { }
343 virtual ~Data() = default;
344
346
351
354 return _platform;
355 }
356
358 template<typename FIELD_TYPE>
359 bool provides() {
360 return dispatch([&](const auto* data) -> bool {
361 return data->template provides<FIELD_TYPE>();
362 });
363 }
364
366
369 template <typename FIELD_TYPE, typename... ARGS>
370 auto& allocate(ARGS&&... args) {
371 return *dispatch([&](auto* data) {
372 return &(data->template allocate<FIELD_TYPE>(std::forward<ARGS&&>(args)...).asAbstract());
373 });
374 }
375
377 template <typename FIELD_TYPE>
378 const auto& get() const {
379 return *dispatch([&](const auto* data) {
380 return &(data->template get<FIELD_TYPE>().asAbstract());
381 });
382 }
384 template <typename FIELD_TYPE>
385 auto& get() {
386 return *dispatch([&](auto* data) {
387 return &(data->template get<FIELD_TYPE>().asAbstract());
388 });
389 }
390
391 virtual void resize(std::size_t newSize) = 0;
392
393 template <typename OPERATOR>
394 void apply() {
395 dispatch([&](auto* data) {
396 data->template apply<OPERATOR>();
397 });
398 }
399
401
406 template <typename FIELD_TYPE>
407 void setSerialization(bool active) {
408 dispatch([&](auto* data) {
409 data->template setSerialization<FIELD_TYPE>(active);
410 });
411 }
412
413};
414
416
423template<typename T, typename DESCRIPTOR, Platform PLATFORM>
424class ConcreteData final : public Data<T,DESCRIPTOR> {
425private:
427 std::map<std::type_index, std::unique_ptr<AnyFieldTypeD<T,DESCRIPTOR,PLATFORM>>> _map;
431 std::map<std::string, Serializable*> _serializationNames;
432
433public:
436 Data<T,DESCRIPTOR>(PLATFORM)
437 { }
438
440 ConcreteData(std::size_t size):
441 Data<T,DESCRIPTOR>(PLATFORM)
442 {
443 DESCRIPTOR::fields_t::for_each([&](auto id) {
444 using field = typename decltype(id)::type;
445 using field_type = Array<field>;
448 });
449 }
450
452 template <typename FIELD_TYPE>
453 bool provides() const {
454 return _registry.template provides<FIELD_TYPE>();
455 }
456
458 template <typename FIELD_TYPE, typename... ARGS>
459 auto& allocate(ARGS&&... args) {
460 _map[typeid(FIELD_TYPE)] = std::make_unique<AnyFieldTypeD<T,DESCRIPTOR,PLATFORM>>(
461 meta::id<FIELD_TYPE>(), std::forward<decltype(args)>(args)...);
462
463 AnyFieldTypeD<T,DESCRIPTOR,PLATFORM>* newField = _map[typeid(FIELD_TYPE)].get();
464 _registry.template track<FIELD_TYPE>(newField);
465 return *newField->template as<FIELD_TYPE>();
466 }
467
469 template <typename FIELD_TYPE>
470 const auto& get() const {
471 return *_registry.template get<FIELD_TYPE>()->template as<FIELD_TYPE>();
472 }
474 template <typename FIELD_TYPE>
475 auto& get() {
476 return *_registry.template get<FIELD_TYPE>()->template as<FIELD_TYPE>();
477 }
478
480 template <typename F>
481 void forEach(F f) {
482 for (auto& [_, field] : _map) {
483 f(*field);
484 }
485 }
486
488
491 template <typename TYPE, typename F>
492 void forEachCastable(F f) {
494 if (auto casted = any.template tryAs<TYPE>()) {
495 f(*casted);
496 }
497 });
498 }
499
500 void resize(std::size_t newSize) override {
501 forEachCastable<ColumnVectorBase>([&](auto columnVector) {
502 columnVector->resize(newSize);
503 });
504 }
505
509 any.setProcessingContext(context);
510 });
511 }
512
514 auto& getRegistry() {
515 return _registry;
516 }
517
519 template <typename FIELD_TYPE>
520 void setSerialization(bool active) {
521 if (active) {
522 _serializationNames[meta::name<FIELD_TYPE>()] = _registry.template get<FIELD_TYPE>()->asSerializable();
523 } else {
524 _serializationNames.erase(meta::name<FIELD_TYPE>());
525 }
526 }
527
529 std::size_t getNblock() const override;
531 std::size_t getSerializableSize() const override;
533 bool* getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode) override;
534
535};
536
538template <typename T, typename DESCRIPTOR, typename... ARGS>
539std::unique_ptr<Data<T,DESCRIPTOR>> makeSharedData(
540 LoadBalancer<T>& loadBalancer, ARGS&&... args)
541{
542 #if defined(PLATFORM_GPU_CUDA)
543 if (loadBalancer.isLocal(Platform::GPU_CUDA)) {
544 return std::unique_ptr<Data<T,DESCRIPTOR>>(
545 new ConcreteData<T,DESCRIPTOR,Platform::GPU_CUDA>(std::forward<ARGS&&>(args)...));
546 } else {
547 return std::unique_ptr<Data<T,DESCRIPTOR>>(
548 new ConcreteData<T,DESCRIPTOR,Platform::CPU_SISD>(std::forward<ARGS&&>(args)...));
549 }
550 #else
551 return std::unique_ptr<Data<T,DESCRIPTOR>>(
552 new ConcreteData<T,DESCRIPTOR,Platform::CPU_SISD>(std::forward<ARGS&&>(args)...));
553 #endif
554}
555
556}
557
558#endif
Container for arbitrary data instances.
Definition data.h:200
FieldTypePromise< T, DESCRIPTOR > getPromise() const
Definition data.h:224
std::string getName() const
Definition data.h:220
std::optional< TYPE * > tryAs()
Definition data.h:242
const auto * as() const
Definition data.h:229
void setProcessingContext(ProcessingContext context)
Definition data.h:250
AnyFieldTypeD(meta::id< FIELD_TYPE > id, ARGS &&... args)
Definition data.h:210
auto * as()
Definition data.h:233
Serializable * asSerializable()
Definition data.h:237
Storage of any FIELD_TYPE data on PLATFORM.
Definition data.h:424
ConcreteData(std::size_t size)
Construct Array<FIELD> of size for each FIELD in DESCRIPTOR and mark for serialization.
Definition data.h:440
void resize(std::size_t newSize) override
Definition data.h:500
auto & allocate(ARGS &&... args)
Allocate and return FIELD_TYPE data.
Definition data.h:459
std::size_t getSerializableSize() const override
Binary size for the serializer.
Definition data.hh:42
auto & get()
Return reference to data of FIELD_TYPE.
Definition data.h:475
void setProcessingContext(ProcessingContext context) override
Set processing context of all managed fields.
Definition data.h:507
std::size_t getNblock() const override
Number of data blocks for the serializable interface.
Definition data.hh:32
auto & getRegistry()
Expose FieldTypeRegistry for device-support.
Definition data.h:514
void forEach(F f)
Call f for each managed AnyFieldType.
Definition data.h:481
ConcreteData()
Construct empty.
Definition data.h:435
bool * getBlock(std::size_t iBlock, std::size_t &sizeBlock, bool loadingMode) override
Return a pointer to the memory of the current block and its size for the serializable interface.
Definition data.hh:52
void forEachCastable(F f)
Call f for each managed AnyFieldType of TYPE.
Definition data.h:492
void setSerialization(bool active)
Sets FIELD_TYPE serialization state to active.
Definition data.h:520
bool provides() const
Returns true iff FIELD_TYPE is allocated and can be accessed.
Definition data.h:453
const auto & get() const
Return reference to data of FIELD_TYPE.
Definition data.h:470
Platform-indepentent interface to ConcreteData.
Definition data.h:319
virtual ~Data()=default
auto & get()
Return reference to data of FIELD_TYPE.
Definition data.h:385
auto dispatch(F &&f)
Definition data.h:332
auto dispatch(F &&f) const
Calls f on concrete implementation of the Data interface.
Definition data.h:325
virtual void resize(std::size_t newSize)=0
virtual void setProcessingContext(ProcessingContext)=0
Set processing context.
const Platform _platform
Definition data.h:321
void apply()
Definition data.h:394
Data(Platform platform)
Definition data.h:340
Platform getPlatform() const
Return platform of concrete implementation.
Definition data.h:353
bool provides()
Return whether FIELD_TYPE is available / has been allocated.
Definition data.h:359
const auto & get() const
Return reference to data of FIELD_TYPE.
Definition data.h:378
auto & allocate(ARGS &&... args)
Allocate and return FIELD_TYPE data.
Definition data.h:370
void setSerialization(bool active)
Sets FIELD_TYPE serialization state to active.
Definition data.h:407
SoA storage for instances of a single FIELD.
Helper for conveying the ability for operations on FIELD_TYPE.
Definition data.h:95
FieldTypePromise(meta::id< FIELD_TYPE >)
Definition data.h:113
std::string name() const
Definition data.h:165
void setPlaceholderExpression(Cell< Expr, DESCRIPTOR > &cell, std::vector< Expr > &expr)
Definition data.h:181
std::optional< unsigned > dimension() const
Definition data.h:169
void ensureAvailabilityIn(BlockLattice< T, DESCRIPTOR > &block)
Definition data.h:173
bool operator<(const FieldTypePromise< T, DESCRIPTOR > &rhs) const
Definition data.h:189
std::vector< Expr > getPlaceholderExpression(Cell< Expr, DESCRIPTOR > &cell)
Definition data.h:185
void ensureAvailabilityIn(BlockD< T, DESCRIPTOR > &block)
Definition data.h:177
Efficient indexing of dynamically allocated data fields.
Definition data.h:261
const AnyFieldTypeD< T, DESCRIPTOR, PLATFORM > * get() const
Return read-only pointer to FIELD_TYPE data.
Definition data.h:280
void track(AnyFieldTypeD< T, DESCRIPTOR, PLATFORM > *fieldType)
Track newly allocated FIELD_TYPE.
Definition data.h:294
AnyFieldTypeD< T, DESCRIPTOR, PLATFORM > * get()
Return pointer to FIELD_TYPE data.
Definition data.h:288
bool provides() const
Returns true iff FIELD_TYPE is registered.
Definition data.h:271
Base class for all LoadBalancer.
Definition vtiWriter.h:42
bool isLocal(const int &glob) const
returns whether glob is on this process
Base class for serializable objects of constant size. For dynamic size use BufferSerializable.
Definition serializer.h:145
(Time) efficient mapping between TYPEs and VALUEs
Descriptor of DdQq lattice and associated constants.
Definition concepts.h:78
constexpr bool isArray()
Helper to determine if FIELD contains FieldArray.
Definition data.h:81
std::string name()
Returns distinct name on GCC, Clang and ICC but may return arbitrary garbage as per the standard.
Definition meta.h:100
Top level namespace for all of OpenLB.
auto callUsingConcretePlatform(Platform platform, typename CONCRETIZABLE::base_t *ptr, F f)
Dispatcher for concrete platform access.
Definition dispatch.h:41
ProcessingContext
OpenLB processing contexts.
Definition platform.h:54
Platform
OpenLB execution targets.
Definition platform.h:35
@ GPU_CUDA
Vector CPU (AVX2 / AVX-512 collision)
Vector< typename FIELD::template value_type< T >, DESCRIPTOR::template size< FIELD >() > FieldD
Vector storing a single field instance.
Definition vector.h:480
std::unique_ptr< Data< T, DESCRIPTOR > > makeSharedData(LoadBalancer< T > &loadBalancer, ARGS &&... args)
Constructs Data accessible on all locally used platforms.
Definition data.h:539
Describe FieldArray of a FIELD in Data.
Definition data.h:50
FIELD field_t
Definition data.h:51
Concrete storage of ParametersD in olb::Data.
Curried ConcreteData template for use in callUsingConcretePlatform.
Definition data.h:306
Describe mask of DYNAMICS in Data.
Definition data.h:72
Describe paramaters of OPERATOR in Data.
Definition data.h:62
Identity type to pass non-constructible types as value.
Definition meta.h:79