21#if defined(MAIA_MS_COMPILER)
38#if defined(MAIA_MS_COMPILER)
39static const unsigned __int64 epoch = ((
unsigned __int64)116444736000000000ULL);
42#ifdef MAIA_TIMER_FUNCTION
43#define NEW_TIMER_GROUP(id, groupName) const MInt id = timers().newGroup(groupName)
44#define NEW_TIMER(id, timerName, groupId) const MInt id = timers().newGroupTimer(timerName, groupId)
45#define NEW_SUB_TIMER(id, timerName, timerId) const MInt id = timers().newSubTimer(timerName, timerId)
46#define NEW_TIMER_GROUP_STATIC(id, groupName) static const MInt id = timers().newGroup(groupName)
47#define NEW_TIMER_STATIC(id, timerName, groupId) static const MInt id = timers().newGroupTimer(timerName, groupId)
48#define NEW_SUB_TIMER_STATIC(id, timerName, timerId) static const MInt id = timers().newSubTimer(timerName, timerId)
49#define NEW_TIMER_GROUP_NOCREATE(id, groupName) id = timers().newGroup(groupName)
50#define NEW_TIMER_NOCREATE(id, timerName, groupId) id = timers().newGroupTimer(timerName, groupId)
51#define NEW_SUB_TIMER_NOCREATE(id, timerName, timerId) id = timers().newSubTimer(timerName, timerId)
52#define RECORD_TIMER_START(timerId) timers().recordTimerStart(timerId, AT_)
53#define RECORD_TIMER_STOP(timerId) timers().recordTimerStop(timerId, AT_)
54#define RETURN_TIMER(timerId) timers().returnTimer(timerId, AT_)
55#define RETURN_TIMER_TIME(timerId) timers().returnTimerTime(timerId)
56#define STOP_ALL_TIMERS() timers().stopAllTimers(AT_)
57#define RECORD_TIMER(timerId) timers().recordTimer(timerId, AT_)
58#define RECORD_TIMERS() timers().recordTimers(AT_)
59#define STOP_ALL_RECORD_TIMERS() timers().stopAllRecordTimers(AT_)
60#define DISPLAY_TIMER(timerId) timers().displayTimer(timerId)
61#define DISPLAY_TIMER_INTERM(timerId) timers().displayTimerNoToggleDisplayed(timerId)
62#define DISPLAY_TIMER_OFFSET(timerId, ivl) \
63 if(globalTimeStep % ivl == 0) timers().displayTimerNoToggleDisplayed(timerId)
64#define DISPLAY_ALL_GROUP_TIMERS(groupId) timers().displayAllTimers(groupId)
65#define DISPLAY_ALL_TIMERS() timers().displayAllTimers()
66#define RESET_TIMER(timerId) timers().resetTimer(timerId, AT_)
67#define RESET_TIMERS() timers().resetTimers(AT_)
68#define RESET_RECORD(timerId) timers().resetRecord(timerId)
69#define SET_RECORD(timerId, timerValue) timers().resetRecord(timerId, timerValue)
70#define RESET_ALL_RECORDS() timers().resetRecords()
71#define SET_RECORD(timerId, timerValue) timers().resetRecord(timerId, timerValue)
73#define NEW_TIMER_GROUP(id, groupName) \
76#define NEW_TIMER(id, timerName, groupId) \
79#define NEW_SUB_TIMER(id, timerName, timerId) \
82#define NEW_TIMER_GROUP_STATIC(id, groupName) \
85#define NEW_TIMER_STATIC(id, timerName, groupId) \
88#define NEW_SUB_TIMER_STATIC(id, timerName, timerId) \
91#define NEW_TIMER_GROUP_NOCREATE(id, groupName) \
94#define NEW_TIMER_NOCREATE(id, timerName, groupId) \
97#define NEW_SUB_TIMER_NOCREATE(id, timerName, timerId) \
100#define RECORD_TIMER_START(timerId) \
103#define RECORD_TIMER_STOP(timerId) \
106#define RETURN_TIMER(timerId) \
109#define STOP_ALL_TIMERS() \
112#define RECORD_TIMER(timerId) \
115#define DISPLAY_TIMER(timerId) \
118#define DISPLAY_ALL_GROUP_TIMERS(groupId) \
121#define DISPLAY_ALL_TIMERS() \
124#define RESET_TIMER(timerId) \
127#define RESET_TIMERS() \
130#define RESET_RECORD(timerId) \
133#define RESET_ALL_RECORDS() \
136#define SET_RECORD(timeValue, timerId) \
200#if defined(MAIA_TIMER_FUNCTION)
201 m_log <<
"MTimers: timers enabled." << std::endl;
203#if defined(MAIA_TIMER_DEBUG)
204 m_log <<
"MTimers: timer debug enabled." << std::endl;
206#if defined(MAIA_TIMER_CHECKS)
207 m_log <<
"MTimers: timer checks enabled." << std::endl;
209#if defined(MAIA_ASSERT_TIMER_CHECKS)
210 m_log <<
"MTimers: assert timer checks enabled." << std::endl;
247 const MBool toggleDisplayed =
true,
248 const MInt tIndent = 0,
249 const MFloat superTime = -1.0);
267 clock_gettime(CLOCK_REALTIME, &t);
268 return static_cast<MFloat>(t.tv_sec) +
static_cast<MFloat>(t.tv_nsec / 1000000000.0);
271 gettimeofday(&t,
nullptr);
272 return static_cast<MFloat>(t.tv_sec) +
static_cast<MFloat>(t.tv_usec / 1000000.0);
278 m_timers[timerId].recordedTime = timerValue;
282 for(std::size_t timerId = 0, e =
m_timers.size(); timerId != e; ++timerId) {
291#ifdef MAIA_SYNCHRONIZE_TIMERS
303 for(std::size_t timerId = 0, e =
m_timers.size(); timerId != e; ++timerId) {
309#if defined(MAIA_TIMER_CHECKS)
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)
326 for(std::size_t timerId = 0, e =
m_timers.size(); timerId != e; ++timerId) {
334#if defined(MAIA_TIMER_DEBUG)
335 m_log <<
"New timer group " <<
m_groups.size() - 1 <<
" '" << name <<
"' " << std::endl;
342 ASSERT(
static_cast<std::size_t
>(groupId) <
m_groups.size() && groupId > -1,
343 "groupId: " << groupId <<
" does not exists | name: " << name);
346#if defined(MAIA_TIMER_DEBUG)
347 m_log <<
"New group timer " << newTimerId <<
" '" << name <<
"' " << groupId << std::endl;
355#if defined(MAIA_TIMER_DEBUG)
356 m_log <<
"cannot create subTimer '" << name <<
"'" << std::endl;
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);
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;
370 m_timers[timerId].subTimers.push_back(newTimerId);
378#ifdef MAIA_SYNCHRONIZE_TIMERS
387 "The timer " <<
m_timers[timerId].name <<
" with id: " << timerId
388 <<
" can't be started because it is already running! " << pos);
390#if defined(MAIA_TIMER_CHECKS)
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)
406#if defined(MAIA_TIMER_DEBUG)
407 m_log <<
"start timer #" + std::to_string(timerId) +
" '" +
m_timers[timerId].name +
"' " << pos << std::endl;
417 LIKWID_MARKER_START(std::to_string(timerId).c_str());
425 TERMM(1,
"Invalid timer id");
429#if defined(MAIA_TIMER_CHECKS)
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)
441#if MAIA_TIMERS_AVERAGE_OVER_DOMAINS
444 MPI_Reduce(&t, &tmp_rcv, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
457#if defined(MAIA_TIMER_DEBUG)
458 m_log <<
"cannot stop timer " << timerId <<
" " << pos << std::endl;
468#if defined(MAIA_TIMER_CHECKS)
469 for(
auto subTimerId :
m_timers[timerId].subTimers) {
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)
483#if defined(MAIA_TIMER_DEBUG)
484 m_log <<
"stop timer #" + std::to_string(timerId) +
" '" +
m_timers[timerId].name +
"' " << pos << std::endl;
489 LIKWID_MARKER_STOP(std::to_string(timerId).c_str());
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)
506 for(std::size_t i = 0, e =
m_timers.size(); i != e; ++i) {
518#ifdef MAIA_SYNCHRONIZE_TIMERS
537 TERMM(1,
"Timer is still running");
542 m_log.setf(std::ios::left);
543 std::stringstream indentedName;
551 }
else if(
approx(superTime, F0, MFloatEps)) {
557 percentage = 100.0 *
m_timers[timerId].recordedTime / superTime;
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;
567 m_log <<
m_timers[timerId].recordedTime << std::left <<
" [sec]";
575 m_log <<
"${timer_" << timerId <<
"}";
577 m_log <<
" [DP MFlops/s]";
579 if(toggleDisplayed)
m_timers[timerId].displayed =
true;
581 for(std::size_t sub = 0, last =
m_timers[timerId].subTimers.size(); sub < last; ++sub) {
593 m_log <<
"--------------------------------------------------------------------------------" << std::endl;
596 m_log.setf(std::ios::left);
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) {
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;
617 for(std::size_t timerId = 0, e =
m_timers.size(); timerId != e; ++timerId) {
618 if(
m_timers[timerId].group == groupId) {
622 for(std::size_t timerId = 0, e =
m_timers.size(); timerId != e; ++timerId) {
623 m_timers[timerId].displayed =
false;
628 ASSERT(
static_cast<std::size_t
>(timerId) <
m_timers.size(),
"ERROR: timer timerId does not exist");
634 ASSERT(
static_cast<std::size_t
>(timerId) <
m_timers.size(),
"ERROR: timer timerId does not exist");
699 const MInt noDomains);
701void logDurations(std::vector<std::pair<MFloat, MString>>& durations,
const MString module,
const MPI_Comm comm,
702 const MInt domainId,
const MInt noDomains);
This class counts the static execution time of a function.
MFloat getDeltaWallTime() const
FunctionTiming & operator=(const FunctionTiming &t)
MFloat getDeltaCpuTime() const
MFloat getInitCpuTime() const
MFloat getInitWallTime() const
Class to create a create an output stream for a writable file, using either MPI I/O or a physical fil...
MTimers manages all MAIA Timers and allows primitive profiling.
void recordTimerStart(const MInt timerId, const MString pos)
void stopTimer(const MInt timerId, const MString pos)
Stops the timer and sets its final value.
MFloat returnTimer(const MInt timerId, const MString pos)
Returns the timer Value.
MInt newSubTimer(const std::string timerName, const MInt timerId)
Creates a new timer and returns its timerId.
void stopAllRecordTimers(const MString pos)
void resetTimer(const MInt timerId, const MString pos)
void recordTimers(const MString pos)
void displayTimerHeader_()
MTimers & operator=(const MTimers &)
MFloat returnTimerTime(const MInt timerId)
MFloat time()
Returns Wall-Clock time in seconds.
void resetRecord(const MInt timerId, const MFloat timerValue=0.0)
MInt newGroupTimer(const std::string timerName, const MInt groupId)
Creates a new timer and returns its timerId.
MInt newGroup(const std::string groupName)
Creates a new timer group and returns its groupId.
friend MTimers & timers()
void recordTimerStop(const MInt timerId, const MString pos)
void recordTimer(const MInt timerId, const MString pos)
void displayTimer(const MInt timerId)
void displayTimerGroupHeader_(const MInt groupId)
void stopAllTimers(const MString pos)
void displayTimer_(const MInt timerId, const MBool toggleDisplayed=true, const MInt tIndent=0, const MFloat superTime=-1.0)
std::vector< Timer > m_timers
void resetTimers(const MString pos)
void displayTimerNoToggleDisplayed(const MInt timerId)
MInt isRunning(const MInt timerId) const
std::vector< std::string > m_groups
void startTimer(const MInt timerId, const MString pos)
MInt indent(const MInt pIndent) const
This class collects all function timings and produces a profiling for certain areas of the code.
static MString printTime(MFloat secs)
static MInt getTimingId(std::string name)
const MFloat m_initWallTime
Profile(const std::string &name)
static std::vector< FunctionTiming > s_functionTimings
const MFloat m_initCpuTime
MBool approx(const T &, const U &, const T)
MFloat cpuTime()
Return the process cpu time (user time) (high-resolution timer - do not use clock())
MInt globalNoDomains()
Return global number of domains.
std::basic_string< char > MString
int MPI_Barrier(MPI_Comm comm, const MString &name)
same as MPI_Barrier
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
MInt status
Timer's status, see enum:
std::vector< MInt > subTimers
MFloat recordedTime
Time recorded on the timer.
MInt parent
Parent timer id.
MFloat oldCpuTime
Old CPU time (for timer restart)
Timer(const MString n, const MInt g, const MInt id, const MInt p)
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...
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...
MBool operator<(const FunctionTiming &a, const FunctionTiming &b)