MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
MTimers Class Reference

MTimers manages all MAIA Timers and allows primitive profiling. More...

#include <timer.h>

Collaboration diagram for MTimers:
[legend]

Classes

struct  Timer
 

Public Member Functions

MInt newGroup (const std::string groupName)
 Creates a new timer group and returns its groupId. More...
 
MInt newGroupTimer (const std::string timerName, const MInt groupId)
 Creates a new timer and returns its timerId. More...
 
MInt newSubTimer (const std::string timerName, const MInt timerId)
 Creates a new timer and returns its timerId. More...
 
MFloat returnTimer (const MInt timerId, const MString pos)
 Returns the timer Value. More...
 
MFloat returnTimerTime (const MInt timerId)
 
void resetTimer (const MInt timerId, const MString pos)
 
void recordTimer (const MInt timerId, const MString pos)
 
void recordTimerStart (const MInt timerId, const MString pos)
 
void recordTimerStop (const MInt timerId, const MString pos)
 
void recordTimers (const MString pos)
 
void stopAllTimers (const MString pos)
 
void stopAllRecordTimers (const MString pos)
 
void displayTimer (const MInt timerId)
 
void displayTimerNoToggleDisplayed (const MInt timerId)
 
void displayAllTimers ()
 
void displayAllTimers (const MInt groupId)
 
void resetTimers (const MString pos)
 
void resetRecord (const MInt timerId, const MFloat timerValue=0.0)
 
void resetRecords ()
 
MInt isRunning (const MInt timerId) const
 

Private Member Functions

void startTimer (const MInt timerId, const MString pos)
 
void stopTimer (const MInt timerId, const MString pos)
 Stops the timer and sets its final value. More...
 
 MTimers ()
 
 ~MTimers ()
 
 MTimers (MTimers &)
 
MTimersoperator= (const MTimers &)
 
MFloat time ()
 Returns Wall-Clock time in seconds. More...
 
void displayTimer_ (const MInt timerId, const MBool toggleDisplayed=true, const MInt tIndent=0, const MFloat superTime=-1.0)
 
void displayTimerHeader_ ()
 
void displayTimerGroupHeader_ (const MInt groupId)
 
MInt indent (const MInt pIndent) const
 

Private Attributes

std::vector< std::string > m_groups
 
std::vector< Timerm_timers
 

Friends

MTimerstimers ()
 

Detailed Description

Usage:

  • NEW_TIMER(string name) creates a new timer with name "name" and returns its index (a MInt that you can use to access it).
  • RESET_TIMER(MInt timerId): resets timerId.
  • START_TIMER(timerId)/STOP_TIMER(timerId) work as expected.
  • DISPLAY_TIMER(timerId) writes the timerId name and time to the log.
  • DISPLAY_ALL_TIMERS: displays all timers.

Example:

RESET_TIMER; MInt myTimer; myTimer = NEW_TIMER("My timer");

START_TIMER(myTimer); f1(); // Function will be timed. STOP_TIMER(myTimer); f2(); // Function will not be timed. START_TIMER(myTimer); f3(); // Function will be timed. STOP_TIMER(myTimer);

DISPLAY_TIMER(myTimer);

NOTE: MAIA_TIMER_FUNCTION macro enable/disables timing MAIA.

Definition at line 169 of file timer.h.

Constructor & Destructor Documentation

◆ MTimers() [1/2]

MTimers::MTimers ( )
inlineprivate

Definition at line 199 of file timer.h.

199 {
200#if defined(MAIA_TIMER_FUNCTION)
201 m_log << "MTimers: timers enabled." << std::endl;
202#endif
203#if defined(MAIA_TIMER_DEBUG)
204 m_log << "MTimers: timer debug enabled." << std::endl;
205#endif
206#if defined(MAIA_TIMER_CHECKS)
207 m_log << "MTimers: timer checks enabled." << std::endl;
208#endif
209#if defined(MAIA_ASSERT_TIMER_CHECKS)
210 m_log << "MTimers: assert timer checks enabled." << std::endl;
211#endif
212 }
InfoOutFile m_log
Definition: timer.h:34

◆ ~MTimers()

MTimers::~MTimers ( )
inlineprivate

Definition at line 213 of file timer.h.

213{}

◆ MTimers() [2/2]

MTimers::MTimers ( MTimers )
private

Member Function Documentation

◆ displayAllTimers() [1/2]

void MTimers::displayAllTimers ( )
inline

Definition at line 602 of file timer.h.

602 {
603 ASSERT(m_timers.size() > 0, "ERROR: no timers have been created!");
604 for(std::size_t groupId = 0, e = m_groups.size(); groupId != e; ++groupId) {
605 displayAllTimers(groupId);
606 }
607}
void displayAllTimers()
Definition: timer.h:602
std::vector< Timer > m_timers
Definition: timer.h:243
std::vector< std::string > m_groups
Definition: timer.h:242

◆ displayAllTimers() [2/2]

void MTimers::displayAllTimers ( const MInt  groupId)
inline

Definition at line 609 of file timer.h.

609 {
610 ASSERT(m_timers.size() > 0, "ERROR: no timers have been created!");
611 ASSERT(static_cast<std::size_t>(groupId) < m_groups.size() && groupId > -1, "ERROR: groupId does not exists");
612 for(std::size_t timerId = 0, e = m_timers.size(); timerId != e; ++timerId) {
613 m_timers[timerId].displayed = false;
614 }
617 for(std::size_t timerId = 0, e = m_timers.size(); timerId != e; ++timerId) {
618 if(m_timers[timerId].group == groupId) {
619 displayTimer_(timerId);
620 }
621 }
622 for(std::size_t timerId = 0, e = m_timers.size(); timerId != e; ++timerId) {
623 m_timers[timerId].displayed = false;
624 }
625}
void displayTimerHeader_()
Definition: timer.h:590
void displayTimerGroupHeader_(const MInt groupId)
Definition: timer.h:592
void displayTimer_(const MInt timerId, const MBool toggleDisplayed=true, const MInt tIndent=0, const MFloat superTime=-1.0)
Definition: timer.h:528

◆ displayTimer()

void MTimers::displayTimer ( const MInt  timerId)
inline

Definition at line 627 of file timer.h.

627 {
628 ASSERT(static_cast<std::size_t>(timerId) < m_timers.size(), "ERROR: timer timerId does not exist");
630 displayTimer_(timerId);
631}

◆ displayTimer_()

void MTimers::displayTimer_ ( const MInt  timerId,
const MBool  toggleDisplayed = true,
const MInt  tIndent = 0,
const MFloat  superTime = -1.0 
)
inlineprivate

Definition at line 528 of file timer.h.

529 {
530 if(m_timers[timerId].displayed) {
531 return;
532 }
533
534 /* MBool running = false; */
535 if(m_timers[timerId].status == Timer::Running) {
536 // NOTE: test this if needed, but not used at the moment
537 TERMM(1, "Timer is still running");
538 /* running = true; */
539 /* stopTimer(timerId, AT_); */
540 }
541 m_log.width(50);
542 m_log.setf(std::ios::left);
543 std::stringstream indentedName;
544
545 // Calculate time relative to the parent timer
546 MFloat percentage;
547 if(superTime < F0) {
548 // If the parent time is less than zero, that means that there is no parent timer
549 // and the percentage should be 100%
550 percentage = 100.0;
551 } else if(approx(superTime, F0, MFloatEps)) {
552 // If the parent time is approximately zero, that probably means that the timer was never
553 // run - therefore the percentage is set to 0%
554 percentage = F0;
555 } else {
556 // Otherwise calculate the percentage as the fraction of this timer vs. the parent timer times 100%
557 percentage = 100.0 * m_timers[timerId].recordedTime / superTime;
558 }
559
560 indentedName << std::string(tIndent, ' ');
561 indentedName << "[" << std::fixed << std::setprecision(1) << std::setw(4) << std::setfill('0') << std::right
562 << percentage << std::left << "%] ";
563 indentedName << m_timers[timerId].name;
564 m_log << indentedName.str() << std::right;
565 m_log.precision(6);
566 m_log.width(20);
567 m_log << m_timers[timerId].recordedTime << std::left << " [sec]";
568 // Show output of likwid performance counters if likwid is enabled
569#ifdef WITH_LIKWID
570 // If the timer wasn't called set the MFLops to 0.00
571 m_log << " ";
572 if(approx(m_timers[timerId].recordedTime, F0, MFloatEps)) {
573 m_log << "0.00";
574 } else {
575 m_log << "${timer_" << timerId << "}";
576 }
577 m_log << " [DP MFlops/s]";
578#endif
579 if(toggleDisplayed) m_timers[timerId].displayed = true;
580 m_log << std::endl;
581 for(std::size_t sub = 0, last = m_timers[timerId].subTimers.size(); sub < last; ++sub) {
582 const MInt new_indent = indent(tIndent);
583 displayTimer_(m_timers[timerId].subTimers[sub], toggleDisplayed, new_indent, m_timers[timerId].recordedTime);
584 }
585 /* if(running) { */
586 /* startTimer(timerId, AT_); */
587 /* } */
588}
MInt indent(const MInt pIndent) const
Definition: timer.h:252
MBool approx(const T &, const U &, const T)
Definition: functions.h:272
int32_t MInt
Definition: maiatypes.h:62
double MFloat
Definition: maiatypes.h:52

◆ displayTimerGroupHeader_()

void MTimers::displayTimerGroupHeader_ ( const MInt  groupId)
inlineprivate

Definition at line 592 of file timer.h.

592 {
593 m_log << "--------------------------------------------------------------------------------" << std::endl;
594 m_log.width(50);
595 m_log.precision(12);
596 m_log.setf(std::ios::left);
597 m_log << "Group";
598 m_log.width(40);
599 m_log << m_groups[groupId] << std::endl;
600}

◆ displayTimerHeader_()

void MTimers::displayTimerHeader_ ( )
inlineprivate

Definition at line 590 of file timer.h.

590{}

◆ displayTimerNoToggleDisplayed()

void MTimers::displayTimerNoToggleDisplayed ( const MInt  timerId)
inline

Definition at line 633 of file timer.h.

633 {
634 ASSERT(static_cast<std::size_t>(timerId) < m_timers.size(), "ERROR: timer timerId does not exist");
636 displayTimer_(timerId, false);
637}

◆ indent()

MInt MTimers::indent ( const MInt  pIndent) const
inlineprivate

Definition at line 252 of file timer.h.

252{ return pIndent + 2; };

◆ isRunning()

MInt MTimers::isRunning ( const MInt  timerId) const
inline

Definition at line 192 of file timer.h.

192{ return m_timers[timerId].status == Timer::Running; };

◆ newGroup()

MInt MTimers::newGroup ( const std::string  groupName)
inline

Definition at line 332 of file timer.h.

332 {
333 m_groups.push_back(name);
334#if defined(MAIA_TIMER_DEBUG)
335 m_log << "New timer group " << m_groups.size() - 1 << " '" << name << "' " << std::endl;
336#endif
337 return m_groups.size() - 1;
338}

◆ newGroupTimer()

MInt MTimers::newGroupTimer ( const std::string  timerName,
const MInt  groupId 
)
inline

Definition at line 341 of file timer.h.

341 {
342 ASSERT(static_cast<std::size_t>(groupId) < m_groups.size() && groupId > -1,
343 "groupId: " << groupId << " does not exists | name: " << name);
344 const MInt newTimerId = m_timers.size();
345 m_timers.push_back(Timer(name, groupId, newTimerId, -1));
346#if defined(MAIA_TIMER_DEBUG)
347 m_log << "New group timer " << newTimerId << " '" << name << "' " << groupId << std::endl;
348#endif
349 return newTimerId;
350}

◆ newSubTimer()

MInt MTimers::newSubTimer ( const std::string  timerName,
const MInt  timerId 
)
inline

Definition at line 353 of file timer.h.

353 {
354 if(timerId < 0) {
355#if defined(MAIA_TIMER_DEBUG)
356 m_log << "cannot create subTimer '" << name << "'" << std::endl;
357#endif
358 return -1;
359 }
360
361 ASSERT(static_cast<std::size_t>(timerId) < m_timers.size(),
362 "timerId " << timerId << " does not exist when trying to create subtimer with name " << name);
363
364 const MInt groupId = m_timers[timerId].group;
365 const MInt newTimerId = m_timers.size();
366 m_timers.push_back(Timer(name, groupId, newTimerId, timerId));
367#if defined(MAIA_TIMER_DEBUG)
368 m_log << "New subtimer " << newTimerId << " '" << name << "' " << groupId << " " << timerId << std::endl;
369#endif
370 m_timers[timerId].subTimers.push_back(newTimerId);
371 return newTimerId;
372}

◆ operator=()

MTimers & MTimers::operator= ( const MTimers )
private

◆ recordTimer()

void MTimers::recordTimer ( const MInt  timerId,
const MString  pos 
)
inline

Definition at line 298 of file timer.h.

298 {
299 m_timers[timerId].recordedTime += returnTimer(timerId, pos);
300}
MFloat returnTimer(const MInt timerId, const MString pos)
Returns the timer Value.
Definition: timer.h:423

◆ recordTimers()

void MTimers::recordTimers ( const MString  pos)
inline

Definition at line 302 of file timer.h.

302 {
303 for(std::size_t timerId = 0, e = m_timers.size(); timerId != e; ++timerId) {
304 recordTimer(timerId, pos);
305 }
306}
void recordTimer(const MInt timerId, const MString pos)
Definition: timer.h:298

◆ recordTimerStart()

void MTimers::recordTimerStart ( const MInt  timerId,
const MString  pos 
)
inline

Definition at line 374 of file timer.h.

374 {
375 if(timerId < 0) {
376 return;
377 }
378#ifdef MAIA_SYNCHRONIZE_TIMERS
379 MPI_Barrier(MPI_COMM_WORLD);
380#endif
381 resetTimer(timerId, pos);
382 startTimer(timerId, pos);
383}
void resetTimer(const MInt timerId, const MString pos)
Definition: timer.h:308
void startTimer(const MInt timerId, const MString pos)
Definition: timer.h:385
int MPI_Barrier(MPI_Comm comm, const MString &name)
same as MPI_Barrier

◆ recordTimerStop()

void MTimers::recordTimerStop ( const MInt  timerId,
const MString  pos 
)
inline

Definition at line 287 of file timer.h.

287 {
288 if(timerId < 0) {
289 return;
290 }
291#ifdef MAIA_SYNCHRONIZE_TIMERS
292 MPI_Barrier(MPI_COMM_WORLD);
293#endif
294 stopTimer(timerId, pos);
295 recordTimer(timerId, pos);
296}
void stopTimer(const MInt timerId, const MString pos)
Stops the timer and sets its final value.
Definition: timer.h:455

◆ resetRecord()

void MTimers::resetRecord ( const MInt  timerId,
const MFloat  timerValue = 0.0 
)
inline

Definition at line 277 of file timer.h.

277 {
278 m_timers[timerId].recordedTime = timerValue;
279}

◆ resetRecords()

void MTimers::resetRecords ( )
inline

Definition at line 281 of file timer.h.

281 {
282 for(std::size_t timerId = 0, e = m_timers.size(); timerId != e; ++timerId) {
283 resetRecord((MInt)timerId);
284 }
285}
void resetRecord(const MInt timerId, const MFloat timerValue=0.0)
Definition: timer.h:277

◆ resetTimer()

void MTimers::resetTimer ( const MInt  timerId,
const MString  pos 
)
inline

Definition at line 308 of file timer.h.

308 {
309#if defined(MAIA_TIMER_CHECKS)
310 if(m_timers[timerId].status == Timer::Running) {
311 const MString msg = "The timer #" + std::to_string(timerId) + " '" + m_timers[timerId].name
312 + "' can't be reset because it is running! " + pos;
313 m_log << msg << std::endl;
314 std::cerr << msg << std::endl;
315#if defined(MAIA_ASSERT_TIMER_CHECKS)
316 TERMM(1, msg);
317#endif
318 }
319#endif
320
321 m_timers[timerId].cpuTime = 0.0;
322 m_timers[timerId].status = Timer::Stopped;
323}
std::basic_string< char > MString
Definition: maiatypes.h:55

◆ resetTimers()

void MTimers::resetTimers ( const MString  pos)
inline

Definition at line 325 of file timer.h.

325 {
326 for(std::size_t timerId = 0, e = m_timers.size(); timerId != e; ++timerId) {
327 resetTimer(timerId, pos);
328 }
329}

◆ returnTimer()

MFloat MTimers::returnTimer ( const MInt  timerId,
const MString  pos 
)
inline

Definition at line 423 of file timer.h.

423 {
424 if(timerId < 0) {
425 TERMM(1, "Invalid timer id");
426 return 0.0;
427 }
428
429#if defined(MAIA_TIMER_CHECKS)
430 if(m_timers[timerId].status != Timer::Stopped) {
431 const MString msg = "The timer #" + std::to_string(timerId) + " '" + m_timers[timerId].name
432 + "' needs to be stopped before returnTimer() is called! " + pos;
433 m_log << msg << std::endl;
434 std::cerr << msg << std::endl;
435#if defined(MAIA_ASSERT_TIMER_CHECKS)
436 TERMM(1, msg);
437#endif
438 }
439#endif
440
441#if MAIA_TIMERS_AVERAGE_OVER_DOMAINS
442 const MFloat t = m_timers[timerId].cpuTime;
443 MFloat tmp_rcv = 0.0;
444 MPI_Reduce(&t, &tmp_rcv, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
445 return tmp_rcv / globalNoDomains();
446#else
447 return m_timers[timerId].cpuTime;
448#endif
449}
MInt globalNoDomains()
Return global number of domains.
int MPI_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Reduce

◆ returnTimerTime()

MFloat MTimers::returnTimerTime ( const MInt  timerId)
inline

Definition at line 452 of file timer.h.

452{ return m_timers[timerId].recordedTime; }

◆ startTimer()

void MTimers::startTimer ( const MInt  timerId,
const MString  pos 
)
inlineprivate

Definition at line 385 of file timer.h.

385 {
386 ASSERT(m_timers[timerId].status != Timer::Running,
387 "The timer " << m_timers[timerId].name << " with id: " << timerId
388 << " can't be started because it is already running! " << pos);
389
390#if defined(MAIA_TIMER_CHECKS)
391 const MInt parent = m_timers[timerId].parent;
392 if(parent != -1) {
393 if(m_timers[parent].status != Timer::Running) {
394 const MString msg = "The timer #" + std::to_string(timerId) + " '" + m_timers[timerId].name
395 + "' can't be started because its parent timer #" + std::to_string(parent) + " '"
396 + m_timers[parent].name + "' is not running! " + pos;
397 m_log << msg << std::endl;
398 std::cerr << msg << std::endl;
399#if defined(MAIA_ASSERT_TIMER_CHECKS)
400 TERMM(1, msg);
401#endif
402 }
403 }
404#endif
405
406#if defined(MAIA_TIMER_DEBUG)
407 m_log << "start timer #" + std::to_string(timerId) + " '" + m_timers[timerId].name + "' " << pos << std::endl;
408#endif
409
410 const MFloat t = time();
411 m_timers[timerId].oldCpuTime = m_timers[timerId].cpuTime;
412 m_timers[timerId].cpuTime = t;
413 m_timers[timerId].status = Timer::Running;
414
415 // Enable likwid counter if likwid is enabled
416#ifdef WITH_LIKWID
417 LIKWID_MARKER_START(std::to_string(timerId).c_str());
418#endif
419}
MFloat time()
Returns Wall-Clock time in seconds.
Definition: timer.h:258

◆ stopAllRecordTimers()

void MTimers::stopAllRecordTimers ( const MString  pos)
inline

Definition at line 514 of file timer.h.

514 {
515 // for(std::size_t i = 0, e = m_timers.size(); i != e; ++i) {
516 for(MInt i = m_timers.size() - 1; i >= 0; i--) {
517 if(m_timers[i].status == Timer::Running) {
518#ifdef MAIA_SYNCHRONIZE_TIMERS
519 MPI_Barrier(MPI_COMM_WORLD);
520#endif
521 stopTimer(i, pos);
522 recordTimer(i, pos);
523 }
524 }
525}

◆ stopAllTimers()

void MTimers::stopAllTimers ( const MString  pos)
inline

Definition at line 505 of file timer.h.

505 {
506 for(std::size_t i = 0, e = m_timers.size(); i != e; ++i) {
507 if(m_timers[i].status == Timer::Running) {
508 stopTimer(i, pos);
509 }
510 }
511}

◆ stopTimer()

void MTimers::stopTimer ( const MInt  timerId,
const MString  pos 
)
inlineprivate

Definition at line 455 of file timer.h.

455 {
456 if(timerId < 0) {
457#if defined(MAIA_TIMER_DEBUG)
458 m_log << "cannot stop timer " << timerId << " " << pos << std::endl;
459#endif
460 return;
461 }
462
463 if(m_timers[timerId].status == Timer::Running) {
464 const MFloat t = time();
465 m_timers[timerId].cpuTime = t - m_timers[timerId].cpuTime + m_timers[timerId].oldCpuTime;
466 m_timers[timerId].status = Timer::Stopped;
467
468#if defined(MAIA_TIMER_CHECKS)
469 for(auto subTimerId : m_timers[timerId].subTimers) {
470 if(m_timers[subTimerId].status == Timer::Running) {
471 const MString msg = "The timer #" + std::to_string(timerId) + " '" + m_timers[timerId].name
472 + "' can't be stopped because its sub-timer #" + std::to_string(subTimerId) + " '"
473 + m_timers[subTimerId].name + "' is still running! " + pos;
474 m_log << msg << std::endl;
475 std::cerr << msg << std::endl;
476#if defined(MAIA_ASSERT_TIMER_CHECKS)
477 TERMM(1, msg);
478#endif
479 }
480 }
481#endif
482
483#if defined(MAIA_TIMER_DEBUG)
484 m_log << "stop timer #" + std::to_string(timerId) + " '" + m_timers[timerId].name + "' " << pos << std::endl;
485#endif
486
487 // Stop likwid counter if likwid is enabled
488#ifdef WITH_LIKWID
489 LIKWID_MARKER_STOP(std::to_string(timerId).c_str());
490#endif
491 } else {
492#if defined(MAIA_TIMER_CHECKS)
493 const MString msg = "The timer '" + m_timers[timerId].name + "' can't be stopped because it is not running! " + pos;
494 m_log << msg << std::endl;
495 std::cerr << msg << std::endl;
496#if defined(MAIA_ASSERT_TIMER_CHECKS)
497 TERMM(1, msg);
498#endif
499#endif
500 }
501}

◆ time()

MFloat MTimers::time ( )
inlineprivate

Timers are not portable. We should use the C++ <chrono> library instead. The factors convert the cpu time to seconds

Definition at line 258 of file timer.h.

258 {
262#ifdef MAIA_MPI_TIMER
263 return MPI_Wtime();
264#else
265#if _POSIX_TIMERS > 0
266 timespec t;
267 clock_gettime(CLOCK_REALTIME, &t);
268 return static_cast<MFloat>(t.tv_sec) + static_cast<MFloat>(t.tv_nsec / 1000000000.0);
269#else
270 struct timeval t;
271 gettimeofday(&t, nullptr);
272 return static_cast<MFloat>(t.tv_sec) + static_cast<MFloat>(t.tv_usec / 1000000.0);
273#endif
274#endif
275}

Friends And Related Function Documentation

◆ timers

MTimers & timers ( )
friend

Definition at line 19 of file timer.cpp.

19 {
20 static MTimers timers;
21 return timers;
22}
MTimers manages all MAIA Timers and allows primitive profiling.
Definition: timer.h:169
friend MTimers & timers()
Definition: timer.cpp:19

Member Data Documentation

◆ m_groups

std::vector<std::string> MTimers::m_groups
private

Definition at line 242 of file timer.h.

◆ m_timers

std::vector<Timer> MTimers::m_timers
private

Definition at line 243 of file timer.h.


The documentation for this class was generated from the following file: