24 level_(std::numeric_limits<unsigned>::max()),name_(
"INVALID"),parent_(nullptr)
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);
70 auto full_name = get_full_name();
71 if (full_name.size() > name.size())
73 if ( strncmp(full_name.c_str(), name.c_str(), full_name.size()))
75 if (get_full_name() ==
name) {
80 for (
unsigned i=0;i<sub_timers_.size(); ++i){
81 t = sub_timers_[i].findTimer(name,found);
135 hist_[i].resize(num_names);
148 updates.
resize(num_names);
153 per_proc_stddev.
resize(num_names);
159 for (
int i=0;i<num_names; ++i) {
164 used[i] = t.count==0? 0:1;
166 updates[i] = t.updates;
168 per_proc_stddev[i] = t.stdDev;
178 for (
int i=0;i<num_names;++i)
182 for (
int i=0;i<num_names;++i)
188 int commRank = comm->getRank();
189 for (
int i=0;i<num_names; ++i) {
190 if (used[i] && (
min_[i]==time[i]))
191 procmin[i] = commRank;
194 if (used[i] && (
max_[i]==time[i]))
195 procmax[i] = commRank;
205 for (
int i=0;i<num_names; ++i) {
211 int bin=(time[i]-
min_[i])/dh;
212 bins[i] = std::max(std::min(bin,options.
num_histogram-1) , 0);
218 for (
int i=0;i<num_names; ++i) {
229 for (
int i=0;i<num_names; ++i)
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);
252 std::vector<bool> &printed,
258 double total_time = 0.0;
266 if ( (level != print_level) || (level >= options.
max_levels) )
269 if ( prefix != split_names.first)
274 std::ostringstream os;
275 for (
int l=0; l<level; ++l)
278 os << split_names.second <<
": ";
284 std::ostringstream os;
291 std::ostringstream os;
292 os <<
" - "<<
sum_[i]/
active_[i]/parent_time*100<<
"%";
298 std::ostringstream os;
305 std::ostringstream os;
313 std::ostringstream os;
314 os <<
" {min=" <<
min_[i];
318 std::ostringstream os;
319 os <<
", max=" <<
max_[i];
325 std::ostringstream os;
332 std::ostringstream os;
339 std::ostringstream os;
347 std::ostringstream os;
351 os <<
", "<<
hist_[h][i];
365 std::ostringstream tmp;
366 for (
int l=0; l<=level; ++l)
368 tmp <<
"Remainder: ";
372 std::ostringstream tmp;
377 std::ostringstream tmp;
396 double total_time = 0.0;
405 if ( (level != print_level) || (level >= options.
max_levels) )
408 if ( prefix != split_names.first)
413 std::ostringstream tmp;
414 for (
int l=0; l<level; ++l) {
418 tmp << split_names.second <<
": ";
425 std::ostringstream tmp;
433 std::ostringstream tmp;
434 tmp <<
" - "<<
sum_[i]/
active_[i]/parent_time*100<<
"%";
446 std::ostringstream tmp;
454 std::ostringstream tmp;
463 std::ostringstream tmp;
464 tmp <<
" {min="<<
min_[i];
470 std::ostringstream tmp;
471 tmp <<
", max="<<
max_[i];
479 std::ostringstream tmp;
488 std::ostringstream tmp;
497 std::ostringstream tmp;
508 for (
size_t j=0; j < offset; ++j)
514 std::ostringstream tmp;
518 tmp <<
", "<<
hist_[h][i];
534 std::ostringstream tmp;
535 tmp <<
", std dev per proc min/max=";
543 std::ostringstream tmp;
545 for (
int l=0; l<level; ++l) {
549 tmp << split_names.second <<
": ";
560 std::ostringstream tmp;
561 for (
int l=0; l<=level; ++l)
563 tmp <<
"Remainder: ";
569 std::ostringstream tmp;
578 std::ostringstream tmp;
592 for (
size_t j=0; j < offset; ++j)
595 std::ostringstream tmp;
597 for (
int l=0; l<=level; ++l)
599 tmp <<
"Remainder: ";
647 StackedTimer::printLevelXML (std::string prefix,
int print_level, std::ostream& os, std::vector<bool> &printed,
double parent_time,
const std::string& rootName)
649 constexpr
int indSpaces = 2;
650 int indent = indSpaces * print_level;
652 double total_time = 0.0;
658 if ( level != print_level)
661 if ( prefix != split_names.first)
664 for (
int j = 0; j < indent; j++)
666 os <<
"<timing name=\"";
667 if(level == 0 && rootName.length())
675 std::ostringstream osInner;
677 std::string innerContents = osInner.str();
678 if(innerContents.length())
684 for (
int j = 0; j < indent + indSpaces; j++)
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;
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."
740 if (rank(*comm) == 0 ) {
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";
751 const char* rawWatchrDir = getenv(
"WATCHR_PERF_DIR");
752 const char* rawBuildName = getenv(
"WATCHR_BUILD_NAME");
753 const char* rawGitSHA = getenv(
"TRILINOS_GIT_SHA");
754 const char* rawBuildDateOverride = getenv(
"WATCHR_BUILD_DATE");
758 std::string watchrDir = rawWatchrDir;
759 if(!watchrDir.length())
765 std::string buildName = rawBuildName ? rawBuildName :
"";
766 std::string datestamp;
767 std::string timestamp;
773 tstruct = gmtime(&t);
774 if(rawBuildDateOverride)
777 int year = 0, month = 0, day = 0;
778 sscanf(rawBuildDateOverride,
"%d_%d_%d", &year, &month, &day);
780 if(year <= 2000 || year > 2100)
781 throw std::invalid_argument(
"$WATCHR_BUILD_DATE has invalid year or is not in YYYY_MM_DD format.");
782 if(month < 1 || month > 12)
783 throw std::invalid_argument(
"$WATCHR_BUILD_DATE has invalid month or is not in YYYY_MM_DD format.");
784 if(day < 1 || day > 31)
785 throw std::invalid_argument(
"$WATCHR_BUILD_DATE has invalid day or is not in YYYY_MM_DD format.");
786 snprintf(buf, 256,
"%04d_%02d_%02d", year, month, day);
788 strftime(buf, 256,
"T%H:%M:%S", tstruct);
789 std::string justTime = buf;
790 snprintf(buf, 256,
"%04d-%02d-%02d", year, month, day);
791 timestamp = std::string(buf) + justTime;
795 strftime(buf, 256,
"%Y_%m_%d", tstruct);
797 strftime(buf, 256,
"%FT%H:%M:%S", tstruct);
803 std::string fullFile;
805 if(rank(*comm) == 0) {
806 std::string nameNoSpaces =
name;
807 for(
char& c : nameNoSpaces)
812 if(buildName.length())
815 std::string buildNameNoSpaces = buildName;
816 for(
char& c : buildNameNoSpaces)
821 fullFile = watchrDir +
'/' + buildNameNoSpaces +
"-" + nameNoSpaces +
'_' + datestamp +
".xml";
824 fullFile = watchrDir +
'/' + nameNoSpaces +
'_' + datestamp +
".xml";
825 std::ofstream os(fullFile);
827 os <<
"<?xml version=\"1.0\"?>\n";
828 os <<
"<performance-report date=\"" << timestamp <<
"\" name=\"nightly_run_" << datestamp <<
"\" time-units=\"seconds\">\n";
831 std::string gitSHA(rawGitSHA);
833 if(gitSHA.length() > 10)
834 gitSHA = gitSHA.substr(0, 10);
835 os <<
" <metadata key=\"Trilinos Version\" value=\"" << gitSHA <<
"\"/>\n";
838 for (
const auto &e : systemInfo) {
839 os <<
" <metadata key=\"" << e.first <<
"\" value=\"";
843 printLevelXML(
"", 0, os, printed, 0.0, buildName +
": " + name);
844 os <<
"</performance-report>\n";
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 \""
893 << flat_timer_name <<
"\" does not exist!");
896 return static_cast<int>(i);
902 "ERROR: StackedTimer::isTimer() - must call aggregateMpiData() before using this query!");
bool isTimer(const std::string &flat_timer_name)
void setVerboseOstream(const Teuchos::RCP< std::ostream > &os)
Set the ostream for verbose mode(defaults to std::cout).
std::string::size_type timer_names_
std::string::size_type histogram_
std::string::size_type average_time_
std::string::size_type total_updates_
std::string::size_type procmax_
Array< double > per_proc_stddev_max_
void addTimerNames(Array< std::string > &names, unsigned &pos)
void enableVerboseTimestamps(const unsigned levels)
Enable timestamps in verbose mode for the number of levels specified.
void enableVerbose(const bool enable_verbose)
If set to true, print timer start/stop to verbose ostream.
void merge(Teuchos::RCP< const Teuchos::Comm< int > > comm)
std::string::size_type max_
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
void reduce< int, double >(const double sendBuf[], double recvBuf[], const int count, const EReductionType reductType, const int root, const Comm< int > &comm)
std::string::size_type procmin_
bool enable_verbose_
If set to true, prints to the debug ostream. At construction, default value is set from environment v...
T * getRawPtr()
Return a raw pointer to beginning of array or NULL if unsized.
double printLevelXML(std::string prefix, int level, std::ostream &os, std::vector< bool > &printed, double parent_time, const std::string &rootName="")
Array< double > per_proc_stddev_min_
double getMpiAverageCount(const std::string &flat_timer_name)
bool enable_timers_
Used to disable timers for asynchronous work.
std::string reportWatchrXML(const std::string &name, Teuchos::RCP< const Teuchos::Comm< int > > comm)
unsigned verbose_timestamp_levels_
If set to a value greater than 0, verbose mode will print that many levels of timers with timestamps...
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)
double accumulatedTime(const std::string &name="")
std::string::size_type fraction_
bool output_per_proc_stddev
std::string::size_type count_
void report(std::ostream &os)
void error_out(const std::string &msg, const bool)
Error reporting function for stacked timer.
The basic timer used internally, uses std::chrono::high_resolution_clock.
static void printXMLEscapedString(std::ostream &os, const std::string &str)
double computeColumnWidthsForAligment(std::string prefix, int print_level, std::vector< bool > &printed, double parent_time, const OutputOptions &options)
void reportXML(std::ostream &os, const std::string &datestamp, const std::string ×tamp, Teuchos::RCP< const Teuchos::Comm< int > > comm)
Array< Array< int > > hist_
void collectRemoteData(Teuchos::RCP< const Teuchos::Comm< int > > comm, const OutputOptions &options)
bool print_names_before_values
Array< unsigned long long > updates_
void mergeCounterNames(const Comm< int > &comm, const Array< std::string > &localNames, Array< std::string > &globalNames, const ECounterSetOp setOp)
Merge counter names over all processors.
std::string::size_type min_
void resize(size_type new_size, const value_type &x=value_type())
Teuchos::RCP< std::ostream > verbose_ostream_
For debugging, this is the ostream used for printing.
LevelTimer timer_
Base timer.
double getMpiAverageTime(const std::string &flat_timer_name)
Array< std::string > flat_names_
int getFlatNameIndex(const std::string &flat_timer_name)
bool global_mpi_aggregation_called_
void report(std::ostream &os)
LevelTimer()
Default constructor, shouldn't be used but needed for std::vector.
const BaseTimer * findBaseTimer(const std::string &name) const
void aggregateMpiData(Teuchos::RCP< const Teuchos::Comm< int > > comm, OutputOptions options=OutputOptions())
Smart reference counting pointer class for automatic garbage collection.
Array< unsigned long > count_
std::string::size_type stddev_
bool output_total_updates
std::pair< std::string, std::string > getPrefix(const std::string &name)
struct Teuchos::StackedTimer::AlignmentWidths alignments_