MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
timer.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#include "timer.h"
8#include "typetraits.h"
9
10#include <algorithm>
11
12#ifdef _OPENMP
13#include <omp.h>
14#endif
15
16using namespace std;
17//--------------------------------------------------------------------------------
18
20 static MTimers timers;
21 return timers;
22}
23
24vector<FunctionTiming> Profile::s_functionTimings;
25
26
28 if(approx(a.getDeltaCpuTime(), b.getDeltaCpuTime(), MFloatEps)) return (a.getInitCpuTime() < b.getInitCpuTime());
29 return (a.getDeltaCpuTime() < b.getDeltaCpuTime());
30}
31
33#ifdef _OPENMP
34 if(omp_get_max_threads() > 1) {
35 m_log << "Skipping profile output for OpenMP. FIXME: Tracer not thread-safe!" << std::endl;
36 return;
37 }
38#endif
39
40 const MFloat exitCpuTime = cpuTime();
41 const MFloat exitWallTime = wallTime();
42 const MFloat thresholdPercentage = 0.5;
43 stringstream sstream;
44 sstream << " CPU WALL FUNCTION >> profile: '" << m_name << "' <<";
45 const string header = sstream.str();
46 const MString dashes1(header.size(), '_');
47 const MString dashes2(header.size(), '-');
48 m_log << dashes1 << endl << header << endl << dashes2 << endl << endl;
49
50 MInt counter = 0;
51 MInt supCounter = 0;
52 // TODO labels:TIMERS add mode to compute statistics over all ranks
53 if(s_functionTimings.size() > 0) {
54 sort(s_functionTimings.begin(), s_functionTimings.end());
55 reverse(s_functionTimings.begin(), s_functionTimings.end());
56 for(vector<FunctionTiming>::size_type i = 0; i < s_functionTimings.size(); i++) {
57 if(s_functionTimings[i].getInitCpuTime() < m_initCpuTime) continue;
58 const MFloat relCpuTime =
59 100.0 * s_functionTimings[i].getDeltaCpuTime() / max(1e-15, (exitCpuTime - m_initCpuTime));
60 const MFloat relWallTime =
61 100.0 * s_functionTimings[i].getDeltaWallTime() / max(1e-15, (exitWallTime - m_initWallTime));
62 if(relCpuTime < thresholdPercentage) {
63 supCounter++;
64 continue;
65 }
66 char buffer[7];
67 sprintf(buffer, "%6.2f", relCpuTime);
68 char buffer2[7];
69 sprintf(buffer2, "%6.2f", relWallTime);
70 // TODO labels:TIMERS abbreviate function names/remove templates etc
71 m_log << buffer << "% " << buffer2 << "% " << s_functionTimings[i].getName() << endl;
72 counter++;
73 }
74 if(supCounter > 0) {
75 m_log << " ..... ..... (" << supCounter << " shorter timings with CPU<" << thresholdPercentage
76 << "% were suppressed)" << endl;
77 }
78 }
79 if(counter == 0) {
80 m_log << "No timings recorded for timer '" << m_name << "'." << endl;
81 }
82 m_log << dashes2 << endl;
83 m_log << "Total cpu time: " << printTime(exitCpuTime - m_initCpuTime) << endl;
84 m_log << "Total wall time: " << printTime(exitWallTime - m_initWallTime) << endl;
85 m_log << dashes1 << endl;
86}
87
89 MInt tId = -1;
90 if(s_functionTimings.size() > 0) {
91 for(vector<FunctionTiming>::size_type i = 0; i < s_functionTimings.size(); i++) {
92 if(s_functionTimings[i].getName() == name) {
93 tId = i;
94 break;
95 }
96 }
97 }
98 if(tId < 0) {
99 tId = static_cast<MInt>(s_functionTimings.size());
100 s_functionTimings.push_back(FunctionTiming(name));
101 }
102 ASSERT(tId > -1, "Non-existing timer");
103 return tId;
104}
105
107 stringstream time;
108 time.str("");
109 MFloat rem = secs;
110 if(rem > 86400.0) {
111 const MFloat div = floor(rem / 86400.0);
112 time << ((MInt)div) << " days, ";
113 rem -= div * 86400.0;
114 }
115 if(rem > 3600.0) {
116 const MFloat div = floor(rem / 3600.0);
117 time << ((MInt)div) << " hours, ";
118 rem -= div * 3600.0;
119 }
120 if(rem > 60.0) {
121 const MFloat div = floor(rem / 60.0);
122 time << ((MInt)div) << " mins, ";
123 rem -= div * 60.0;
124 }
125 time << rem << " secs";
126 const MString ret = time.str();
127 return ret;
128}
129
130
132 : m_initCpuTime(cpuTime()),
133 m_deltaCpuTime(0),
134 m_tmpCpuTime(0),
135 m_initWallTime(wallTime()),
136 m_deltaWallTime(0.0),
137 m_tmpWallTime(-1.0),
138 m_name(name) {}
139
141
149 m_name = t.m_name;
150 return *this;
151}
152
156}
157
161 m_tmpCpuTime = -1.0;
162 m_tmpWallTime = -1.0;
163}
164
165
171void logDuration_(const MFloat timeStart, const MString module, const MString comment, const MPI_Comm comm,
172 const MInt domainId, const MInt noDomains) {
173 const MFloat duration = wallTime() - timeStart;
174
175 std::vector<std::pair<MFloat, MString>> durations{};
176 durations.push_back(std::make_pair(duration, comment));
177 logDurations(durations, module, comm, domainId, noDomains);
178}
179
180
182void logDurations(std::vector<std::pair<MFloat, MString>>& durations, const MString module, const MPI_Comm comm,
183 const MInt domainId, const MInt noDomains) {
184 const MInt noDurations = durations.size();
185
186 std::vector<MFloat> maxDurations(noDurations);
187 for(MInt i = 0; i < noDurations; i++) {
188 maxDurations[i] = durations[i].first;
189 }
190 // Copy durations vector
191 std::vector<MFloat> minDurations = maxDurations;
192 std::vector<MFloat> sumDurations = maxDurations;
193
194 // Compute max, min and sum of durations over all involved ranks
195 MPI_Allreduce(MPI_IN_PLACE, &maxDurations[0], noDurations, maia::type_traits<MFloat>::mpiType(), MPI_MAX, comm, AT_,
196 "MPI_IN_PLACE", "maxDurations");
197 MPI_Allreduce(MPI_IN_PLACE, &minDurations[0], noDurations, maia::type_traits<MFloat>::mpiType(), MPI_MIN, comm, AT_,
198 "MPI_IN_PLACE", "minDurations");
199 MPI_Allreduce(MPI_IN_PLACE, &sumDurations[0], noDurations, maia::type_traits<MFloat>::mpiType(), MPI_SUM, comm, AT_,
200 "MPI_IN_PLACE", "sumDurations");
201
202 const MInt maxLineLength = 256;
203 MChar b[maxLineLength];
204 for(MInt i = 0; i < noDurations; i++) {
205 const MString comment = durations[i].second;
206 snprintf(b, maxLineLength, "=== MAIA %s DURATION: %-35s | min: %.4e s | avg: %.4e s | max: %.4e s |",
207 module.c_str(), comment.c_str(), minDurations[i], sumDurations[i] / (MFloat)noDomains, maxDurations[i]);
208 if(domainId == 0) {
209 std::cerr << b << std::endl;
210 }
211 m_log << b << std::endl;
212 }
213}
This class counts the static execution time of a function.
Definition: timer.h:649
FunctionTiming & operator=(const FunctionTiming &t)
Definition: timer.cpp:142
MFloat m_initWallTime
Definition: timer.h:666
MFloat m_deltaWallTime
Definition: timer.h:667
MFloat m_deltaCpuTime
Definition: timer.h:664
MString m_name
Definition: timer.h:669
FunctionTiming(std::string name)
Definition: timer.cpp:131
MFloat m_tmpCpuTime
Definition: timer.h:665
void in()
Definition: timer.cpp:153
MFloat m_tmpWallTime
Definition: timer.h:668
void out()
Definition: timer.cpp:158
MFloat m_initCpuTime
Definition: timer.h:663
MTimers manages all MAIA Timers and allows primitive profiling.
Definition: timer.h:169
static MString printTime(MFloat secs)
Definition: timer.cpp:106
static MInt getTimingId(std::string name)
Definition: timer.cpp:88
const MFloat m_initWallTime
Definition: timer.h:689
~Profile()
Definition: timer.cpp:32
const MString m_name
Definition: timer.h:690
static std::vector< FunctionTiming > s_functionTimings
Definition: timer.h:685
const MFloat m_initCpuTime
Definition: timer.h:688
MBool approx(const T &, const U &, const T)
Definition: functions.h:272
MFloat cpuTime()
Return the process cpu time (user time) (high-resolution timer - do not use clock())
Definition: functions.h:73
MFloat wallTime()
Definition: functions.h:80
InfoOutFile m_log
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
char MChar
Definition: maiatypes.h:56
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce
Definition: contexttypes.h:19
void logDuration_(const MFloat timeStart, const MString module, const MString comment, const MPI_Comm comm, const MInt domainId, const MInt noDomains)
Output the min/max/average duration of a code section over the ranks in a communicator Note: only use...
Definition: timer.cpp:171
MTimers & timers()
Definition: timer.cpp:19
void logDurations(std::vector< std::pair< MFloat, MString > > &durations, const MString module, const MPI_Comm comm, const MInt domainId, const MInt noDomains)
Output the min/max/average durations of provided timed code sections over the ranks in a communicator...
Definition: timer.cpp:182
MBool operator<(const FunctionTiming &a, const FunctionTiming &b)
Definition: timer.cpp:27
InfoOutFile m_log
Definition: timer.h:34