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