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"
20 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
23 extern void pushRegion (
const std::string&);
24 extern void popRegion ();
33 void error_out(
const std::string& msg,
const bool fail_all =
false);
48 using Clock = std::chrono::high_resolution_clock;
50 BaseTimer() : accumulation_(0.0), count_started_(0), count_updates_(0), running_(
false) {}
55 error_out(
"Base_Timer:start Failed timer already running");
56 start_time_ = Clock::now();
65 error_out(
"Base_Timer:stop Failed timer not running");
66 accumulation_ += std::chrono::duration_cast<std::chrono::duration<double>>(Clock::now() - start_time_).count();
71 unsigned long incrementCount(
unsigned long count=1) {count_updates_ += count;
return count_updates_;}
88 if (count_updates_ > 0) {
89 return accumulation_/count_updates_;
104 if (count_started_> 0) {
105 return accumulation_/count_started_;
118 return accumulation_ - from.accumulation_;
124 error_out(
"BaseTimer, cannot reset a running timer");
126 count_started_ = count_updates_ = 0;
129 unsigned long totalUpdates()
const {
return count_updates_;}
131 bool running()
const {
return running_;}
134 TimeInfo():time(0.0), count(0), updates(0), running(false){}
135 TimeInfo(BaseTimer* t): time(t->accumulation_), count(t->count_started_), updates(t->count_updates_), running(t->running()) {}
138 unsigned long long updates;
143 double accumulation_;
144 unsigned long count_started_;
145 unsigned long long count_updates_;
146 Clock::time_point start_time_;
149 friend struct TimeInfo;
189 std::vector<LevelTimer> sub_timers_;
202 const char* name =
"RootTimer",
204 bool start_timer=
true) :
217 BaseTimer(src), level_(src.level_), name_(src.name_),parent_(src.parent_), sub_timers_(src.sub_timers_)
219 for (
unsigned i=0;i<sub_timers_.size();++i)
220 sub_timers_[i].parent_ =
this;
229 for (
unsigned i=0;i<sub_timers_.size();i++ )
230 if (sub_name == sub_timers_[i].name_ ) {
231 sub_timers_[i].BaseTimer::start();
232 return &sub_timers_[i];
234 sub_timers_.push_back(
LevelTimer(level_+1,sub_name,
this,
true));
235 return &sub_timers_[sub_timers_.size()-1];
247 error_out(
"Stopping timer "+name+
" But top level running timer is "+name_);
258 std::string parent_name(
"");
259 if ((parent_ != NULL) && (parent_->level_ > 0))
262 std::string my_name(name_);
264 std::string full_name = parent_name + my_name;
275 for (
unsigned i=0;i<sub_timers_.size(); ++i)
282 for (
unsigned i=0;i<sub_timers_.size(); ++i)
283 sub_timers_[i].addTimerNames(names, pos);
293 if (locate_name ==
"")
296 std::string first_name,second_name;
298 size_t i = locate_name.find_first_of(
'@');
299 if ( i >= locate_name.size() ) {
300 first_name = locate_name;
303 first_name.assign(locate_name,0,i);
304 second_name.assign(locate_name,i+1,locate_name.size()-i-1);
306 for (
unsigned j=0;j<sub_timers_.size();++j)
307 if ( first_name == sub_timers_[j].name_)
308 return sub_timers_[j].accumulatedTime(second_name);
319 void splitString(
const std::string &locate_name, std::string &first_name, std::string &second_name) {
320 size_t i = locate_name.find_first_of(
'@');
321 if ( i >= locate_name.size() ) {
322 first_name = locate_name;
325 first_name.assign(locate_name,0,i);
326 second_name.assign(locate_name,i+1,locate_name.size()-i-1);
338 if (locate_name ==
"")
341 std::string first_name,second_name;
344 for (
unsigned j=0;j<sub_timers_.size();j++)
345 if ( first_name == sub_timers_[j].name_)
346 return sub_timers_[j].accumulatedTimePerUpdate(second_name);
357 if (locate_name ==
"")
360 std::string first_name,second_name;
363 for (
unsigned j=0;j<sub_timers_.size();j++)
364 if ( first_name == sub_timers_[j].name_)
365 return sub_timers_[j].accumulatedTimePerTimerCall(second_name);
385 void report(std::ostream &os);
393 BaseTimer::TimeInfo
findTimer(
const std::string &name,
bool& found);
414 timer_.BaseTimer::start();
415 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
416 ::Kokkos::Profiling::pushRegion(
"ANONYMOUS");
423 void start(
const std::string name) {
428 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
429 ::Kokkos::Profiling::pushRegion(name);
436 void stop(
const std::string &name =
"RootTimer") {
440 timer_.BaseTimer::stop( );
441 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
442 ::Kokkos::Profiling::popRegion();
494 BaseTimer::TimeInfo
findTimer(
const std::string &name) {
495 bool foundTimer =
false;
498 "StackedTimer::findTimer() failed to find a timer named \"" << name <<
"\"!\n");
502 void report(std::ostream &os) {
508 OutputOptions() : output_fraction(
false), output_total_updates(
false), output_histogram(
false),
509 output_minmax(
false), num_histogram(10), max_levels(INT_MAX),
510 print_warnings(
true) {}
511 bool output_fraction;
512 bool output_total_updates;
513 bool output_histogram;
563 double printLevel(std::string prefix,
int level, std::ostream &os, std::vector<bool> &printed,