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,