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/timer.hpp" 6 : #include "issm-precice/logging.hpp" 7 : #include <vector> 8 : 9 : namespace ipc 10 : { 11 : struct Timing 12 : { 13 : uint64_t count{0}; 14 : std::chrono::system_clock::duration total_duration{0}; 15 : std::chrono::system_clock::duration minimum_duration{std::chrono::system_clock::duration::max()}; 16 : std::chrono::system_clock::duration maximum_duration{std::chrono::system_clock::duration::zero()}; 17 : }; 18 : 19 : static std::vector<Timing> g_timings = std::vector<Timing>(size_t(TimingScope::Count)); 20 : 21 36 : void add_timing(TimingScope scope, std::chrono::system_clock::duration duration) 22 : { 23 36 : auto& s = g_timings[size_t(scope)]; 24 36 : s.count += 1; 25 36 : s.total_duration += duration; 26 36 : s.minimum_duration = std::min(s.minimum_duration, duration); 27 36 : s.maximum_duration = std::max(s.maximum_duration, duration); 28 36 : } 29 : 30 8 : const char* to_string(TimingScope scope) 31 : { 32 8 : switch (scope) 33 : { 34 1 : case TimingScope::Total: 35 1 : return "Total"; 36 1 : case TimingScope::Advance: 37 1 : return "Advance"; 38 1 : case TimingScope::Coupling: 39 1 : return "Coupling"; 40 1 : case TimingScope::Initialize: 41 1 : return "Initialize"; 42 1 : case TimingScope::Read: 43 1 : return "Read"; 44 1 : case TimingScope::Write: 45 1 : return "Write"; 46 1 : case TimingScope::Setup: 47 1 : return "Setup"; 48 1 : case TimingScope::Solve: 49 1 : return "Solve"; 50 0 : default: 51 0 : throw std::logic_error("Invalid TimingScope"); 52 : } 53 : } 54 : 55 24 : std::pair<double, const char*> duration_count(std::chrono::system_clock::duration dur) { 56 24 : auto count_s = std::chrono::duration<double>(dur).count(); 57 24 : auto count_ms = std::chrono::duration<double, std::milli>(dur).count(); 58 24 : auto count_us = std::chrono::duration<double, std::micro>(dur).count(); 59 50 : return count_s > 1.0 ? std::pair{ count_s, "s" } : 60 54 : count_ms > 1.0 ? std::pair{ count_ms, "ms" } : 61 48 : std::pair{ count_us, "us" }; 62 : } 63 : 64 1 : void log_timings(MPI_Comm comm) 65 : { 66 1 : IPC_LOG_INFO_0(comm, "{:<10} {:>10} {:>10} {:>10} {:>10} {:>10}", "Scope", "Count", "Total", "Avg", "Min", "Max"); 67 9 : for (size_t i = 0; i < size_t(TimingScope::Count); ++i) 68 : { 69 8 : auto scope = TimingScope(i); 70 8 : auto timings = g_timings[i]; 71 8 : auto [total, total_unit] = duration_count(timings.total_duration); 72 8 : auto avg = timings.count > 0 ? total / timings.count : 0.0; 73 8 : auto [max, max_unit] = duration_count(timings.maximum_duration); 74 8 : auto [min, min_unit] = duration_count(timings.minimum_duration); 75 8 : IPC_LOG_INFO_0( 76 : comm, 77 : "{:<10s} {:>10d} {:>8.2f}{:2s} {:>8.2f}{:2s} {:>8.2f}{:2s} {:>8.2f}{:2s}", 78 : to_string(scope), 79 : timings.count, 80 : total, total_unit, 81 : avg, total_unit, 82 : min, min_unit, 83 : max, max_unit); 84 : } 85 1 : } 86 : } // namespace ipc