Line data Source code
1 : // SPDX-FileCopyrightText: 2024 Daniel Abele <daniel.abele@dlr.de>
2 : //
3 : // SPDX-License-Identifier: BSD-3-Clause
4 :
5 : #include "issm-precice/config.hpp"
6 : #include <chrono>
7 : #include <optional>
8 : #include "mpi.h"
9 :
10 : namespace ipc
11 : {
12 :
13 : /**
14 : * Parts of the program to measure and report timings for.
15 : */
16 : enum class TimingScope
17 : {
18 : Total, //! Whole program execution time
19 : Setup, //! Loading of issm model
20 : Coupling, //! Coupling run without setup
21 : Initialize, //! Initialization before the coupling loop
22 : Read, //! Reading of data during the coupling loop
23 : Write, //! Writing of data during the coupling loop
24 : Advance, //! Advance coupling window, may block until other solver is ready
25 : Solve, //! Solver
26 :
27 : Count //! Last enum member, so enum can be used as index
28 : };
29 :
30 : /**
31 : * Add a timing to the global timing store.
32 : */
33 : void add_timing(TimingScope scope, std::chrono::system_clock::duration duration);
34 :
35 : /**
36 : * Print the global timing sums to the terminal.
37 : */
38 : void log_timings(MPI_Comm comm);
39 :
40 : /**
41 : * Timer that starts when created and stores it's timing when destroyed.
42 : * Timer starts when created. Can be restarted manually.
43 : * Timer stops when destroyed or when stopped manually.
44 : */
45 : class ScopedTimer
46 : {
47 : public:
48 : /**
49 : * Create ScopedTimer and start timing.
50 : */
51 36 : ScopedTimer(TimingScope scope) : m_scope(scope) { start(); }
52 :
53 : /**
54 : * Stop timer (if not stopped manually)
55 : */
56 36 : ~ScopedTimer()
57 : {
58 36 : stop();
59 36 : add_timing(m_scope, elapsed());
60 36 : }
61 :
62 : /**
63 : * (Re)start the timer.
64 : */
65 36 : void start()
66 : {
67 36 : m_start_time = std::chrono::system_clock::now();
68 36 : m_stop_time.reset();
69 36 : }
70 :
71 : /**
72 : * Stop the timer.
73 : */
74 36 : void stop()
75 : {
76 36 : if (!m_stop_time)
77 : {
78 36 : m_stop_time = std::chrono::system_clock::now();
79 : }
80 36 : }
81 :
82 : /**
83 : * Time elapsed between the most recent starts and stops.
84 : */
85 36 : std::chrono::system_clock::duration elapsed()
86 : {
87 72 : return m_stop_time.value_or(std::chrono::system_clock::now()) - m_start_time;
88 : }
89 :
90 : private:
91 : TimingScope m_scope;
92 : std::chrono::system_clock::time_point m_start_time;
93 : std::optional<std::chrono::system_clock::time_point> m_stop_time;
94 : };
95 : } // namespace ipc
|