Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
monitor.hh
Go to the documentation of this file.
1#ifndef UTOPIA_DATAIO_MONITOR_HH
2#define UTOPIA_DATAIO_MONITOR_HH
3
4#include <chrono>
5#include <iostream>
6#include <utility>
7#include <vector>
8#include <yaml-cpp/yaml.h>
9
10#include "../core/string.hh"
11#include "cfg_utils.hh"
12
13
14namespace Utopia::DataIO
15{
16
39
47template < class F, class... Args >
49{
50 template < class U >
51 static auto
53 -> decltype((*p)(std::declval< Args >()...), void(), std::true_type());
54 template < class U >
55 static auto
56 test(...) -> decltype(std::false_type());
57
58 static constexpr bool value = decltype(test< F >(0))::value;
59};
60
63{
64 public:
65 // -- Data types uses throughout the monitor timer-- //
66
68 using Clock = std::chrono::high_resolution_clock;
69
71 using Time = std::chrono::high_resolution_clock::time_point;
72
74 using DurationType = std::chrono::duration< double >;
75
76 private:
77 // -- Member declaration -- //
80
83
86
87 public:
89
98 // Store the emit interval
100 // Set the starting time member
102 // Initialize _last_emit empty, setting it to 1.1.1970, 0:00, meaning
103 // that no emit has occurred yet.
104 _last_emit(){};
105
107
112 bool
114 {
115 // Calculate the time difference between now and the last emit
116 const DurationType duration = Clock::now() - _last_emit;
117
118 // If more time than the _emit_interval has passed, return true
119 return (duration > _emit_interval);
120 }
121
123 void
125 {
126 _last_emit = Clock::now();
127 }
128
130 template < class DurationT = DurationType >
131 const DurationT
133 {
134 return Clock::now() - _start_time;
135 }
136
138 double
143
145 const DurationType
147 {
148 return _emit_interval;
149 }
150};
151
153
159{
160 private:
162 using Timer = std::shared_ptr< MonitorTimer >;
163
164 // -- Members -------------------------------------------------------------
167
169 YAML::Node _entries;
170
173
175 std::size_t _emit_counter;
176
178 const std::string _emit_prefix;
179
181 const std::string _emit_suffix;
182
183 public:
185
193 const std::string emit_prefix = "!!map ",
194 const std::string emit_suffix = "")
195 :
196 // Create a new MonitorTimer object
198 // Create an empty MonitorEntries object for the data to be emitted
199 _entries(YAML::Node()),
200 // Initialially set the collect data flag to true
202 _emit_counter(0),
205 {};
206
208 void
210 {
211 if (not _emit_enabled) return;
212
213 // Calling recursive_setitem may remove the emitter style, requiring
214 // to reset it here each time. This will only set some flags in the
215 // to-be-created YAML::Emitter and has negligible performance impact.
216 _entries.SetStyle(YAML::EmitterStyle::Flow);
217
218 std::cout << _emit_prefix
219 << _entries
220 << _emit_suffix
221 << std::endl;
222
224 _timer->reset();
225 _emit_enabled = false;
226 }
227
229 void
231 {
232 if (_timer->time_has_come())
233 {
234 _emit_enabled = true;
235 }
236 }
237
239 /* This function can be used as a more performative way to checking whether
240 * it makes sense to collect monitor entries; it makes only sense to
241 * collect entries, if the emission will actually performed in the current
242 * time step.
243 */
244 bool
246 {
247 return _emit_enabled;
248 }
249
251
264 template < typename Value >
265 void
266 set_entry(const std::string& path,
267 const std::string& key,
268 const Value value)
269 {
271 recursive_setitem(_entries, path + "." + key, value, ".");
272 }
273
275
282 template < typename Time >
283 void
284 set_time_entries(const Time time, const Time time_max)
285 {
286 _entries["time"] = time;
287
288 // Add the progress indicator and the elapsed time
289 _entries["progress"] = float(time) / float(time_max);
290 }
291
293 Timer&
295 {
296 return _timer;
297 }
298
300 auto
302 {
303 return _timer->get_emit_interval();
304 }
305
307 auto
309 {
310 return _emit_counter;
311 }
312
314 YAML::Node&
316 {
317 return _entries;
318 }
319};
320
323{
324 private:
326
328 const std::string _name;
329
331 std::shared_ptr< MonitorManager > _mtr_mgr;
332
333 public:
335
340 Monitor(std::shared_ptr< MonitorManager > root_mtr_mgr)
341 :
342 _name(""),
344
346
354 Monitor(const std::string& name, const Monitor& parent_mtr)
355 :
356 _name(parent_mtr.get_name() + "." + name),
358
360
367 template < typename Func >
368 void
369 set_by_func(const std::string key, Func&& f)
370 {
371 _mtr_mgr->set_entry(_name, key, f());
372 }
373
375
383 template < typename Value >
384 void
385 set_by_value(const std::string key, Value const& v)
386 {
387 _mtr_mgr->set_entry(_name, key, v);
388 }
389
391
406 template < typename Arg >
407 void
408 set_entry(const std::string key, Arg arg)
409 {
410 if constexpr (is_callable< Arg >::value)
411 {
413 }
414 else
415 {
417 }
418 }
419
421 std::shared_ptr< MonitorManager >
423 {
424 return _mtr_mgr;
425 }
426
428 std::string
429 get_name() const
430 {
431 return _name;
432 }
433};
434
// end of group Monitor // end of group DataIO
437
438} // namespace Utopia::DataIO
439
440#endif // UTOPIA_DATAIO_MONITOR_HH
The Monitor monitors entries that are emitted if a given time has passed.
Definition monitor.hh:323
const std::string _name
The name of the monitor.
Definition monitor.hh:328
void set_by_value(const std::string key, Value const &v)
Provide a new entry to the monitor manager.
Definition monitor.hh:385
Monitor(const std::string &name, const Monitor &parent_mtr)
Construct a monitor object within a hierarchy.
Definition monitor.hh:354
std::shared_ptr< MonitorManager > _mtr_mgr
The monitor manager.
Definition monitor.hh:331
Monitor(std::shared_ptr< MonitorManager > root_mtr_mgr)
Constructs a root monitor object.
Definition monitor.hh:340
std::shared_ptr< MonitorManager > get_monitor_manager() const
Get a shared pointer to the MonitorManager.
Definition monitor.hh:422
void set_by_func(const std::string key, Func &&f)
Provide a new entry to the monitor manager.
Definition monitor.hh:369
void set_entry(const std::string key, Arg arg)
Provide a new entry to the monitor manager.
Definition monitor.hh:408
std::string get_name() const
Get the name of the monitor.
Definition monitor.hh:429
The MonitorManager manages the monitor entries and MonitorTimer.
Definition monitor.hh:159
void set_time_entries(const Time time, const Time time_max)
Set time- and progress-related top level entries.
Definition monitor.hh:284
void check_timer()
Checks with the timer whether the time to emit has come.
Definition monitor.hh:230
MonitorManager(const double emit_interval, const std::string emit_prefix="!!map ", const std::string emit_suffix="")
Constructor.
Definition monitor.hh:192
Timer _timer
The monitor timer.
Definition monitor.hh:166
std::shared_ptr< MonitorTimer > Timer
Type of the timer.
Definition monitor.hh:162
YAML::Node & get_entries()
Get the reference to the monitor entries object.
Definition monitor.hh:315
std::size_t _emit_counter
Counts the number of emit operations.
Definition monitor.hh:175
const std::string _emit_suffix
A suffix to the emitted string.
Definition monitor.hh:181
void set_entry(const std::string &path, const std::string &key, const Value value)
Set an entry in the tree of monitor entries.
Definition monitor.hh:266
auto get_emit_interval()
Return the emit interval.
Definition monitor.hh:301
bool emit_enabled() const
Returns true if the emission is enabled.
Definition monitor.hh:245
void emit_if_enabled()
Perform an emission of the data to the terminal, if the flag was set.
Definition monitor.hh:209
auto get_emit_counter()
Return the emit interval.
Definition monitor.hh:308
const std::string _emit_prefix
A prefix to the emitted string.
Definition monitor.hh:178
YAML::Node _entries
The monitor entries.
Definition monitor.hh:169
Timer & get_timer()
Get a shared pointer to the MonitorTimer object.
Definition monitor.hh:294
bool _emit_enabled
The flag that determines whether to collect data.
Definition monitor.hh:172
The MonitorTimer keeps track of the time when to emit monitor data.
Definition monitor.hh:63
const DurationType _emit_interval
The emit interval.
Definition monitor.hh:79
Time _last_emit
The time of the last emit.
Definition monitor.hh:85
const DurationT get_time_elapsed() const
Get the time elapsed since the start of this timer.
Definition monitor.hh:132
const DurationType get_emit_interval() const
Return the emit interval.
Definition monitor.hh:146
double get_time_elapsed_seconds() const
Get the time elapsed since start of this timer, converted to seconds.
Definition monitor.hh:139
bool time_has_come() const
Check for whether the time to emit has come or not.
Definition monitor.hh:113
std::chrono::high_resolution_clock::time_point Time
Data type for a time point.
Definition monitor.hh:71
const Time _start_time
The starting time of the timer.
Definition monitor.hh:82
void reset()
Reset the timer to the current time.
Definition monitor.hh:124
MonitorTimer(const double emit_interval)
Constructor.
Definition monitor.hh:97
std::chrono::duration< double > DurationType
Data type for the time unit.
Definition monitor.hh:74
std::chrono::high_resolution_clock Clock
Data type for the clock.
Definition monitor.hh:68
Check if a type T is callable, i.e., if it has.
Definition type_traits.hh:685
static constexpr bool value
Definition type_traits.hh:687
void recursive_setitem(Config &d, std::list< std::string > key_sequence, const T val)
Recursively sets an element in a configuration tree.
Definition cfg_utils.hh:422
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 types.hh:64
Definition parallel.hh:235
static auto test(...) -> decltype(std::false_type())
static auto test(U *p) -> decltype((*p)(std::declval< Args >()...), void(), std::true_type())