Triumvirate C++ API 0.5.0
Three-point clustering measurements in large-scale structure analyses.
Loading...
Searching...
No Matches
monitor.cpp
Go to the documentation of this file.
1// Copyright (C) [GPLv3 Licence]
2//
3// This file is part of the Triumvirate program. See the COPYRIGHT
4// and LICENCE files at the top-level directory of this distribution
5// for details of copyright and licensing.
6//
7// This program is free software: you can redistribute it and/or modify it
8// under the terms of the GNU General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15// See the GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program. If not, see <https://www.gnu.org/licenses/>.
19
27#include "monitor.hpp"
28
30#ifdef TRV_EXTCALL
31#define SHOW_CPPSTATE "C++"
32#else // !TRV_EXTCALL
33#define SHOW_CPPSTATE "\b"
34#endif // TRV_EXTCALL
36
37namespace trv {
38namespace sys {
39
40// ***********************************************************************
41// Program tracking
42// ***********************************************************************
43
44int currTask = 0;
45
46double gbytesMem = 0.;
47double gbytesMaxMem = 0.;
48
51float count_grid = 0.;
54float max_count_grid = 0.;
55
56int count_fft = 0;
57int count_ifft = 0;
58
61
62auto clockStart = std::chrono::steady_clock::now();
63
67
72
84
85std::string show_current_datetime() {
86 // Get current time.
87 auto now = std::chrono::system_clock::now();
88 auto timenow = std::chrono::system_clock::to_time_t(now);
89
90 // Format timestamp.
91 char buffer[64];
92 std::strftime(
93 buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", std::localtime(&timenow)
94 );
95
96 // Print timestamp to string.
97 std::string timestamp = std::string(buffer);
98
99 return timestamp;
100}
101
103 // Round time to an integer number of seconds.
105
106 // Calculate the hour, minute and second and convert to strings.
107 std::string h = std::to_string(time / 3600);
108 std::string m = std::to_string((time % 3600) / 60);
109 std::string s = std::to_string(time % 60);
110
111 // Format the strings.
112 std::string hh;
113 if (h.length() < 2) {
114 hh = std::string(2 - h.length(), '0') + h;
115 } else {
116 hh = h;
117 }
118
119 std::string mm = std::string(2 - m.length(), '0') + m;
120 std::string ss = std::string(2 - s.length(), '0') + s;
121
122 // Form the elapsed time string.
123 std::string elapsed_time = hh + ":" + mm + ":" + ss;
124
125 return elapsed_time;
126}
127
128std::string show_timestamp() {
129 // Calculate the elapsed time in seconds.
130 double elapsed_time = double(
131 std::chrono::duration_cast<std::chrono::seconds>(
132 std::chrono::steady_clock::now() - clockStart
133 ).count()
134 );
135
136 // Format the timestamp.
137 char timestamp_[128];
138 std::snprintf(
139 timestamp_, sizeof(timestamp_), "%s (+%s)",
141 );
142
143 std::string timestamp(timestamp_);
144
145 return timestamp;
146}
147
151
155
159
161 this->level_limit = level;
162}
163
164void Logger::emit(
165 std::string log_type, const char* fmt_string, std::va_list args
166) {
167 char log_mesg_buf[4096];
168 std::vsnprintf(log_mesg_buf, sizeof(log_mesg_buf), fmt_string, args);
169
170 std::printf(
171 "[%s %s %s] %s\n",
174 );
175}
176
178 if (entry_level >= this->level_limit) {
179 std::string log_type;
180 switch (entry_level) {
181 case LogLevel::NSET:
182 log_type = "\b";
183 break;
184 case LogLevel::DBUG:
185 log_type = "DBUG";
186 break;
187 case LogLevel::STAT:
188 log_type = "STAT";
189 break;
190 case LogLevel::INFO:
191 log_type = "INFO";
192 break;
193 case LogLevel::WARN:
194 log_type = "WARN";
195 break;
196 case LogLevel::ERRO:
197 log_type = "ERRO";
198 break;
199 default:
200 throw InvalidParameterError("Unsupported log level.");
201 }
202
203 std::va_list args;
205 Logger::emit(log_type, fmt_string, args);
206 va_end(args);
207 }
208}
209
210void Logger::log(int level_entry, const char* fmt_string, ...) {
211 if (level_entry >= this->level_limit) {
212 // CAVEAT: See @ref trv::sys::LogLevel.
213 level_entry /= 10;
214
215 std::string log_type;
216 switch (level_entry) {
217 case LogLevel::NSET:
218 log_type = "\b";
219 break;
220 case LogLevel::DBUG:
221 log_type = "DBUG";
222 break;
223 case LogLevel::STAT:
224 log_type = "STAT";
225 break;
226 case LogLevel::INFO:
227 log_type = "INFO";
228 break;
229 case LogLevel::WARN:
230 log_type = "WARN";
231 break;
232 case LogLevel::ERRO:
233 log_type = "ERRO";
234 break;
235 default:
236 throw InvalidParameterError("Unsupported log level.");
237 }
238
239 std::va_list args;
241 Logger::emit(log_type, fmt_string, args);
242 va_end(args);
243 }
244}
245
246void Logger::debug(const char* fmt_string, ...) {
247 if (this->level_limit <= LogLevel::DBUG) {
248 std::va_list args;
250 Logger::emit("DBUG", fmt_string, args);
251 va_end(args);
252 }
253}
254
255void Logger::stat(const char* fmt_string, ...) {
256 if (this->level_limit <= LogLevel::STAT) {
257 std::va_list args;
259 Logger::emit("STAT", fmt_string, args);
260 va_end(args);
261 }
262}
263
264void Logger::info(const char* fmt_string, ...) {
265 if (this->level_limit <= LogLevel::INFO) {
266 std::va_list args;
268 Logger::emit("INFO", fmt_string, args);
269 va_end(args);
270 }
271}
272
273void Logger::warn(const char* fmt_string, ...) {
274 if (this->level_limit <= LogLevel::WARN) {
275 std::va_list args;
277 Logger::emit("WARN", fmt_string, args);
278 va_end(args);
279 }
280}
281
282void Logger::error(const char* fmt_string, ...) {
283 if (this->level_limit <= LogLevel::ERRO) {
284 std::va_list args;
286 Logger::emit("ERRO", fmt_string, args);
287 va_end(args);
288 }
289}
290
291ProgressBar::ProgressBar(int task_count, std::string name) {
292 this->name = name;
293
294 if (task_count < 1) {
296 "Progress bar must count at least one task in total.\n"
297 );
298 }
299 this->task_count = task_count;
300
301 this->set_default_pcpt_nodes();
302}
303
305 if (width < 1) {
306 throw InvalidParameterError("Progress bar width must be at least 1.\n");
307 }
308 this->bar_width = width;
309}
310
311void ProgressBar::set_nodes(std::vector<float> nodes) {
312 if (nodes.size() < 1) {
314 "Progress bar nodes must have at least one element.\n"
315 );
316 }
317 this->nodes = nodes;
318}
319
320void ProgressBar::set_task_idx(int task_idx) {
323 "Progress bar task index must be non-negative and "
324 "within the total task count.\n"
325 );
326 }
327 this->task_idx = task_idx;
328
329 float progress = float(this->task_idx) / float(this->task_count);
330 this->set_progress(progress);
331}
332
333void ProgressBar::set_progress(float progress) {
336 "Progress bar progress must be within the range [0, 1].\n"
337 );
338 }
339 this->progress = progress;
340
341 this->next_node_idx = 0;
342 while (this->progress > this->nodes[this->next_node_idx]) {
343 this->next_node_idx += 1;
344 }
345}
346
348 this->task_idx = task_idx_now;
349 float progress_now = float(this->task_idx) / float(this->task_count);
350 this->update(progress_now);
351}
352
354 this->progress = progress_now;
355
356 if (this->progress <= 1.) {
357 if (this->progress >= this->nodes[this->next_node_idx]) {
358 int pos = this->bar_width * this->progress;
359
360 if (this->name != "") {
361 std::cout << this->name << " [";
362 } else {
363 std::cout << "[";
364 }
365
366 for (int ichar = 0; ichar < this->bar_width; ichar++) {
367 if (ichar < pos) {
368 std::cout << "=";
369 } else
370 if (ichar == pos) {
371 std::cout << ">";
372 } else {
373 std::cout << " ";
374 }
375 }
376 std::cout << "] " << int(progress * 100.) << " %\r";
377 std::cout.flush();
378
379 this->next_node_idx += 1;
380 }
381 } else {
382 throw InvalidDataError(
383 "Progress bar has already completed: progress %f > 1.\n", this->progress
384 );
385 }
386 if (this->progress == 1.) {std::cout << std::endl;}
387}
388
389void ProgressBar::set_default_pcpt_nodes() {
390 this->nodes.resize(101, 0.);
391 for (int pcpt = 0; pcpt <= 100; ++pcpt) {
392 this->nodes.push_back(float(pcpt) / 100.);
393 }
394}
395
396
397// ***********************************************************************
398// Program exceptions
399// ***********************************************************************
400
402 std::logic_error(
403 "Unimplemented error." // mandatory default error message
404 ) {
405 std::va_list args;
406
407 char err_mesg_buf[4096];
409 std::vsnprintf(err_mesg_buf, sizeof(err_mesg_buf), fmt_string, args);
410 va_end(args);
411
412 this->err_mesg = std::string(err_mesg_buf);
413}
414
416 return this->err_mesg.c_str();
417}
418
419IOError::IOError(const char* fmt_string, ...) : std::runtime_error(
420 "I/O error." // mandatory default error message
421) {
422 std::va_list args;
423
424 char err_mesg_buf[4096];
426 std::vsnprintf(err_mesg_buf, sizeof(err_mesg_buf), fmt_string, args);
427 va_end(args);
428
429 this->err_mesg = std::string(err_mesg_buf);
430}
431
432const char* IOError::what() const noexcept {return this->err_mesg.c_str();}
433
435std::invalid_argument(
436 "Invalid parameter error." // mandatory default error message
437) {
438 std::va_list args;
439
440 char err_mesg_buf[4096];
442 std::vsnprintf(err_mesg_buf, sizeof(err_mesg_buf), fmt_string, args);
443 va_end(args);
444
445 this->err_mesg = std::string(err_mesg_buf);
446}
447
449 return this->err_mesg.c_str();
450}
451
452InvalidDataError::InvalidDataError(const char* fmt_string, ...):
453std::runtime_error(
454 "Invalid data error." // mandatory default error message
455) {
456 std::va_list args;
457
458 char err_mesg_buf[4096];
460 std::vsnprintf(err_mesg_buf, sizeof(err_mesg_buf), fmt_string, args);
461 va_end(args);
462
463 this->err_mesg = std::string(err_mesg_buf);
464}
465
467 return this->err_mesg.c_str();
468}
469
470
471// ***********************************************************************
472// Program notices
473// ***********************************************************************
474
476 std::printf("\n");
477 std::printf(
478 " //\\ ___ __ __ ___ ___ \n"
479 " // \\ | |__) | | | |\\/| \\ / | |__) /\\ | |__ \n"
480 " // \\ | | \\ | \\__/ | | \\/ | | \\ /~~\\ | |___ \n"
481 " // \\ \n"
482 " //________\\ • Three-Point Clustering Measurements in LSS • \n"
483 " \n"
484 "(C) 2023 Mike S Wang & Naonori S Sugiyama [GPL-3.0] \n"
485 );
486 std::printf("\n");
487}
488
490 std::printf("LICENCE NOTICE >\n\n");
491 std::printf(
492 "This program is free software: you can redistribute it and/or modify \n"
493 "it under the terms of the GNU General Public License as published by \n"
494 "the Free Software Foundation, either version 3 of the License, or \n"
495 "(at your option) any later version. \n"
496 " \n"
497 "This program is distributed in the hope that it will be useful, but \n"
498 "WITHOUT ANY WARRANTY; without even the implied warranty of \n"
499 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU \n"
500 "General Public License for more details. \n"
501 " \n"
502 "You should have received a copy of the GNU General Public License \n"
503 "along with this program. If not, see <https://www.gnu.org/licenses/>.\n"
504 );
505 std::printf("\n");
506}
507
509 std::printf("RUNTIME INFORMATION >\n\n");
510
511#ifdef GSL_VERSION
512#define _GSL_VERSION GSL_VERSION
513#else // !GSL_VERSION
514#define _GSL_VERSION "unknown"
515#endif // GSL_VERSION
516 std::printf("GSL version: %s\n", _GSL_VERSION);
517
518 std::printf("FFTW version: %s\n", fftw_version);
519
520#ifdef TRV_USE_OMP
521#define _OMP_VERSION std::to_string(_OPENMP)
522#define _OMP_NTHREADS omp_get_max_threads()
523#else // !TRV_USE_OMP
524#define _OMP_VERSION std::string("unknown")
525#define _OMP_NTHREADS 1
526#endif // TRV_USE_OMP
527 std::printf("OpenMP version: %s\n", _OMP_VERSION.c_str());
528
529 std::printf("Thread number: %d\n", _OMP_NTHREADS);
530
531 std::printf("\n");
532}
533
535 if (endpoint == 0) {
536 // std::printf("%s\n", std::string(80, '>').c_str());
537 std::printf("PROGRAM LOG >\n\n");
538 } else
539 if (endpoint == 1) {
540 // std::printf("%s\n", std::string(80, '<').c_str());
541 // std::printf("\nTRIUMVIRATE LOG <\n");
542 } else {
544 "Invalid endpoint for log bars: %d.\n", endpoint
545 );
546 }
547}
548
549} // namespace trv::sys
550} // namespace trv
IOError(const char *fmt_string,...)
Construct an trv::sys::IOError exception.
Definition monitor.cpp:419
std::string err_mesg
error message
Definition monitor.hpp:410
virtual const char * what() const noexcept
Exception string representation.
Definition monitor.cpp:432
Exception raised when the data to be operated on are invalid.
Definition monitor.hpp:456
std::string err_mesg
error message
Definition monitor.hpp:458
virtual const char * what() const noexcept
Exception string representation.
Definition monitor.cpp:466
InvalidDataError(const char *fmt_string,...)
Construct an trv::sys::InvalidDataError exception.
Definition monitor.cpp:452
Exception raised when parameters are invalid.
Definition monitor.hpp:432
InvalidParameterError(const char *fmt_string,...)
Construct an trv::sys::InvalidParameterError exception.
Definition monitor.cpp:434
virtual const char * what() const noexcept
Exception string representation.
Definition monitor.cpp:448
std::string err_mesg
error message
Definition monitor.hpp:434
Logger with logging level differentiation.
Definition monitor.hpp:174
Logger(LogLevel level)
Construct the logger with the specified threshold level.
Definition monitor.cpp:148
void info(const char *fmt_string,...)
Emit a information-level message.
Definition monitor.cpp:264
void debug(const char *fmt_string,...)
Emit a debugging-level message.
Definition monitor.cpp:246
void error(const char *fmt_string,...)
Emit a warning-level message.
Definition monitor.cpp:282
void warn(const char *fmt_string,...)
Emit a warning-level message.
Definition monitor.cpp:273
void stat(const char *fmt_string,...)
Emit a status-level message.
Definition monitor.cpp:255
int level_limit
logger threshold level
Definition monitor.hpp:176
void log(LogLevel level_entry, const char *fmt_string,...)
Log a message at the specified level.
Definition monitor.cpp:177
void reset_level(LogLevel level)
Reset the logger threshold level.
Definition monitor.cpp:156
float progress
progress value in [0, 1] interval
Definition monitor.hpp:303
int task_count
total task count
Definition monitor.hpp:301
ProgressBar(int task_count, std::string name="")
Construct a progress bar.
Definition monitor.cpp:291
void set_task_idx(int task_idx)
Set current (or initial) task index.
Definition monitor.cpp:320
void set_nodes(std::vector< float > nodes)
Set progress bar width.
Definition monitor.cpp:311
int task_idx
task index
Definition monitor.hpp:302
void set_bar_width(int bar_width)
Set progress bar width.
Definition monitor.cpp:304
std::string name
progress bar name
Definition monitor.hpp:300
void update(int task_idx_now)
Update the progress bar.
Definition monitor.cpp:347
void set_progress(float progress)
Set current (or initial) progress value.
Definition monitor.cpp:333
virtual const char * what() const noexcept
Exception string representation.
Definition monitor.cpp:415
std::string err_mesg
error message
Definition monitor.hpp:386
UnimplementedError(const char *fmt_string,...)
Construct an trv::sys::UnimplementedError exception.
Definition monitor.cpp:401
#define _OMP_NTHREADS
#define _OMP_VERSION
#define _GSL_VERSION
Provide tracking of program resources and exceptions.
double gbytesMem
current memory usage in gibibytes
Definition monitor.cpp:46
std::string show_timestamp()
Return the timestamp string including the elapsed time.
Definition monitor.cpp:128
auto clockStart
program starting time
Definition monitor.cpp:62
double size_in_gb(long long num)
Return size in gibibytes.
Definition monitor.hpp:101
void update_maxmem()
Update the maximum memory usage estimate.
Definition monitor.cpp:68
void display_prog_licence()
Display program licence in stdout.
Definition monitor.cpp:489
bool fftw_wisdom_b_imported
wisdom import status for backward transform
Definition monitor.cpp:60
void display_prog_logo()
Display program logo in stdout.
Definition monitor.cpp:475
bool fftw_wisdom_f_imported
wisdom import status for forward transform
Definition monitor.cpp:59
float max_count_grid
maximum number of grids
Definition monitor.cpp:54
Logger logger
default logger (at NSET logging level)
int max_count_rgrid
maximum number of 3-d real grids
Definition monitor.cpp:52
float count_grid
number of grids
Definition monitor.cpp:51
int max_count_cgrid
maximum number of 3-d complex grids
Definition monitor.cpp:53
std::string show_current_datetime()
Return the current date-time string in 'YYYY-MM-DD HH:MM:SS' format.
Definition monitor.cpp:85
int currTask
current task
Definition monitor.cpp:44
void display_prog_logbars(int endpoint)
Display program log bars in stdout.
Definition monitor.cpp:534
LogLevel
Logging levels.
Definition monitor.hpp:160
@ NSET
0: unset
Definition monitor.hpp:162
@ INFO
30: info
Definition monitor.hpp:165
@ STAT
20: status
Definition monitor.hpp:164
@ WARN
40: warning
Definition monitor.hpp:166
@ ERRO
50: error/critical
Definition monitor.hpp:167
@ DBUG
10: debugging
Definition monitor.hpp:163
int count_fft
number of FFTs
Definition monitor.cpp:56
int count_cgrid
number of 3-d complex grids
Definition monitor.cpp:50
double gbytesMaxMem
maximum memory usage in gibibytes
Definition monitor.cpp:47
int count_rgrid
number of 3-d real grids
Definition monitor.cpp:49
int count_ifft
number of IFFTs
Definition monitor.cpp:57
void update_maxcntgrid()
Update the maximum 3-d grid counts.
Definition monitor.cpp:73
void display_prog_info()
Display program information in stdout.
Definition monitor.cpp:508
std::string show_elapsed_time(double duration_in_seconds)
Return the elapsed-time string in 'HH:MM:SS' format.
Definition monitor.cpp:102