10#include "Teuchos_StackedTimer.hpp"
20#include "Trilinos_git_sha.h"
38 for (
unsigned i=0;
i<level_; ++
i)
40 os << name_<<
":"<<
accumulatedTime()<<
" [" << count_started_<<
"] ("<< count_updates_ <<
")"<<std::endl;
42 for (
size_t i=0;
i<sub_timers_.size(); ++
i) {
43 t_total += sub_timers_[
i].accumulatedTime();
44 sub_timers_[
i].report(os);
46 if ( sub_timers_.size() == 0 )
48 for (
unsigned i=0;
i<=level_; ++
i)
57 if (get_full_name() == name) {
61 for (
unsigned i=0;
i<sub_timers_.size(); ++
i){
62 t = sub_timers_[
i].findBaseTimer(name);
72 BaseTimer::TimeInfo t;
78 if (get_full_name() == name) {
79 t = BaseTimer::TimeInfo(
this);
83 for (
unsigned i=0;
i<sub_timers_.size(); ++
i){
84 t = sub_timers_[
i].findTimer(name,
found);
129 if (
options.output_proc_minmax) {
135 if (
options.output_histogram ) {
136 hist_.resize(
options.num_histogram);
141 if (
options.output_per_proc_stddev) {
150 if (
options.output_total_updates)
155 if (
options.output_per_proc_stddev)
167 used[
i] = t.count==0? 0:1;
168 if (
options.output_total_updates)
169 updates[
i] = t.updates;
170 if (
options.output_per_proc_stddev)
188 if (procmin_.
size()) {
193 if (
used[
i] && (min_[
i]==time[
i]))
197 if (
used[
i] && (max_[
i]==time[
i]))
207 if (
options.output_histogram) {
210 double dh = (max_[
i]-min_[
i])/
options.num_histogram;
231 if (sum_sq_.
size()) {
237 if (
options.output_per_proc_stddev) {
244std::pair<std::string, std::string> getPrefix(
const std::string &name) {
245 for (std::size_t
i=name.size()-1;
i>0; --
i)
246 if (name[
i] ==
'@') {
247 return std::pair<std::string, std::string>(name.substr(0,
i), name.substr(
i+1));
249 return std::pair<std::string, std::string>(std::string(
""), name);
263 for (
int i=0;
i<flat_names_.
size(); ++
i ) {
264 if (sum_[
i]/active_[
i] <=
options.drop_time)
268 int level = std::count(flat_names_[
i].begin(), flat_names_[
i].end(),
'@');
277 std::ostringstream os;
278 for (
int l=0;
l<level; ++
l)
282 alignments_.timer_names_= std::max(alignments_.timer_names_,os.str().size());
287 std::ostringstream os;
288 os << sum_[
i]/active_[
i];
289 alignments_.average_time_ = std::max(alignments_.average_time_,os.str().size());
294 std::ostringstream os;
296 alignments_.fraction_ = std::max(alignments_.fraction_,os.str().size());
301 std::ostringstream os;
302 os <<
" ["<<count_[
i]/active_[
i]<<
"]";
303 alignments_.count_ = std::max(alignments_.count_,os.str().size());
307 if (
options.output_total_updates) {
308 std::ostringstream os;
309 os <<
" ("<<updates_[
i]/active_[
i]<<
")";
310 alignments_.total_updates_ = std::max(alignments_.total_updates_,os.str().size());
314 if (
options.output_minmax && active_[
i]>1) {
316 std::ostringstream os;
317 os <<
" {min=" << min_[
i];
318 alignments_.min_ = std::max(alignments_.min_,os.str().size());
321 std::ostringstream os;
322 os <<
", max=" << max_[
i];
325 alignments_.max_ = std::max(alignments_.max_,os.str().size());
327 if (procmin_.
size()) {
328 std::ostringstream os;
329 os <<
", proc min=" << procmin_[
i];
332 alignments_.procmin_ = std::min(alignments_.procmin_,os.str().size());
334 if (procmax_.
size()) {
335 std::ostringstream os;
336 os <<
", proc max=" << procmax_[
i];
339 alignments_.procmax_ = std::max(alignments_.procmax_,os.str().size());
342 std::ostringstream os;
343 os <<
", std dev=" <<
sqrt(std::max<double>(sum_sq_[
i]-sum_[
i]*sum_[
i]/active_[
i],0.0)/(active_[
i]-1));
345 alignments_.stddev_ = std::max(alignments_.stddev_,os.str().size());
349 if (
options.output_histogram && active_[
i] >1 ) {
350 std::ostringstream os;
354 os <<
", "<<hist_[
h][
i];
359 alignments_.histogram_ = std::max(alignments_.histogram_,os.str().size());
367 if (
options.print_names_before_values) {
368 std::ostringstream
tmp;
369 for (
int l=0;
l<=level; ++
l)
371 tmp <<
"Remainder: ";
372 alignments_.timer_names_ = std::max(alignments_.timer_names_,
tmp.str().size());
375 std::ostringstream
tmp;
377 alignments_.average_time_ = std::max(alignments_.average_time_,
tmp.str().size());
379 if (
options.output_fraction && (sum_[
i]/active_[
i] > 0.) ) {
380 std::ostringstream
tmp;
381 tmp <<
" - "<< (sum_[
i]/active_[
i]-
sub_time)/(sum_[
i]/active_[
i])*100 <<
"%";
382 alignments_.fraction_ = std::max(alignments_.fraction_,
tmp.str().size());
401 for (
int i=0;
i<flat_names_.
size(); ++
i ) {
402 if (sum_[
i]/active_[
i] <=
options.drop_time) {
407 int level = std::count(flat_names_[
i].begin(), flat_names_[
i].end(),
'@');
415 if (
options.print_names_before_values) {
416 std::ostringstream
tmp;
417 for (
int l=0;
l<level; ++
l) {
423 os << std::left << std::setw(alignments_.timer_names_);
428 std::ostringstream
tmp;
429 tmp << sum_[
i]/active_[
i];
431 os << std::left << std::setw(alignments_.average_time_);
436 std::ostringstream
tmp;
439 os << std::left << std::setw(alignments_.fraction_);
443 else if (
options.output_fraction) {
445 os << std::setw(alignments_.fraction_) <<
" ";
449 std::ostringstream
tmp;
450 tmp <<
" ["<<count_[
i]/active_[
i]<<
"]";
452 os << std::left << std::setw(alignments_.count_);
456 if (
options.output_total_updates ) {
457 std::ostringstream
tmp;
458 tmp <<
" ("<<updates_[
i]/active_[
i]<<
")";
460 os << std::left << std::setw(alignments_.total_updates_);
464 if (
options.output_minmax && active_[
i]>1) {
466 std::ostringstream
tmp;
467 tmp <<
" {min="<<min_[
i];
469 os << std::left << std::setw(alignments_.min_);
473 std::ostringstream
tmp;
474 tmp <<
", max="<<max_[
i];
478 os << std::left << std::setw(alignments_.max_);
481 if (procmin_.
size()) {
482 std::ostringstream
tmp;
483 tmp <<
", proc min="<<procmin_[
i];
487 os << std::left << std::setw(alignments_.procmin_);
490 if (procmax_.
size()) {
491 std::ostringstream
tmp;
492 tmp <<
", proc max="<<procmax_[
i];
496 os << std::left << std::setw(alignments_.procmax_);
500 std::ostringstream
tmp;
501 tmp <<
", std dev="<<
sqrt(std::max<double>(sum_sq_[
i]-sum_[
i]*sum_[
i]/active_[
i],0.0)/(active_[
i]-1));
504 os << std::left << std::setw(alignments_.stddev_);
508 else if (
options.output_minmax) {
510 size_t offset = alignments_.min_ + alignments_.max_ + alignments_.stddev_;
516 if (
options.output_histogram && active_[
i] >1 ) {
517 std::ostringstream
tmp;
521 tmp <<
", "<<hist_[
h][
i];
527 os << std::left << std::setw(alignments_.histogram_);
530 else if (
options.output_histogram) {
532 for (
size_t j=0;
j < alignments_.histogram_; ++
j)
536 if (
options.output_per_proc_stddev) {
537 std::ostringstream
tmp;
538 tmp <<
", std dev per proc min/max=";
539 tmp << per_proc_stddev_min_[
i];
541 tmp << per_proc_stddev_max_[
i];
545 if (!
options.print_names_before_values) {
546 std::ostringstream
tmp;
548 for (
int l=0;
l<level; ++
l) {
562 if (
options.print_names_before_values) {
563 std::ostringstream
tmp;
564 for (
int l=0;
l<=level; ++
l)
566 tmp <<
"Remainder: ";
568 os << std::left << std::setw(alignments_.timer_names_);
572 std::ostringstream
tmp;
575 os << std::left << std::setw(alignments_.average_time_);
578 if (
options.output_fraction && (sum_[
i]/active_[
i] > 0.) ) {
580 os << std::left << std::setw(alignments_.fraction_);
581 std::ostringstream
tmp;
582 tmp <<
" - "<< (sum_[
i]/active_[
i]-
sub_time)/(sum_[
i]/active_[
i])*100 <<
"%";
585 if (!
options.print_names_before_values) {
588 offset += alignments_.count_;
589 if (
options.output_total_updates)
590 offset += alignments_.total_updates_;
592 offset += alignments_.min_ + alignments_.max_ + alignments_.stddev_;
594 offset += alignments_.histogram_;
598 std::ostringstream
tmp;
600 for (
int l=0;
l<=level; ++
l)
602 tmp <<
"Remainder: ";
604 os << std::left << std::setw(alignments_.timer_names_);
614static void printXMLEscapedString(std::ostream& os,
const std::string&
str)
657 for (
int i=0;
i<flat_names_.
size(); ++
i) {
660 int level = std::count(flat_names_[
i].begin(), flat_names_[
i].end(),
'@');
667 for (
int j = 0;
j < indent;
j++)
669 os <<
"<timing name=\"";
671 printXMLEscapedString(os,
rootName);
674 os <<
"\" value=\"" << sum_[
i]/active_[
i] <<
"\"";
689 os <<
"<timing name=\"Remainder\" value=\"" << (sum_[
i]/active_[
i] -
sub_time) <<
"\"/>\n";
692 for (
int j = 0;
j < indent;
j++)
709 if (rank(*
comm) == 0 ) {
711 os <<
"*** Teuchos::StackedTimer::report() - Remainder for a level will be ***"
712 <<
"\n*** incorrect if a timer in the level does not exist on every rank ***"
713 <<
"\n*** of the MPI Communicator. ***"
717 os <<
"Teuchos::StackedTimer::report() - max_levels manually set to " <<
options.max_levels
718 <<
". \nTo print more levels, increase value of OutputOptions::max_levels." << std::endl;
720 if ( (!
options.print_names_before_values) && (!
options.align_columns)) {
723 os <<
"Teuchos::StackedTimer::report() - option print_names_before_values=false "
724 <<
"\nrequires that the option align_columns=true too. Setting the value for "
725 <<
"\nalign_column to true."
729 std::vector<bool>
printed(flat_names_.
size(),
false);
733 std::vector<bool>
printed(flat_names_.
size(),
false);
743 if (rank(*
comm) == 0 ) {
744 std::vector<bool>
printed(flat_names_.
size(),
false);
745 os <<
"<?xml version=\"1.0\"?>\n";
746 os <<
"<performance-report date=\"" <<
timestamp <<
"\" name=\"nightly_run_" <<
datestamp <<
"\" time-units=\"seconds\">\n";
748 os <<
"</performance-report>\n";
756 std::string
gitSHA(Trilinos::TRILINOS_GIT_SHA);
784 throw std::invalid_argument(
"$WATCHR_BUILD_DATE has invalid year or is not in YYYY_MM_DD format.");
786 throw std::invalid_argument(
"$WATCHR_BUILD_DATE has invalid month or is not in YYYY_MM_DD format.");
788 throw std::invalid_argument(
"$WATCHR_BUILD_DATE has invalid day or is not in YYYY_MM_DD format.");
808 if(rank(*
comm) == 0) {
829 std::vector<bool>
printed(flat_names_.
size(),
false);
830 os <<
"<?xml version=\"1.0\"?>\n";
831 os <<
"<performance-report date=\"" <<
timestamp <<
"\" name=\"nightly_run_" <<
datestamp <<
"\" time-units=\"seconds\">\n";
834 os <<
" <metadata key=\"Trilinos Version\" value=\"" <<
gitSHA <<
"\"/>\n";
836 auto systemInfo = SystemInformation::collectSystemInformation();
838 os <<
" <metadata key=\"" <<
e.first <<
"\" value=\"";
839 printXMLEscapedString(os,
e.second);
843 os <<
"</performance-report>\n";
868 global_mpi_aggregation_called_ =
true;
874 return sum_[
i] / active_[
i];
880 return static_cast<double>(count_[
i]) /
static_cast<double>(active_[
i]);
886 "ERROR: StackedTimer::getAverageMpiTime() - must call aggregateMpiData() first!");
891 "ERROR: StackedTimer::getAverageMpiTime() - the timer named \""
895 return static_cast<int>(
i);
901 "ERROR: StackedTimer::isTimer() - must call aggregateMpiData() before using this query!");
912 const std::string name =
top_->get_name();
937 this->
start(timers_to_start.top());
T * getRawPtr()
Return a raw pointer to beginning of array or NULL if unsized.
void resize(size_type new_size, const value_type &x=value_type())
The basic timer used internally, uses std::chrono::high_resolution_clock.
bool running() const
Returns true if the timer is currently accumulating time.
Smart reference counting pointer class for automatic garbage collection.
T * getRawPtr() const
Get the raw C++ pointer to the underlying object.
void report(std::ostream &os)
BaseTimer::TimeInfo findTimer(const std::string &name, bool &found)
const BaseTimer * findBaseTimer(const std::string &name) const
unsigned level() const
Returns the level of the timer in the stack.
LevelTimer()
Default constructor, shouldn't be used but needed for std::vector.
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)
double getMpiAverageTime(const std::string &flat_timer_name)
void start(const std::string name, const bool push_kokkos_profiling_region=true)
void stop(const std::string &name, const bool pop_kokkos_profiling_region=true)
void startBaseTimer(const bool push_kokkos_profiling_region=true)
void stopBaseTimer(const bool pop_kokkos_profiling_region=true)
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.
void startTimers(std::stack< std::string > timers_to_start)
int getFlatNameIndex(const std::string &flat_timer_name)
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...
void aggregateMpiData(Teuchos::RCP< const Teuchos::Comm< int > > comm, OutputOptions options=OutputOptions())
std::stack< std::string > stopAllTimers()
void merge(Teuchos::RCP< const Teuchos::Comm< int > > comm)
bool isTimer(const std::string &flat_timer_name)
double printLevel(std::string prefix, int level, std::ostream &os, std::vector< bool > &printed, double parent_time, const OutputOptions &options)
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)
double getMpiAverageCount(const std::string &flat_timer_name)
void reportXML(std::ostream &os, const std::string &datestamp, const std::string ×tamp, Teuchos::RCP< const Teuchos::Comm< int > > comm)
#define TEUCHOS_ASSERT(assertion_test)
This macro is throws when an assert fails.
#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 mergeCounterNames(const Comm< int > &comm, const Array< std::string > &localNames, Array< std::string > &globalNames, const ECounterSetOp setOp)
Merge counter names over all processors.
void error_out(const std::string &msg, const bool)
Error reporting function for stacked timer.