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 24 : return count_s > 1.0 ? std::pair{ count_s, "s" } :
60 22 : 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
|