10#include "Teuchos_StackedTimer.hpp"
35 for (
unsigned i=0;
i<level_; ++
i)
37 os << name_<<
":"<<
accumulatedTime()<<
" [" << count_started_<<
"] ("<< count_updates_ <<
")"<<std::endl;
39 for (
size_t i=0;
i<sub_timers_.size(); ++
i) {
40 t_total += sub_timers_[
i].accumulatedTime();
41 sub_timers_[
i].report(os);
43 if ( sub_timers_.size() == 0 )
45 for (
unsigned i=0;
i<=level_; ++
i)
54 if (get_full_name() == name) {
58 for (
unsigned i=0;
i<sub_timers_.size(); ++
i){
59 t = sub_timers_[
i].findBaseTimer(name);
69 BaseTimer::TimeInfo t;
75 if (get_full_name() == name) {
76 t = BaseTimer::TimeInfo(
this);
80 for (
unsigned i=0;
i<sub_timers_.size(); ++
i){
81 t = sub_timers_[
i].findTimer(name,
found);
126 if (
options.output_proc_minmax) {
132 if (
options.output_histogram ) {
133 hist_.resize(
options.num_histogram);
138 if (
options.output_per_proc_stddev) {
147 if (
options.output_total_updates)
152 if (
options.output_per_proc_stddev)
164 used[
i] = t.count==0? 0:1;
165 if (
options.output_total_updates)
166 updates[
i] = t.updates;
167 if (
options.output_per_proc_stddev)
185 if (procmin_.
size()) {
190 if (
used[
i] && (min_[
i]==time[
i]))
194 if (
used[
i] && (max_[
i]==time[
i]))
204 if (
options.output_histogram) {
207 double dh = (max_[
i]-min_[
i])/
options.num_histogram;
228 if (sum_sq_.
size()) {
234 if (
options.output_per_proc_stddev) {
241std::pair<std::string, std::string> getPrefix(
const std::string &name) {
242 for (std::size_t
i=name.size()-1;
i>0; --
i)
243 if (name[
i] ==
'@') {
244 return std::pair<std::string, std::string>(name.substr(0,
i), name.substr(
i+1));
246 return std::pair<std::string, std::string>(std::string(
""), name);
260 for (
int i=0;
i<flat_names_.
size(); ++
i ) {
261 if (sum_[
i]/active_[
i] <=
options.drop_time)
265 int level = std::count(flat_names_[
i].begin(), flat_names_[
i].end(),
'@');
274 std::ostringstream os;
275 for (
int l=0;
l<level; ++
l)
279 alignments_.timer_names_= std::max(alignments_.timer_names_,os.str().size());
284 std::ostringstream os;
285 os << sum_[
i]/active_[
i];
286 alignments_.average_time_ = std::max(alignments_.average_time_,os.str().size());
291 std::ostringstream os;
293 alignments_.fraction_ = std::max(alignments_.fraction_,os.str().size());
298 std::ostringstream os;
299 os <<
" ["<<count_[
i]/active_[
i]<<
"]";
300 alignments_.count_ = std::max(alignments_.count_,os.str().size());
304 if (
options.output_total_updates) {
305 std::ostringstream os;
306 os <<
" ("<<updates_[
i]/active_[
i]<<
")";
307 alignments_.total_updates_ = std::max(alignments_.total_updates_,os.str().size());
311 if (
options.output_minmax && active_[
i]>1) {
313 std::ostringstream os;
314 os <<
" {min=" << min_[
i];
315 alignments_.min_ = std::max(alignments_.min_,os.str().size());
318 std::ostringstream os;
319 os <<
", max=" << max_[
i];
322 alignments_.max_ = std::max(alignments_.max_,os.str().size());
324 if (procmin_.
size()) {
325 std::ostringstream os;
326 os <<
", proc min=" << procmin_[
i];
329 alignments_.procmin_ = std::min(alignments_.procmin_,os.str().size());
331 if (procmax_.
size()) {
332 std::ostringstream os;
333 os <<
", proc max=" << procmax_[
i];
336 alignments_.procmax_ = std::max(alignments_.procmax_,os.str().size());
339 std::ostringstream os;
340 os <<
", std dev=" <<
sqrt(std::max<double>(sum_sq_[
i]-sum_[
i]*sum_[
i]/active_[
i],0.0)/(active_[
i]-1));
342 alignments_.stddev_ = std::max(alignments_.stddev_,os.str().size());
346 if (
options.output_histogram && active_[
i] >1 ) {
347 std::ostringstream os;
351 os <<
", "<<hist_[
h][
i];
356 alignments_.histogram_ = std::max(alignments_.histogram_,os.str().size());
364 if (
options.print_names_before_values) {
365 std::ostringstream
tmp;
366 for (
int l=0;
l<=level; ++
l)
368 tmp <<
"Remainder: ";
369 alignments_.timer_names_ = std::max(alignments_.timer_names_,
tmp.str().size());
372 std::ostringstream
tmp;
374 alignments_.average_time_ = std::max(alignments_.average_time_,
tmp.str().size());
376 if (
options.output_fraction && (sum_[
i]/active_[
i] > 0.) ) {
377 std::ostringstream
tmp;
378 tmp <<
" - "<< (sum_[
i]/active_[
i]-
sub_time)/(sum_[
i]/active_[
i])*100 <<
"%";
379 alignments_.fraction_ = std::max(alignments_.fraction_,
tmp.str().size());
398 for (
int i=0;
i<flat_names_.
size(); ++
i ) {
399 if (sum_[
i]/active_[
i] <=
options.drop_time) {
404 int level = std::count(flat_names_[
i].begin(), flat_names_[
i].end(),
'@');
412 if (
options.print_names_before_values) {
413 std::ostringstream
tmp;
414 for (
int l=0;
l<level; ++
l) {
420 os << std::left << std::setw(alignments_.timer_names_);
425 std::ostringstream
tmp;
426 tmp << sum_[
i]/active_[
i];
428 os << std::left << std::setw(alignments_.average_time_);
433 std::ostringstream
tmp;
436 os << std::left << std::setw(alignments_.fraction_);
440 else if (
options.output_fraction) {
442 os << std::setw(alignments_.fraction_) <<
" ";
446 std::ostringstream
tmp;
447 tmp <<
" ["<<count_[
i]/active_[
i]<<
"]";
449 os << std::left << std::setw(alignments_.count_);
453 if (
options.output_total_updates ) {
454 std::ostringstream
tmp;
455 tmp <<
" ("<<updates_[
i]/active_[
i]<<
")";
457 os << std::left << std::setw(alignments_.total_updates_);
461 if (
options.output_minmax && active_[
i]>1) {
463 std::ostringstream
tmp;
464 tmp <<
" {min="<<min_[
i];
466 os << std::left << std::setw(alignments_.min_);
470 std::ostringstream
tmp;
471 tmp <<
", max="<<max_[
i];
475 os << std::left << std::setw(alignments_.max_);
478 if (procmin_.
size()) {
479 std::ostringstream
tmp;
480 tmp <<
", proc min="<<procmin_[
i];
484 os << std::left << std::setw(alignments_.procmin_);
487 if (procmax_.
size()) {
488 std::ostringstream
tmp;
489 tmp <<
", proc max="<<procmax_[
i];
493 os << std::left << std::setw(alignments_.procmax_);
497 std::ostringstream
tmp;
498 tmp <<
", std dev="<<
sqrt(std::max<double>(sum_sq_[
i]-sum_[
i]*sum_[
i]/active_[
i],0.0)/(active_[
i]-1));
501 os << std::left << std::setw(alignments_.stddev_);
505 else if (
options.output_minmax) {
507 size_t offset = alignments_.min_ + alignments_.max_ + alignments_.stddev_;
513 if (
options.output_histogram && active_[
i] >1 ) {
514 std::ostringstream
tmp;
518 tmp <<
", "<<hist_[
h][
i];
524 os << std::left << std::setw(alignments_.histogram_);
527 else if (
options.output_histogram) {
529 for (
size_t j=0;
j < alignments_.histogram_; ++
j)
533 if (
options.output_per_proc_stddev) {
534 std::ostringstream
tmp;
535 tmp <<
", std dev per proc min/max=";
536 tmp << per_proc_stddev_min_[
i];
538 tmp << per_proc_stddev_max_[
i];
542 if (!
options.print_names_before_values) {
543 std::ostringstream
tmp;
545 for (
int l=0;
l<level; ++
l) {
559 if (
options.print_names_before_values) {
560 std::ostringstream
tmp;
561 for (
int l=0;
l<=level; ++
l)
563 tmp <<
"Remainder: ";
565 os << std::left << std::setw(alignments_.timer_names_);
569 std::ostringstream
tmp;
572 os << std::left << std::setw(alignments_.average_time_);
575 if (
options.output_fraction && (sum_[
i]/active_[
i] > 0.) ) {
577 os << std::left << std::setw(alignments_.fraction_);
578 std::ostringstream
tmp;
579 tmp <<
" - "<< (sum_[
i]/active_[
i]-
sub_time)/(sum_[
i]/active_[
i])*100 <<
"%";
582 if (!
options.print_names_before_values) {
585 offset += alignments_.count_;
586 if (
options.output_total_updates)
587 offset += alignments_.total_updates_;
589 offset += alignments_.min_ + alignments_.max_ + alignments_.stddev_;
591 offset += alignments_.histogram_;
595 std::ostringstream
tmp;
597 for (
int l=0;
l<=level; ++
l)
599 tmp <<
"Remainder: ";
601 os << std::left << std::setw(alignments_.timer_names_);
611static void printXMLEscapedString(std::ostream& os,
const std::string&
str)
654 for (
int i=0;
i<flat_names_.
size(); ++
i) {
657 int level = std::count(flat_names_[
i].begin(), flat_names_[
i].end(),
'@');
664 for (
int j = 0;
j < indent;
j++)
666 os <<
"<timing name=\"";
668 printXMLEscapedString(os,
rootName);
671 os <<
"\" value=\"" << sum_[
i]/active_[
i] <<
"\"";
686 os <<
"<timing name=\"Remainder\" value=\"" << (sum_[
i]/active_[
i] -
sub_time) <<
"\"/>\n";
689 for (
int j = 0;
j < indent;
j++)
706 if (rank(*
comm) == 0 ) {
708 os <<
"*** Teuchos::StackedTimer::report() - Remainder for a level will be ***"
709 <<
"\n*** incorrect if a timer in the level does not exist on every rank ***"
710 <<
"\n*** of the MPI Communicator. ***"
714 os <<
"Teuchos::StackedTimer::report() - max_levels manually set to " <<
options.max_levels
715 <<
". \nTo print more levels, increase value of OutputOptions::max_levels." << std::endl;
717 if ( (!
options.print_names_before_values) && (!
options.align_columns)) {
720 os <<
"Teuchos::StackedTimer::report() - option print_names_before_values=false "
721 <<
"\nrequires that the option align_columns=true too. Setting the value for "
722 <<
"\nalign_column to true."
726 std::vector<bool>
printed(flat_names_.
size(),
false);
730 std::vector<bool>
printed(flat_names_.
size(),
false);
740 if (rank(*
comm) == 0 ) {
741 std::vector<bool>
printed(flat_names_.
size(),
false);
742 os <<
"<?xml version=\"1.0\"?>\n";
743 os <<
"<performance-report date=\"" <<
timestamp <<
"\" name=\"nightly_run_" <<
datestamp <<
"\" time-units=\"seconds\">\n";
745 os <<
"</performance-report>\n";
781 throw std::invalid_argument(
"$WATCHR_BUILD_DATE has invalid year or is not in YYYY_MM_DD format.");
783 throw std::invalid_argument(
"$WATCHR_BUILD_DATE has invalid month or is not in YYYY_MM_DD format.");
785 throw std::invalid_argument(
"$WATCHR_BUILD_DATE has invalid day or is not in YYYY_MM_DD format.");
805 if(rank(*
comm) == 0) {
826 std::vector<bool>
printed(flat_names_.
size(),
false);
827 os <<
"<?xml version=\"1.0\"?>\n";
828 os <<
"<performance-report date=\"" <<
timestamp <<
"\" name=\"nightly_run_" <<
datestamp <<
"\" time-units=\"seconds\">\n";
835 os <<
" <metadata key=\"Trilinos Version\" value=\"" <<
gitSHA <<
"\"/>\n";
837 auto systemInfo = SystemInformation::collectSystemInformation();
839 os <<
" <metadata key=\"" <<
e.first <<
"\" value=\"";
840 printXMLEscapedString(os,
e.second);
844 os <<
"</performance-report>\n";
869 global_mpi_aggregation_called_ =
true;
875 return sum_[
i] / active_[
i];
881 return static_cast<double>(count_[
i]) /
static_cast<double>(active_[
i]);
887 "ERROR: StackedTimer::getAverageMpiTime() - must call aggregateMpiData() first!");
892 "ERROR: StackedTimer::getAverageMpiTime() - the timer named \""
896 return static_cast<int>(
i);
902 "ERROR: StackedTimer::isTimer() - must call aggregateMpiData() before using this query!");
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.
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
LevelTimer()
Default constructor, shouldn't be used but needed for std::vector.
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)
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.
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())
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_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.