12 #ifndef CD_TimerImplem_H
13 #define CD_TimerImplem_H
28 #include <CD_NamespaceHeader.H>
35 const auto currentTime = std::chrono::steady_clock::now();
36 const auto durationInSeconds = std::chrono::duration<Real>(currentTime.time_since_epoch());
38 return durationInSeconds.count();
62 if (omp_get_thread_num() == 0) {
64 if (m_events.find(a_event) == m_events.end()) {
68 m_events.emplace(a_event, std::make_tuple(
false, startTime, elapsedTime));
72 std::tuple<bool, TimePoint, Duration>&
event = m_events.at(a_event);
73 const bool stoppedEvent = std::get<StoppedEvent>(event);
77 const Duration& previousElapsedTime = std::get<ElapsedTime>(event);
79 event = std::make_tuple(
false, startTime, previousElapsedTime);
91 if (omp_get_thread_num() == 0) {
93 if (m_events.find(a_event) != m_events.end()) {
94 std::tuple<bool, TimePoint, Duration>&
event = m_events.at(a_event);
96 const TimePoint startTime = std::get<StartClock>(event);
98 const Duration curElapsedTime = stopTime - startTime;
99 const Duration previousElapsedTime = std::get<ElapsedTime>(event);
100 const Duration totalElapsedTime = previousElapsedTime + curElapsedTime;
102 event = std::make_tuple(
true, startTime, totalElapsedTime);
105 std::cerr <<
"Timer::stopEvent -- event '" + a_event +
"' has not been started\n";
116 if (omp_get_thread_num() == 0) {
118 std::stringstream header;
120 <<
"| ---------------------------------------------------------------------------------------------------------|"
122 <<
"| " + m_processName +
" kernel report: "
124 <<
"| ---------------------------------------------------------------------------------------------------------|"
126 <<
"| " << std::left << std::setw(25) <<
"Event"
127 <<
"| " << std::right << std::setw(8) <<
"Loc. (s)"
128 <<
"| " << std::right << std::setw(8) <<
"Loc. (%)"
130 <<
"| " << std::right << std::setw(8) <<
"Min. (s)"
131 <<
"| " << std::right << std::setw(8) <<
"Max. (s)"
132 <<
"| " << std::right << std::setw(8) <<
"Avg. (s)"
133 <<
"| " << std::right << std::setw(8) <<
"Dev. (s)"
134 <<
"| " << std::right << std::setw(8) <<
"Min rank"
135 <<
"| " << std::right << std::setw(8) <<
"Max rank"
139 <<
"| ---------------------------------------------------------------------------------------------------------|"
142 a_outputStream << header.str();
152 if (omp_get_thread_num() == 0) {
154 std::stringstream tail;
157 <<
"| ---------------------------------------------------------------------------------------------------------|"
159 <<
"| Local elapsed time = " << std::fixed << std::setprecision(4) << a_elapsedTime.first <<
" seconds"
161 <<
"| Global elapsed time = " << std::fixed << std::setprecision(4) << a_elapsedTime.second <<
" seconds"
163 <<
"| ---------------------------------------------------------------------------------------------------------|"
166 a_outputStream << tail.str();
178 if (omp_get_thread_num() == 0) {
181 this->printReportHeader(a_outputStream);
183 const std::pair<Real, Real> totalTime = this->computeTotalElapsedTime(a_localReportOnly);
184 const Real totalTimeLocal = totalTime.first;
186 for (
const auto& e : m_events) {
188 const std::string& eventName = e.first;
189 const bool finishedEvent = std::get<StoppedEvent>(e.second);
191 std::stringstream ssLocalDuration;
192 std::stringstream ssPercentage;
193 std::stringstream ssMinDuration;
194 std::stringstream ssMaxDuration;
195 std::stringstream ssAvgDuration;
196 std::stringstream ssDevDuration;
197 std::stringstream ssMinRank;
198 std::stringstream ssMaxRank;
201 const Duration localDuration = std::get<ElapsedTime>(e.second);
202 const Real localDurationInSeconds = localDuration.count();
204 ssLocalDuration << std::fixed << std::setprecision(4) << localDurationInSeconds;
205 ssPercentage << std::fixed << std::setprecision(4) << 100. * localDurationInSeconds / totalTimeLocal;
208 if (!a_localReportOnly) {
210 const int srcRank = 0;
211 const int numRank = numProc();
213 Vector<Real> allDurations(numRank);
214 gather(allDurations, localDurationInSeconds, srcRank);
229 for (
int i = 0; i < allDurations.size(); i++) {
232 if (allDurations[i] < minTime) {
234 minTime = allDurations[i];
236 if (allDurations[i] > maxTime) {
238 maxTime = allDurations[i];
244 for (
int i = 0; i < allDurations.size(); i++) {
245 sigma += sqrt(std::pow(allDurations[i] -
average, 2));
247 sigma = sqrt(sigma / numRank);
251 broadcast(sigma, srcRank);
252 broadcast(maxTime, srcRank);
253 broadcast(minTime, srcRank);
257 ssMinDuration << std::fixed << std::setprecision(4) << minTime;
258 ssMaxDuration << std::fixed << std::setprecision(4) << maxTime;
259 ssAvgDuration << std::fixed << std::setprecision(4) <<
average;
260 ssDevDuration << std::fixed << std::setprecision(4) << sigma;
261 ssMinRank << std::fixed << std::setprecision(4) <<
minRank;
262 ssMaxRank << std::fixed << std::setprecision(4) <<
maxRank;
265 ssMinDuration <<
" N/A ";
266 ssMaxDuration <<
" N/A ";
267 ssAvgDuration <<
" N/A ";
268 ssDevDuration <<
" N/A ";
269 ssMinRank <<
" N/A ";
270 ssMaxRank <<
" N/A ";
275 ssLocalDuration <<
" - ";
276 ssPercentage <<
" - ";
277 ssMinDuration <<
" - ";
278 ssMaxDuration <<
" - ";
279 ssAvgDuration <<
" - ";
280 ssDevDuration <<
" - ";
285 std::stringstream outputString;
288 outputString <<
"| " << std::left << std::setw(25) << eventName <<
"| " << std::right << std::setw(8)
289 << ssLocalDuration.str() <<
"| " << std::right << std::setw(8) << ssPercentage.str()
291 <<
"| " << std::right << std::setw(8) << ssMinDuration.str() <<
"| " << std::right << std::setw(8)
292 << ssMaxDuration.str() <<
"| " << std::right << std::setw(8) << ssAvgDuration.str() <<
"| "
293 << std::right << std::setw(8) << ssDevDuration.str() <<
"| " << std::right << std::setw(8)
294 << ssMinRank.str() <<
"| " << std::right << std::setw(8) << ssMaxRank.str()
299 a_outputStream << outputString.str();
302 this->printReportTail(a_outputStream, totalTime);
309 inline std::pair<Real, Real>
313 Real elapsedTimeLocal = 0.0;
314 Real elapsedTimeGlobal = 0.0;
316 for (
const auto& e : m_events) {
317 const bool finishedEvent = std::get<StoppedEvent>(e.second);
320 const Duration elapsedTime = std::get<ElapsedTime>(e.second);
321 const Real localDurationInSeconds = elapsedTime.count();
323 elapsedTimeLocal += localDurationInSeconds;
328 if (!a_localReportOnly) {
329 MPI_Allreduce(&elapsedTimeLocal, &elapsedTimeGlobal, 1, MPI_CH_REAL, MPI_MAX, Chombo_MPI::comm);
332 elapsedTimeGlobal = elapsedTimeLocal;
335 elapsedTimeGlobal = elapsedTimeLocal;
338 return std::make_pair(elapsedTimeLocal, elapsedTimeGlobal);
346 std::vector<std::string> headerRow;
347 headerRow.emplace_back(
"# MPI rank");
352 std::vector<std::vector<Real>> finishedEvents;
355 constexpr
int srcRank = 0;
356 const int numRanks = numProc();
358 const int numRanks = 1;
361 for (
const auto& e : m_events) {
362 const std::string& eventName = e.first;
363 const std::tuple<bool, TimePoint, Duration>& eventData = e.second;
365 const bool finishedEvent = std::get<StoppedEvent>(eventData);
370 const Real localEventDuration = std::get<ElapsedTime>(eventData).count();
371 Vector<Real> allTimes(numRanks, 0.0);
373 gather(allTimes, localEventDuration, srcRank);
375 allTimes[0] = localEventDuration;
378 finishedEvents.emplace_back(allTimes.stdVector());
379 headerRow.emplace_back(eventName);
385 if (procID() == srcRank) {
388 if (omp_get_thread_num() == 0) {
391 f.open(a_fileName, std::ios_base::trunc);
393 const int width = 12;
394 for (
int col = 0; col < headerRow.size(); col++) {
395 f << std::left << std::setw(width) << headerRow[col] <<
"\t";
400 for (
int irank = 0; irank < numRanks; irank++) {
401 f << std::left << std::setw(width) << irank <<
"\t";
402 for (
int event = 0;
event < finishedEvents.size();
event++) {
403 f << std::left << std::setw(width) << finishedEvents[event][irank] <<
"\t";
417 #include <CD_NamespaceFooter.H>
Implementation of CD_Timer.H.
void stopEvent(const std::string a_event) noexcept
Stop an event.
Definition: CD_TimerImplem.H:88
std::chrono::duration< Real > Duration
Duration in seconds.
Definition: CD_Timer.H:46
~Timer()
Destructor.
Definition: CD_TimerImplem.H:47
void startEvent(const std::string a_event) noexcept
Start an event.
Definition: CD_TimerImplem.H:59
std::string m_processName
Process name. Used for input/output.
Definition: CD_Timer.H:135
void writeReportToFile(const std::string a_fileName) const noexcept
Print all timed events to a file.
Definition: CD_TimerImplem.H:342
std::chrono::steady_clock::time_point TimePoint
Point in time.
Definition: CD_Timer.H:41
void printReportHeader(std::ostream &a_outputStream) const noexcept
Print report header.
Definition: CD_TimerImplem.H:113
std::map< std::string, std::tuple< bool, TimePoint, Duration > > m_events
Timer events. First entry is the name of the event.
Definition: CD_Timer.H:141
Timer()=default
Default constructor. This creates a timer without any timer events and without a name.
void printReportTail(std::ostream &a_outputStream, const std::pair< Real, Real > a_elapsedTime) const noexcept
Print report tail.
Definition: CD_TimerImplem.H:149
static Real wallClock()
Static function which returns the time (in seconds) between now and an arbitrary time in the past.
Definition: CD_TimerImplem.H:31
std::pair< Real, Real > computeTotalElapsedTime(const bool a_localReportOnly) const noexcept
Compute the total time for all finished events.
Definition: CD_TimerImplem.H:310
void clear() noexcept
Clear all events.
Definition: CD_TimerImplem.H:53
void eventReport(std::ostream &a_outputStream, const bool a_localReportOnly=false) const noexcept
Print all timed events to cout.
Definition: CD_TimerImplem.H:173
Real max(const Real &a_input) noexcept
Get the maximum of the input, reduced over MPI ranks (in the Chombo communicator)
Definition: CD_ParallelOpsImplem.H:176
std::pair< Real, int > maxRank(const Real &a_val) noexcept
Get the maximum value and the rank having the maximum value.
Definition: CD_ParallelOpsImplem.H:293
Real average(const Real &a_val) noexcept
Compute the average (across MPI ranks) of the input value.
Definition: CD_ParallelOpsImplem.H:500
std::pair< Real, int > minRank(const Real &a_val) noexcept
Get the minimum value and the rank having the minimum value.
Definition: CD_ParallelOpsImplem.H:323
Real min(const Real &a_input) noexcept
Get the minimum of the input, reduced over MPI ranks (in the Chombo communicator)
Definition: CD_ParallelOpsImplem.H:58