4 #ifndef TEUCHOS_STACKED_TIMER_HPP 
    5 #define TEUCHOS_STACKED_TIMER_HPP 
    8 #include "Teuchos_Comm.hpp" 
    9 #include "Teuchos_DefaultComm.hpp" 
   10 #include "Teuchos_CommHelpers.hpp" 
   22 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE) 
   25 extern void pushRegion (
const std::string&);
 
   26 extern void popRegion ();
 
   35 void error_out(
const std::string& msg, 
const bool fail_all = 
false);
 
   50   using Clock = std::chrono::high_resolution_clock;
 
   52   BaseTimer() : accumulation_(0.0), count_started_(0), count_updates_(0), running_(
false) {}
 
   57       error_out(
"Base_Timer:start Failed timer already running");
 
   58     start_time_ = Clock::now();
 
   67       error_out(
"Base_Timer:stop Failed timer not running");
 
   68     accumulation_ += std::chrono::duration_cast<std::chrono::duration<double>>(Clock::now() - start_time_).count();
 
   73   unsigned long long incrementUpdates(
unsigned long long count=1) {count_updates_ += count; 
return count_updates_;}
 
   90     if (count_updates_ > 0) {
 
   91       return accumulation_/count_updates_;
 
  106     if (count_started_> 0) {
 
  107       return accumulation_/count_started_;
 
  120     return accumulation_ - from.accumulation_;
 
  126        error_out(
"BaseTimer, cannot reset a running timer");
 
  128     count_started_ = count_updates_ = 0;
 
  135   unsigned long numCalls()
 const { 
return count_started_; }
 
  138   unsigned long long numUpdates()
 const { 
return count_updates_; }
 
  142   { count_started_ = num_calls; }
 
  146   { count_updates_ = num_updates; }
 
  149     TimeInfo():time(0.0), count(0), updates(0), 
running(false){}
 
  150     TimeInfo(BaseTimer* t): time(t->accumulation_), count(t->count_started_), updates(t->count_updates_), 
running(t->
running()) {}
 
  153     unsigned long long updates;
 
  158   double accumulation_;       
 
  159   unsigned long count_started_; 
 
  160   unsigned long long count_updates_; 
 
  161   Clock::time_point start_time_;
 
  164   friend struct TimeInfo;
 
  204     std::vector<LevelTimer> sub_timers_;
 
  217         const char* name = 
"RootTimer",
 
  219         bool start_timer=
true) :
 
  232       BaseTimer(src), level_(src.level_), name_(src.name_),parent_(src.parent_), sub_timers_(src.sub_timers_)
 
  234       for (
unsigned i=0;i<sub_timers_.size();++i)
 
  235         sub_timers_[i].parent_ = 
this;
 
  244       for (
unsigned i=0;i<sub_timers_.size();i++ )
 
  245         if (sub_name == sub_timers_[i].name_ ) {
 
  246           sub_timers_[i].BaseTimer::start();
 
  247           return &sub_timers_[i];
 
  249       sub_timers_.push_back(
LevelTimer(level_+1,sub_name,
this,
true));
 
  250       return &sub_timers_[sub_timers_.size()-1];
 
  262         error_out(
"Stopping timer "+name+
" But top level running timer is "+name_);
 
  273       std::string parent_name(
"");
 
  274       if ((parent_ != 
nullptr))
 
  277       std::string my_name(name_);
 
  279       std::string full_name = parent_name + my_name;
 
  290       for (
unsigned i=0;i<sub_timers_.size(); ++i)
 
  297       for (
unsigned i=0;i<sub_timers_.size(); ++i)
 
  298         sub_timers_[i].addTimerNames(names, pos);
 
  308       if (locate_name == 
"")
 
  311       std::string first_name,second_name;
 
  313       size_t i = locate_name.find_first_of(
'@');
 
  314       if ( i >= locate_name.size() ) {
 
  315         first_name = locate_name;
 
  318         first_name.assign(locate_name,0,i);
 
  319         second_name.assign(locate_name,i+1,locate_name.size()-i-1);
 
  321       for (
unsigned j=0;j<sub_timers_.size();++j)
 
  322         if ( first_name == sub_timers_[j].name_)
 
  323           return sub_timers_[j].accumulatedTime(second_name);
 
  334     void splitString(
const std::string &locate_name, std::string &first_name, std::string &second_name) {
 
  335       size_t i = locate_name.find_first_of(
'@');
 
  336       if ( i >= locate_name.size() ) {
 
  337         first_name = locate_name;
 
  340         first_name.assign(locate_name,0,i);
 
  341         second_name.assign(locate_name,i+1,locate_name.size()-i-1);
 
  353        if (locate_name == 
"")
 
  356        std::string first_name,second_name;
 
  359        for (
unsigned j=0;j<sub_timers_.size();j++)
 
  360          if ( first_name == sub_timers_[j].name_)
 
  361            return sub_timers_[j].accumulatedTimePerUpdate(second_name);
 
  372        if (locate_name == 
"")
 
  375        std::string first_name,second_name;
 
  378        for (
unsigned j=0;j<sub_timers_.size();j++)
 
  379          if ( first_name == sub_timers_[j].name_)
 
  380            return sub_timers_[j].accumulatedTimePerTimerCall(second_name);
 
  400      void report(std::ostream &os);
 
  415     BaseTimer::TimeInfo 
findTimer(
const std::string &name,
bool& found);
 
  431   explicit StackedTimer(
const char *name, 
const bool start_base_timer = 
true)
 
  432     : 
timer_(0,name,nullptr,false),
 
  437     if (start_base_timer)
 
  440     auto check_verbose = std::getenv(
"TEUCHOS_ENABLE_VERBOSE_TIMERS");
 
  441     if (check_verbose != 
nullptr)
 
  449     timer_.BaseTimer::start();
 
  450 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE) 
  460 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE) 
  461     ::Kokkos::Profiling::popRegion();
 
  471              const bool push_kokkos_profiling_region = 
true) {
 
  476 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE) 
  477     if (push_kokkos_profiling_region) {
 
  478       ::Kokkos::Profiling::pushRegion(name);
 
  490   void stop(
const std::string &name,
 
  491             const bool pop_kokkos_profiling_region = 
true) {
 
  496 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE) 
  497     if (pop_kokkos_profiling_region) {
 
  498       ::Kokkos::Profiling::popRegion();
 
  556                                "StackedTimer::findBaseTimer() failed to find a timer named \"" << name << 
"\"!\n");
 
  565   BaseTimer::TimeInfo 
findTimer(
const std::string &name) {
 
  566     bool foundTimer = 
false;
 
  569       "StackedTimer::findTimer() failed to find a timer named \"" << name << 
"\"!\n");
 
  573   void report(std::ostream &os) {
 
  579     OutputOptions() : output_fraction(
false), output_total_updates(
false), output_histogram(
false),
 
  580                       output_minmax(
false), num_histogram(10), max_levels(INT_MAX),
 
  581                       print_warnings(
true), align_columns(
false), print_names_before_values(
true) {}
 
  582     bool output_fraction;
 
  583     bool output_total_updates;
 
  584     bool output_histogram;
 
  590     bool print_names_before_values;
 
  602   void enableVerbose(
const bool enable_verbose);
 
  625     std::string::size_type timer_names_;
 
  626     std::string::size_type average_time_;
 
  627     std::string::size_type fraction_;
 
  628     std::string::size_type count_;
 
  629     std::string::size_type total_updates_;
 
  630     std::string::size_type min_;
 
  631     std::string::size_type max_;
 
  632     std::string::size_type stddev_;
 
  633     std::string::size_type histogram_;
 
  675                                         std::vector<bool> &printed, 
double parent_time,
 
  681   double printLevel(std::string prefix, 
int level, std::ostream &os, std::vector<bool> &printed,
 
void setAccumulatedTime(double accum=0)
Setter for accumulated time. 
 
double accumulatedTimePerTimerCall(const std::string &name="")
 
double difference(const BaseTimer &from) const 
Return the difference between two timers in seconds,. 
 
StackedTimer(const char *name, const bool start_base_timer=true)
 
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 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 ...
 
void stop(const std::string &name, const bool pop_kokkos_profiling_region=true)
 
LevelTimer(int level, const char *name="RootTimer", LevelTimer *parent=nullptr, bool start_timer=true)
 
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. 
 
double accumulatedTimePerTimerCall() const 
return the average time per timer start/stop 
 
void merge(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. 
 
double accumulatedTimePerUpdate() const 
return the average time per item updated 
 
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
 
bool enable_verbose_
If set to true, prints to the debug ostream. At construction, default value is set from environment v...
 
void incrementUpdates(const long long i=1)
 
void start()
Start a currently stopped timer. 
 
LevelTimer * top_
Current level running. 
 
double accumulatedTimePerUpdate(const std::string &name="")
 
unsigned long numCalls() const 
Returns the number of calls to start(). 
 
BaseTimer::TimeInfo findTimer(const std::string &name, bool &found)
 
double printLevel(std::string prefix, int level, std::ostream &os, std::vector< bool > &printed, double parent_time, const OutputOptions &options)
 
LevelTimer * unpack(unsigned from)
 
double accumulatedTime(const std::string &name="")
 
void start(const std::string name, const bool push_kokkos_profiling_region=true)
 
double accumulatedTime(const std::string &locate_name="")
 
void report(std::ostream &os)
 
void overrideNumCallsForUnitTesting(const unsigned long num_calls)
Sets the number of calls to start() for this timer. This is only used for unit testing. 
 
the basic timer used elsewhere, uses MPI_Wtime for time 
 
double computeColumnWidthsForAligment(std::string prefix, int print_level, std::vector< bool > &printed, double parent_time, const OutputOptions &options)
 
Stores the column widths for output alignment. 
 
void collectRemoteData(Teuchos::RCP< const Teuchos::Comm< int > > comm, const OutputOptions &options)
 
LevelTimer(const LevelTimer &src)
Copy constructor. 
 
Timer info at a given level and all the children. 
 
const BaseTimer * findBaseTimer(const std::string &name) const 
 
double accumulatedTimePerUpdate(const std::string &locate_name="")
 
Teuchos::RCP< std::ostream > verbose_ostream_
For debugging, this is the ostream used for printing. 
 
LevelTimer timer_
Base timer. 
 
double accumulatedTimePerTimerCall(const std::string &locate_name="")
 
Templated array class derived from the STL std::vector. 
 
void error_out(const std::string &msg, const bool)
Error reporting function for stacked timer. 
 
Abstract interface for distributed-memory communication. 
 
LevelTimer * stop(const std::string &name="RootTimer")
 
void reset()
Reset all the timer stats, throws if it is already running. 
 
void stop()
Stop a current running timer and accumulate time difference. 
 
LevelTimer()
Default constructor, shouldn't be used but needed for std::vector. 
 
const BaseTimer * findBaseTimer(const std::string &name) const 
 
Smart reference counting pointer class for automatic garbage collection. 
 
BaseTimer::TimeInfo findTimer(const std::string &name)
 
This class allows one to push and pop timers on and off a stack. 
 
unsigned long long numUpdates() const 
Returns the number of updates added to this timer. 
 
Struct for controlling output options like histograms. 
 
Reference-counted pointer class and non-member templated function implementations. 
 
LevelTimer * start(const char *sub_name)
 
std::string get_full_name() const