Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
defaults.hh
Go to the documentation of this file.
1#ifndef UTOPIA_DATAIO_DATA_MANAGER_DEFAULTS_HH
2#define UTOPIA_DATAIO_DATA_MANAGER_DEFAULTS_HH
3
4#include <boost/hana/ext/std/tuple.hpp>
5#include <boost/hana/fold.hpp>
6#include <boost/hana/zip.hpp>
7#include <unordered_map>
8
9#include "../cfg_utils.hh"
10#include "write_task.hh"
11
12namespace Utopia
13{
14namespace DataIO
15{
16namespace Default
17{
18
28// =============================================================================
29// ================================ Writer Tasks ===============================
30// =============================================================================
31
34 std::function< std::shared_ptr< HDFGroup >(std::shared_ptr< HDFGroup >&&) >;
35
37template < typename Model >
39 std::function< void(std::shared_ptr< HDFDataset >&, Model&) >;
40
42template < typename Model >
43using DefaultBuilder = std::function< std::shared_ptr< HDFDataset >(
44 std::shared_ptr< HDFGroup >&, Model&) >;
45
47template < typename Model >
49 std::function< void(std::shared_ptr< HDFGroup >&, Model&) >;
50
52template < typename Model >
54 std::function< void(std::shared_ptr< HDFDataset >&, Model&) >;
55
64template < typename Model >
70
71// =============================================================================
72// ================================ Execution Process ==========================
73// =============================================================================
74
84{
94 template < class Datamanager, class Model >
95 void
96 operator()(Datamanager& dm, Model& m)
97 {
98 auto& tasks = dm.get_tasks();
99 for (auto& taskpair : tasks)
100 {
101 // TODO Instead of nullptr-check, check boolean?!
102 if (taskpair.second->base_group == nullptr)
103 {
104 taskpair.second->base_group =
105 taskpair.second->build_basegroup(m.get_hdfgrp());
106 }
107 }
108 for (auto& [name, trigger] : dm.get_triggers())
109 {
110 if ((*trigger)(m))
111 {
112 for (auto& taskname : dm.get_trigger_task_map()[name])
113 {
114 // using this ref variable avoids recomputing
115 // 'taskname''s hash all the time, should give minor
116 // performance improvement
117 auto& task = tasks[taskname];
118
119 task->active_dataset =
120 task->build_dataset(
121 task->base_group, m);
122
123 if (task->write_attribute_basegroup)
124 {
125 task->write_attribute_basegroup(
126 task->base_group, m);
127 }
128 }
129 }
130 }
131
132 for (auto& [name, decider] : dm.get_deciders())
133 {
134 if ((*decider)(m))
135 {
136 for (auto& taskname : dm.get_decider_task_map()[name])
137 {
138 auto& task = tasks[taskname];
139
140 task->write_data(task->active_dataset,
141 m);
142 if (task->write_attribute_active_dataset)
143 {
144 task->write_attribute_active_dataset(
145 task->active_dataset, m);
146 }
147 }
148 }
149 }
150 }
151};
152
153
154// =============================================================================
155// ================================ Decider ====================================
156// =============================================================================
157
165template<typename Model>
166struct Decider {
167
168 virtual bool operator()(Model&) = 0;
169 virtual void set_from_cfg(const Config&) = 0;
170
171 Decider() = default;
172 Decider(const Decider&) = default;
173 Decider(Decider&&) = default;
174 Decider&
175 operator=(const Decider&) = default;
176 Decider&
177 operator=(Decider&&) = default;
178 virtual ~Decider() = default;
179};
180
181
183
186template < typename Model >
187struct IntervalDecider : Decider< Model >
188{
189
192
194 std::list< std::array< std::size_t, 3 > > intervals;
195
196 virtual bool
197 operator()(Model& m) override
198 {
199 // Are at the end of the current interval; pop it, such that
200 // at next invocation the front is the new interval
201 if (intervals.size() != 0 and m.get_time() == intervals.front()[1])
202 {
203 intervals.pop_front();
204 }
205
206 if (intervals.size() != 0)
207 {
208 const auto [start, stop, step] = intervals.front();
209 // Check if within [start, end) interval
210 if ((m.get_time() >= start) and (m.get_time() < stop) and
211 ((m.get_time() - start) % step == 0))
212 {
213 return true;
214 }
215 }
216 return false;
217 }
223 virtual void
224 set_from_cfg(const Config& cfg) override
225 {
227 "intervals", cfg);
228 for (std::vector< std::size_t > tmp_interval : tmp)
229 {
230 if (tmp_interval.size() == 2)
231 {
232 tmp_interval.push_back(1);
233 }
234 else if (tmp_interval.size() != 3)
235 {
236 throw Utopia::KeyError("intervals", cfg,
237 fmt::format("Array of unexpected length {}! "
238 "Expected array of length 2 or 3 [start, stop, step] "
239 "with step optional (default 1).",
240 tmp_interval.size())
241 );
242 }
243
244 std::array< std::size_t, 3 > interval;
245 std::copy(tmp_interval.begin(), tmp_interval.end(),
246 interval.begin());
247 intervals.push_back(interval);
248 }
249 }
250
251 IntervalDecider() = default;
255 operator=(const IntervalDecider&) = default;
258 virtual ~IntervalDecider() = default;
259};
260
264template < typename Model >
265struct OnceDecider : Decider< Model >
266{
269 std::size_t time;
270
271 virtual bool
272 operator()(Model& m) override
273 {
274 return (m.get_time() == time);
275 }
276
282 virtual void
283 set_from_cfg(const Config& cfg) override
284 {
285 time = get_as< std::size_t >("time", cfg);
286 }
287
289 OnceDecider() = default;
290
291 OnceDecider(const OnceDecider&) = default;
294 operator=(const OnceDecider&) = default;
296 operator=(OnceDecider&&) = default;
297 virtual ~OnceDecider() = default;
298};
299
303template < typename Model >
304struct AlwaysDecider : Decider< Model >
305{
308
309 virtual bool
310 operator()(Model&) override
311 {
312 return true;
313 }
314
315 // dummy implementation of
316 virtual void
317 set_from_cfg(const Config&) override {}
318
319 AlwaysDecider() = default;
320
321 AlwaysDecider(const AlwaysDecider&) = default;
324 operator=(const AlwaysDecider&) = default;
327 virtual ~AlwaysDecider() = default;
328};
329
336template < typename Model, typename... Deciders >
337struct CompositeDecider : Decider< Model >
338{
341
343 std::tuple< Deciders... > held_deciders;
344
350 virtual bool
351 operator()(Model& m) override
352 {
353 return boost::hana::fold(
354 held_deciders, false, [&m](bool res, auto&& decider) {
355 return (res or decider(m));
356 });
357 }
358
366 virtual void
367 set_from_cfg(const Config& cfg) override
368 {
369 // BAD: User has to be smart about it, because it breaks
370 // if args are not the same order as Deciders...
371 std::array< const Config&, sizeof...(Deciders) > configs;
372
373 // make the args node for each decider into an array
374 auto conf_it = configs.begin();
375
376 for (auto it = cfg.begin(); it != cfg.end(); ++it, ++conf_it)
377 {
378 *conf_it = it->second["args"];
379 }
380
381 // then iterate over the zipped confs and deciders and built the
382 // deciders with their respective config
383 boost::hana::for_each(boost::hana::zip(configs, held_deciders),
384 [](auto&& conf_dcd_pair) {
385 auto&& [c, d] = conf_dcd_pair;
386 d.set_from_cfg(c);
387 });
388 }
389
390 CompositeDecider() = default;
393 operator=(const CompositeDecider&) = default;
396 virtual ~CompositeDecider() = default;
397};
398
399// =============================================================================
400// =========================== Default type maps ==============================
401// =============================================================================
402
403template < typename Model >
404using DefaultDecidermap = std::unordered_map<
405 std::string,
406 std::function< std::shared_ptr< Decider< Model > >() > >;
407
419template < typename Model >
421 { std::string("always"),
422 []() { return std::make_shared< AlwaysDecider< Model > >(); } },
423 { std::string("once"),
424 []() { return std::make_shared< OnceDecider< Model > >(); } },
425 { std::string("interval"),
426 []() { return std::make_shared< IntervalDecider< Model > >(); } }
427};
428
429// =============================================================================
430// ================================ Triggers
431// ===================================
432// =============================================================================
433
438template < typename Model >
440
441template < typename Model >
443
444template < typename Model >
446
447template < typename Model >
449
450template < typename Model, typename... Deciders >
452
453template < typename Model >
460template < typename Model >
462
467} // namespace Default
468} // namespace DataIO
469} // namespace Utopia
470
471#endif
For access to a dict-like structure with a bad key.
Definition exceptions.hh:67
Base class interface for Models using the CRT Pattern.
Definition model.hh:112
OutputIt copy(const Utopia::ExecPolicy policy, InputIt first, InputIt last, OutputIt d_first)
Copy the input range to a new range.
Definition parallel.hh:324
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition types.hh:71
static DefaultDecidermap< Model > default_deciders
Map that names the deciders supplied by default such that they can be addressed in a config file.
Definition defaults.hh:420
std::function< void(std::shared_ptr< HDFDataset > &, Model &) > DefaultAttributeWriterDataset
Type of the default attribute writer for datasets.
Definition defaults.hh:54
std::function< std::shared_ptr< HDFGroup >(std::shared_ptr< HDFGroup > &&) > DefaultBaseGroupBuilder
Type of the default group builder.
Definition defaults.hh:34
std::unordered_map< std::string, std::function< std::shared_ptr< Decider< Model > >() > > DefaultDecidermap
Definition defaults.hh:406
std::function< std::shared_ptr< HDFDataset >(std::shared_ptr< HDFGroup > &, Model &) > DefaultBuilder
Type of the default dataset builder.
Definition defaults.hh:44
std::function< void(std::shared_ptr< HDFGroup > &, Model &) > DefaultAttributeWriterGroup
Type of the default attribute writer for groups.
Definition defaults.hh:49
DefaultDecidermap< Model > DefaultTriggermap
Definition defaults.hh:454
std::function< void(std::shared_ptr< HDFDataset > &, Model &) > DefaultDataWriter
Type of the default data writer.
Definition defaults.hh:39
static DefaultTriggermap< Model > default_triggers
Default trigger factories. Equal to deciders because while the task they fullfill is different,...
Definition defaults.hh:461
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
Definition agent.hh:11
Decider which always returns true.
Definition defaults.hh:305
virtual void set_from_cfg(const Config &) override
Definition defaults.hh:317
virtual bool operator()(Model &) override
Definition defaults.hh:310
AlwaysDecider(AlwaysDecider &&)=default
AlwaysDecider & operator=(AlwaysDecider &&)=default
AlwaysDecider(const AlwaysDecider &)=default
AlwaysDecider & operator=(const AlwaysDecider &)=default
Combines a number of deciders; returns true if any of them is true.
Definition defaults.hh:338
std::tuple< Deciders... > held_deciders
Tuple of associated decider objects.
Definition defaults.hh:343
virtual void set_from_cfg(const Config &cfg) override
Set the decider up from a given config node.
Definition defaults.hh:367
CompositeDecider & operator=(const CompositeDecider &)=default
CompositeDecider & operator=(CompositeDecider &&)=default
virtual bool operator()(Model &m) override
Evaluates the composite deciders; returns true if any is true.
Definition defaults.hh:351
CompositeDecider(const CompositeDecider &)=default
Common interface for all deciders (and triggers, for that matter). Every decider/Trigger must inherit...
Definition defaults.hh:166
virtual void set_from_cfg(const Config &)=0
virtual bool operator()(Model &)=0
Decider & operator=(const Decider &)=default
Decider(const Decider &)=default
Decider & operator=(Decider &&)=default
Functor representing what is considered the most widely used execution process for writing data.
Definition defaults.hh:84
void operator()(Datamanager &dm, Model &m)
Call operator for executing the execution process.
Definition defaults.hh:96
A decider that returns true when within certain time intervals.
Definition defaults.hh:188
IntervalDecider(const IntervalDecider &)=default
IntervalDecider & operator=(IntervalDecider &&)=default
IntervalDecider & operator=(const IntervalDecider &)=default
virtual bool operator()(Model &m) override
Definition defaults.hh:197
IntervalDecider(IntervalDecider &&)=default
virtual void set_from_cfg(const Config &cfg) override
Set the decider up from a given config node.
Definition defaults.hh:224
std::list< std::array< std::size_t, 3 > > intervals
The sequence of intervals within to return true.
Definition defaults.hh:194
Decider which only returns true at a certain time.
Definition defaults.hh:266
OnceDecider & operator=(const OnceDecider &)=default
virtual void set_from_cfg(const Config &cfg) override
Set the decider up from a given config node.
Definition defaults.hh:283
std::size_t time
Definition defaults.hh:269
virtual bool operator()(Model &m) override
Definition defaults.hh:272
OnceDecider(const OnceDecider &)=default
OnceDecider(OnceDecider &&)=default
OnceDecider()=default
Construct a OnceDecider that evaluates to true at time zero.
OnceDecider & operator=(OnceDecider &&)=default
Encapsulate a task for writing data to a destination. Containes a callable 'writer' responisible for ...
Definition write_task.hh:50