40#ifndef TEUCHOS_STACKED_TIMER_HPP
41#define TEUCHOS_STACKED_TIMER_HPP
44#include "Teuchos_Comm.hpp"
45#include "Teuchos_DefaultComm.hpp"
46#include "Teuchos_CommHelpers.hpp"
59#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
62extern void pushRegion (
const std::string&);
63extern void popRegion ();
72void error_out(
const std::string& msg,
const bool fail_all =
false);
87 using Clock = std::chrono::high_resolution_clock;
89 BaseTimer() : accumulation_(0.0), count_started_(0), count_updates_(0), running_(
false) {}
94 error_out(
"Base_Timer:start Failed timer already running");
95 start_time_ = Clock::now();
104 error_out(
"Base_Timer:stop Failed timer not running");
105 accumulation_ += std::chrono::duration_cast<std::chrono::duration<double>>(Clock::now() - start_time_).count();
110 unsigned long long incrementUpdates(
unsigned long long count=1) {count_updates_ += count;
return count_updates_;}
127 if (count_updates_ > 0) {
128 return accumulation_/count_updates_;
143 if (count_started_> 0) {
144 return accumulation_/count_started_;
157 return accumulation_ - from.accumulation_;
163 error_out(
"BaseTimer, cannot reset a running timer");
165 count_started_ = count_updates_ = 0;
172 unsigned long numCalls()
const {
return count_started_; }
175 unsigned long long numUpdates()
const {
return count_updates_; }
179 { count_started_ = num_calls; }
183 { count_updates_ = num_updates; }
186 TimeInfo():time(0.0), count(0), updates(0), running(false){}
187 TimeInfo(BaseTimer* t): time(t->accumulation_), count(t->count_started_), updates(t->count_updates_), running(t->running()) {}
190 unsigned long long updates;
195 double accumulation_;
196 unsigned long count_started_;
197 unsigned long long count_updates_;
198 Clock::time_point start_time_;
201 friend struct TimeInfo;
241 std::vector<LevelTimer> sub_timers_;
254 const char* name =
"RootTimer",
256 bool start_timer=
true) :
269 BaseTimer(src), level_(src.level_), name_(src.name_),parent_(src.parent_), sub_timers_(src.sub_timers_)
271 for (
unsigned i=0;i<sub_timers_.size();++i)
272 sub_timers_[i].parent_ =
this;
281 for (
unsigned i=0;i<sub_timers_.size();i++ )
282 if (sub_name == sub_timers_[i].name_ ) {
283 sub_timers_[i].BaseTimer::start();
284 return &sub_timers_[i];
286 sub_timers_.push_back(
LevelTimer(level_+1,sub_name,
this,
true));
287 return &sub_timers_[sub_timers_.size()-1];
299 error_out(
"Stopping timer "+name+
" But top level running timer is "+name_);
310 std::string parent_name(
"");
311 if ((parent_ !=
nullptr))
314 std::string my_name(name_);
316 std::string full_name = parent_name + my_name;
327 for (
unsigned i=0;i<sub_timers_.size(); ++i)
334 for (
unsigned i=0;i<sub_timers_.size(); ++i)
335 sub_timers_[i].addTimerNames(names, pos);
345 if (locate_name ==
"")
348 std::string first_name,second_name;
350 size_t i = locate_name.find_first_of(
'@');
351 if ( i >= locate_name.size() ) {
352 first_name = locate_name;
355 first_name.assign(locate_name,0,i);
356 second_name.assign(locate_name,i+1,locate_name.size()-i-1);
358 for (
unsigned j=0;j<sub_timers_.size();++j)
359 if ( first_name == sub_timers_[j].name_)
360 return sub_timers_[j].accumulatedTime(second_name);
375 void splitString(
const std::string &locate_name, std::string &first_name, std::string &second_name) {
376 size_t i = locate_name.find_first_of(
'@');
377 if ( i >= locate_name.size() ) {
378 first_name = locate_name;
381 first_name.assign(locate_name,0,i);
382 second_name.assign(locate_name,i+1,locate_name.size()-i-1);
394 if (locate_name ==
"")
397 std::string first_name,second_name;
400 for (
unsigned j=0;j<sub_timers_.size();j++)
401 if ( first_name == sub_timers_[j].name_)
402 return sub_timers_[j].accumulatedTimePerUpdate(second_name);
413 if (locate_name ==
"")
416 std::string first_name,second_name;
419 for (
unsigned j=0;j<sub_timers_.size();j++)
420 if ( first_name == sub_timers_[j].name_)
421 return sub_timers_[j].accumulatedTimePerTimerCall(second_name);
441 void report(std::ostream &os);
456 BaseTimer::TimeInfo
findTimer(
const std::string &name,
bool& found);
472 explicit StackedTimer(
const char *name,
const bool start_base_timer =
true)
473 :
timer_(0,name,nullptr,false),
480 if (start_base_timer)
483 auto check_verbose = std::getenv(
"TEUCHOS_ENABLE_VERBOSE_TIMERS");
484 if (check_verbose !=
nullptr)
487 auto check_timestamp = std::getenv(
"TEUCHOS_ENABLE_VERBOSE_TIMESTAMP_LEVELS");
488 if (check_timestamp !=
nullptr) {
497 timer_.BaseTimer::start();
498#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
508#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
509 ::Kokkos::Profiling::popRegion();
519 const bool push_kokkos_profiling_region =
true) {
525#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
526 if (push_kokkos_profiling_region) {
527 ::Kokkos::Profiling::pushRegion(name);
537#if !defined(__GNUC__) || ( defined(__GNUC__) && (__GNUC__ > 4) )
538 else if (
top_ !=
nullptr) {
540 auto now = std::chrono::system_clock::now();
541 auto now_time = std::chrono::system_clock::to_time_t(now);
542 auto gmt = gmtime(&now_time);
543 auto timestamp = std::put_time(gmt,
"%Y-%m-%d %H:%M:%S");
544 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
557 void stop(
const std::string &name,
558 const bool pop_kokkos_profiling_region =
true) {
564#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
565 if (pop_kokkos_profiling_region) {
566 ::Kokkos::Profiling::popRegion();
576#if !defined(__GNUC__) || ( defined(__GNUC__) && (__GNUC__ > 4) )
578 else if (
top_ !=
nullptr) {
580 auto now = std::chrono::system_clock::now();
581 auto now_time = std::chrono::system_clock::to_time_t(now);
582 auto gmt = gmtime(&now_time);
583 auto timestamp = std::put_time(gmt,
"%Y-%m-%d %H:%M:%S");
584 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
643 "StackedTimer::findBaseTimer() failed to find a timer named \"" << name <<
"\"!\n");
652 BaseTimer::TimeInfo
findTimer(
const std::string &name) {
653 bool foundTimer =
false;
656 "StackedTimer::findTimer() failed to find a timer named \"" << name <<
"\"!\n");
660 void report(std::ostream &os) {
678 OutputOptions() : output_fraction(
false), output_total_updates(
false), output_histogram(
false),
679 output_minmax(
false), output_proc_minmax(
false), num_histogram(10), max_levels(INT_MAX),
680 print_warnings(
true), align_columns(
false), print_names_before_values(
true),
682 bool output_fraction;
683 bool output_total_updates;
684 bool output_histogram;
686 bool output_proc_minmax;
691 bool print_names_before_values;
783 std::string::size_type timer_names_;
784 std::string::size_type average_time_;
785 std::string::size_type fraction_;
786 std::string::size_type count_;
787 std::string::size_type total_updates_;
788 std::string::size_type min_;
789 std::string::size_type max_;
790 std::string::size_type procmin_;
791 std::string::size_type procmax_;
792 std::string::size_type stddev_;
793 std::string::size_type histogram_;
842 std::vector<bool> &printed,
double parent_time,
848 double printLevel(std::string prefix,
int level, std::ostream &os, std::vector<bool> &printed,
855 double printLevelXML(std::string prefix,
int level, std::ostream &os, std::vector<bool> &printed,
double parent_time,
const std::string& rootName =
"");
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.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
the basic timer used elsewhere, uses MPI_Wtime for time
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.
Abstract interface for distributed-memory communication.
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 report(std::ostream &os)
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.
BaseTimer::TimeInfo findTimer(const std::string &name, bool &found)
const BaseTimer * findBaseTimer(const std::string &name) const
LevelTimer * stop(const std::string &name="RootTimer")
unsigned level() const
Returns the level of the timer in the stack.
LevelTimer()
Default constructor, shouldn't be used but needed for std::vector.
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.
double computeColumnWidthsForAligment(std::string prefix, int print_level, std::vector< bool > &printed, double parent_time, const OutputOptions &options)
void collectRemoteData(Teuchos::RCP< const Teuchos::Comm< int > > comm, const OutputOptions &options)
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 printLevelXML(std::string prefix, int level, std::ostream &os, std::vector< bool > &printed, double parent_time, const std::string &rootName="")
void enableVerboseTimestamps(const unsigned levels)
Enable timestamps in verbose mode for the number of levels specified.
double accumulatedTimePerUpdate(const std::string &name="")
void incrementUpdates(const long long i=1)
void setVerboseOstream(const Teuchos::RCP< std::ostream > &os)
Set the ostream for verbose mode(defaults to std::cout).
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="")
void merge(Teuchos::RCP< const Teuchos::Comm< int > > comm)
double printLevel(std::string prefix, int level, std::ostream &os, std::vector< bool > &printed, double parent_time, const OutputOptions &options)
StackedTimer(const char *name, const bool start_base_timer=true)
void enableVerbose(const bool enable_verbose)
If set to true, print timer start/stop to verbose ostream.
std::string reportWatchrXML(const std::string &name, Teuchos::RCP< const Teuchos::Comm< int > > comm)
void reportXML(std::ostream &os, const std::string &datestamp, const std::string ×tamp, Teuchos::RCP< const Teuchos::Comm< int > > comm)
#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.