10#ifndef TEUCHOS_STACKED_TIMER_HPP
11#define TEUCHOS_STACKED_TIMER_HPP
14#include "Teuchos_Comm.hpp"
15#include "Teuchos_DefaultComm.hpp"
16#include "Teuchos_CommHelpers.hpp"
29#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOS)
32extern void pushRegion (
const std::string&);
33extern void popRegion ();
42TEUCHOSCOMM_LIB_DLL_EXPORT
void error_out(
const std::string& msg,
const bool fail_all =
false);
57 using Clock = std::chrono::high_resolution_clock;
59 BaseTimer() : accumulation_(0.0), count_started_(0), count_updates_(0), running_(
false) {}
64 error_out(
"Base_Timer:start Failed timer already running");
65 start_time_ = Clock::now();
74 error_out(
"Base_Timer:stop Failed timer not running");
75 accumulation_ += std::chrono::duration_cast<std::chrono::duration<double>>(Clock::now() - start_time_).count();
80 unsigned long long incrementUpdates(
unsigned long long count=1) {count_updates_ += count;
return count_updates_;}
double accumulatedTimePerUpdate()
const {
97 if (count_updates_ > 0) {
98 return accumulation_/count_updates_;
113 if (count_started_> 0) {
114 return accumulation_/count_started_;
127 return accumulation_ -
from.accumulation_;
133 error_out(
"BaseTimer, cannot reset a running timer");
135 count_started_ = count_updates_ = 0;
142 unsigned long numCalls()
const {
return count_started_; }
145 unsigned long long numUpdates()
const {
return count_updates_; }
156 TimeInfo():time(0.0), count(0), updates(0), running(
false){}
157 TimeInfo(BaseTimer* t): time(t->accumulation_), count(t->count_started_), updates(t->count_updates_), running(t->running()) {}
160 unsigned long long updates;
165 double accumulation_;
166 unsigned long count_started_;
167 unsigned long long count_updates_;
168 Clock::time_point start_time_;
171 friend struct TimeInfo;
211 std::vector<LevelTimer> sub_timers_;
224 const char* name =
"RootTimer",
241 for (
unsigned i=0;
i<sub_timers_.size();++
i)
242 sub_timers_[
i].parent_ =
this;
251 for (
unsigned i=0;
i<sub_timers_.size();
i++ )
253 sub_timers_[
i].BaseTimer::start();
254 return &sub_timers_[
i];
257 return &sub_timers_[sub_timers_.size()-1];
269 error_out(
"Stopping timer "+name+
" But top level running timer is "+name_);
281 if ((parent_ !=
nullptr))
297 for (
unsigned i=0;
i<sub_timers_.size(); ++
i)
298 count += sub_timers_[
i].countTimers();
304 for (
unsigned i=0;
i<sub_timers_.size(); ++
i)
305 sub_timers_[
i].addTimerNames(
names,
pos);
316 return BaseTimer::accumulatedTime();
328 for (
unsigned j=0;
j<sub_timers_.size();++
j)
365 return BaseTimer::accumulatedTimePerUpdate();
370 for (
unsigned j=0;
j<sub_timers_.size();
j++)
372 return sub_timers_[
j].accumulatedTimePerUpdate(
second_name);
384 return BaseTimer::accumulatedTimePerTimerCall();
389 for (
unsigned j=0;
j<sub_timers_.size();
j++)
391 return sub_timers_[
j].accumulatedTimePerTimerCall(
second_name);
411 void report(std::ostream &os);
418 const BaseTimer* findBaseTimer(
const std::string &name)
const;
426 BaseTimer::TimeInfo findTimer(
const std::string &name,
bool&
found);
439 global_mpi_aggregation_called_(
false),
440 enable_verbose_(
false),
441 verbose_timestamp_levels_(0),
447 this->startBaseTimer();
449 auto check_verbose = std::getenv(
"TEUCHOS_ENABLE_VERBOSE_TIMERS");
451 enable_verbose_ =
true;
453 auto check_timestamp = std::getenv(
"TEUCHOS_ENABLE_VERBOSE_TIMESTAMP_LEVELS");
463 timer_.BaseTimer::start();
464#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOS)
465 ::Kokkos::Tools::pushRegion(timer_.get_full_name());
473 timer_.BaseTimer::stop();
474#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOS)
475 ::Kokkos::Tools::popRegion();
486 if (enable_timers_) {
488 top_ = timer_.start(name.c_str());
490 top_ = top_->start(name.c_str());
491#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOS)
493 ::Kokkos::Tools::pushRegion(name);
497 if (enable_verbose_) {
498 if (!verbose_timestamp_levels_) {
499 *verbose_ostream_ <<
"STARTING: " << name << std::endl;
503#if !defined(__GNUC__) || ( defined(__GNUC__) && (__GNUC__ > 4) )
504 else if (top_ !=
nullptr) {
505 if ( top_->level() <= verbose_timestamp_levels_) {
506 auto now = std::chrono::system_clock::now();
507 auto now_time = std::chrono::system_clock::to_time_t(
now);
509 auto timestamp = std::put_time(
gmt,
"%Y-%m-%d %H:%M:%S");
510 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000;
511 *verbose_ostream_ <<
"STARTING: " << name <<
" LEVEL: " << top_->level() <<
" COUNT: " << timer_.numCalls() <<
" TIMESTAMP: " <<
timestamp <<
"." <<
ms.count() << std::endl;
523 void stop(
const std::string &name,
525 if (enable_timers_) {
527 top_ = top_->stop(name);
529 timer_.BaseTimer::stop();
530#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOS)
532 ::Kokkos::Tools::popRegion();
536 if (enable_verbose_) {
537 if (!verbose_timestamp_levels_) {
538 *verbose_ostream_ <<
"STOPPING: " << name << std::endl;
542#if !defined(__GNUC__) || ( defined(__GNUC__) && (__GNUC__ > 4) )
544 else if (top_ !=
nullptr) {
545 if ( (top_->level()+1) <= verbose_timestamp_levels_) {
546 auto now = std::chrono::system_clock::now();
547 auto now_time = std::chrono::system_clock::to_time_t(
now);
549 auto timestamp = std::put_time(
gmt,
"%Y-%m-%d %H:%M:%S");
550 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000;
551 *verbose_ostream_ <<
"STOPPING: " << name <<
" LEVEL: " << top_->level()+1 <<
" COUNT: " << timer_.numCalls() <<
" TIMESTAMP: " <<
timestamp <<
"." <<
ms.count() << std::endl;
563 top_->incrementUpdates(
i);
573 return top_->accumulatedTime(name);
575 return timer_.accumulatedTime(name);
585 return top_->accumulatedTimePerUpdate(name);
587 return timer_.accumulatedTimePerUpdate(name);
596 return top_->accumulatedTimePerTimerCall(name);
598 return timer_.accumulatedTimePerTimerCall(name);
609 "StackedTimer::findBaseTimer() failed to find a timer named \"" << name <<
"\"!\n");
618 BaseTimer::TimeInfo
findTimer(
const std::string &name) {
622 "StackedTimer::findTimer() failed to find a timer named \"" << name <<
"\"!\n");
626 void report(std::ostream &os) {
644 OutputOptions() : output_fraction(
false), output_total_updates(
false), output_histogram(
false),
645 output_minmax(
false), output_proc_minmax(
false), num_histogram(10), max_levels(
INT_MAX),
646 print_warnings(
true), align_columns(
false), print_names_before_values(
true),
648 bool output_fraction;
649 bool output_total_updates;
650 bool output_histogram;
652 bool output_proc_minmax;
657 bool print_names_before_values;
717 void enableVerboseTimestamps(
const unsigned levels);
724 void disableTimers();
785 bool global_mpi_aggregation_called_;
789 std::string::size_type timer_names_;
790 std::string::size_type average_time_;
791 std::string::size_type fraction_;
792 std::string::size_type count_;
793 std::string::size_type total_updates_;
794 std::string::size_type min_;
795 std::string::size_type max_;
796 std::string::size_type procmin_;
797 std::string::size_type procmax_;
798 std::string::size_type stddev_;
799 std::string::size_type histogram_;
859 double printLevel(std::string
prefix,
int level, std::ostream &os, std::vector<bool> &
printed,
Templated array class derived from the STL std::vector.
Teuchos header file which uses auto-configuration information to include necessary C++ headers.
Reference-counted pointer class and non-member templated function implementations.
The basic timer used internally, uses std::chrono::high_resolution_clock.
void setAccumulatedTime(double accum=0)
Setter for accumulated time.
double difference(const BaseTimer &from) const
Return the difference between two timers in seconds,.
void reset()
Reset all the timer stats, throws if it is already running.
void start()
Start a currently stopped timer.
double accumulatedTimePerTimerCall() const
return the average time per timer start/stop
double accumulatedTimePerUpdate() const
return the average time per item updated
void stop()
Stop a current running timer and accumulate time difference.
void overrideNumUpdatesForUnitTesting(const unsigned long long num_updates)
Sets the number of counts for this timer. This is only used for unit testing.
double accumulatedTime() const
Get the total accumulated time since last reset or construction when the timer is running.
void overrideNumCallsForUnitTesting(const unsigned long num_calls)
Sets the number of calls to start() for this timer. This is only used for unit testing.
unsigned long long numUpdates() const
Returns the number of updates added to this timer.
unsigned long numCalls() const
Returns the number of calls to start().
unsigned long long incrementUpdates(unsigned long long count=1)
Increment the total number of items updated between a start stop.
bool running() const
Returns true if the timer is currently accumulating time.
Smart reference counting pointer class for automatic garbage collection.
Timer info at a given level and all the children.
double accumulatedTime(const std::string &locate_name="")
LevelTimer * start(const char *sub_name)
void splitString(const std::string &locate_name, std::string &first_name, std::string &second_name)
split a string into two parts split by a '@' if no '@' first gets the full string
double accumulatedTimePerTimerCall(const std::string &locate_name="")
LevelTimer(const LevelTimer &src)
Copy constructor.
LevelTimer * stop(const std::string &name="RootTimer")
unsigned level() const
Returns the level of the timer in the stack.
double accumulatedTimePerUpdate(const std::string &locate_name="")
std::string get_full_name() const
LevelTimer * unpack(unsigned from)
LevelTimer(int level, const char *name="RootTimer", LevelTimer *parent=nullptr, bool start_timer=true)
This class allows one to push and pop timers on and off a stack.
LevelTimer * top_
Current level running.
void start(const std::string name, const bool push_kokkos_profiling_region=true)
BaseTimer::TimeInfo findTimer(const std::string &name)
void stop(const std::string &name, const bool pop_kokkos_profiling_region=true)
const BaseTimer * findBaseTimer(const std::string &name) const
Teuchos::RCP< std::ostream > verbose_ostream_
For debugging, this is the ostream used for printing.
double accumulatedTimePerUpdate(const std::string &name="")
void incrementUpdates(const long long i=1)
bool enable_timers_
Used to disable timers for asynchronous work.
unsigned verbose_timestamp_levels_
If set to a value greater than 0, verbose mode will print that many levels of timers with timestamps....
double accumulatedTime(const std::string &name="")
LevelTimer timer_
Base timer.
bool enable_verbose_
If set to true, prints to the debug ostream. At construction, default value is set from environment v...
double accumulatedTimePerTimerCall(const std::string &name="")
StackedTimer(const char *name, const bool start_base_timer=true)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
void error_out(const std::string &msg, const bool)
Error reporting function for stacked timer.
Stores the column widths for output alignment.