4 #include "Teuchos_StackedTimer.hpp"
13 level_(std::numeric_limits<unsigned>::max()),name_(
"INVALID"),parent_(nullptr)
24 for (
unsigned i=0; i<level_; ++i)
26 os << name_<<
":"<<
accumulatedTime()<<
" [" << count_started_<<
"] ("<< count_updates_ <<
")"<<std::endl;
28 for (
size_t i=0; i<sub_timers_.size(); ++i) {
29 t_total += sub_timers_[i].accumulatedTime();
30 sub_timers_[i].report(os);
32 if ( sub_timers_.size() == 0 )
34 for (
unsigned i=0; i<=level_; ++i)
43 if (get_full_name() == name) {
47 for (
unsigned i=0;i<sub_timers_.size(); ++i){
48 t = sub_timers_[i].findBaseTimer(name);
58 BaseTimer::TimeInfo t;
59 if (get_full_name() == name) {
60 t = BaseTimer::TimeInfo(
this);
64 for (
unsigned i=0;i<sub_timers_.size(); ++i){
65 t = sub_timers_[i].findTimer(name,found);
76 flat_names_.
resize(num_timers);
78 timer_.addTimerNames(flat_names_, pos);
85 flat_names_ = all_names;
91 int num_names = flat_names_.
size();
94 updates_.
resize(num_names);
97 if (options.output_minmax || options.output_histogram) {
100 if ( options.output_minmax )
101 sum_sq_.
resize(num_names);
105 if (options.output_histogram ) {
106 hist_.resize(options.num_histogram);
107 for (
int i=0;i<options.num_histogram ; ++i)
108 hist_[i].resize(num_names);
115 if (options.output_total_updates)
116 updates.
resize(num_names);
120 if (options.output_histogram)
124 for (
int i=0;i<num_names; ++i) {
129 used[i] = t.count==0? 0:1;
130 if (options.output_total_updates)
131 updates[i] = t.updates;
144 if (options.output_histogram) {
145 for (
int i=0;i<num_names; ++i) {
147 double dh = (max_[i]-min_[i])/options.num_histogram;
151 int bin=(time[i]- min_[i])/dh;
152 bins[i] = std::max(std::min(bin,options.num_histogram-1) , 0);
156 for (
int j=0; j<options.num_histogram; ++j){
157 for (
int i=0;i<num_names; ++i) {
167 if (sum_sq_.
size()) {
168 for (
int i=0;i<num_names; ++i)
175 std::pair<std::string, std::string> getPrefix(
const std::string &name) {
176 for (std::size_t i=name.size()-1; i>0; --i)
177 if (name[i] ==
'@') {
178 return std::pair<std::string, std::string>(name.substr(0,i), name.substr(i+1, name.size()));
180 return std::pair<std::string, std::string>(std::string(
""), name);
186 std::vector<bool> &printed,
192 double total_time = 0.0;
194 for (
int i=0; i<flat_names_.
size(); ++i ) {
197 int level = std::count(flat_names_[i].begin(), flat_names_[i].end(),
'@');
198 if ( (level != print_level) || (level >= options.max_levels) )
200 auto split_names = getPrefix(flat_names_[i]);
201 if ( prefix != split_names.first)
206 std::ostringstream os;
207 for (
int l=0; l<level; ++l)
210 os << split_names.second <<
": ";
211 alignments_.timer_names_= std::max(alignments_.timer_names_,os.str().size());
216 std::ostringstream os;
217 os << sum_[i]/active_[i];
218 alignments_.average_time_ = std::max(alignments_.average_time_,os.str().size());
222 if ( options.output_fraction && parent_time>0) {
223 std::ostringstream os;
224 os <<
" - "<<sum_[i]/active_[i]/parent_time*100<<
"%";
225 alignments_.fraction_ = std::max(alignments_.fraction_,os.str().size());
230 std::ostringstream os;
231 os <<
" ["<<count_[i]/active_[i]<<
"]";
232 alignments_.count_ = std::max(alignments_.count_,os.str().size());
236 if ( options.output_total_updates) {
237 std::ostringstream os;
238 os <<
" ("<<updates_[i]/active_[i]<<
")";
239 alignments_.total_updates_ = std::max(alignments_.total_updates_,os.str().size());
243 if ( options.output_minmax && active_[i]>1) {
245 std::ostringstream os;
246 os <<
" {min=" << min_[i];
247 alignments_.min_ = std::max(alignments_.min_,os.str().size());
250 std::ostringstream os;
251 os <<
", max=" << max_[i];
254 alignments_.max_ = std::max(alignments_.max_,os.str().size());
257 std::ostringstream os;
258 os <<
", std dev=" << sqrt(std::max<double>(sum_sq_[i]-sum_[i]*sum_[i]/active_[i],0.0)/(active_[i]-1));
260 alignments_.stddev_ = std::max(alignments_.stddev_,os.str().size());
264 if ( options.output_histogram && active_[i] >1 ) {
265 std::ostringstream os;
267 for (
int h=0;h<options.num_histogram; ++h) {
269 os <<
", "<<hist_[h][i];
274 alignments_.histogram_ = std::max(alignments_.histogram_,os.str().size());
282 if (options.print_names_before_values) {
283 std::ostringstream tmp;
284 for (
int l=0; l<=level; ++l)
286 tmp <<
"Remainder: ";
287 alignments_.timer_names_ = std::max(alignments_.timer_names_,tmp.str().size());
290 std::ostringstream tmp;
291 tmp << sum_[i]/active_[i]- sub_time;
292 alignments_.average_time_ = std::max(alignments_.average_time_,tmp.str().size());
294 if ( options.output_fraction && (sum_[i]/active_[i] > 0.) ) {
295 std::ostringstream tmp;
296 tmp <<
" - "<< (sum_[i]/active_[i]- sub_time)/(sum_[i]/active_[i])*100 <<
"%";
297 alignments_.fraction_ = std::max(alignments_.fraction_,tmp.str().size());
301 total_time += sum_[i]/active_[i];
314 double total_time = 0.0;
316 for (
int i=0; i<flat_names_.
size(); ++i ) {
319 int level = std::count(flat_names_[i].begin(), flat_names_[i].end(),
'@');
320 if ( (level != print_level) || (level >= options.max_levels) )
322 auto split_names = getPrefix(flat_names_[i]);
323 if ( prefix != split_names.first)
327 if (options.print_names_before_values) {
328 std::ostringstream tmp;
329 for (
int l=0; l<level; ++l) {
333 tmp << split_names.second <<
": ";
334 if (options.align_columns)
335 os << std::left << std::setw(alignments_.timer_names_);
340 std::ostringstream tmp;
341 tmp << sum_[i]/active_[i];
342 if (options.align_columns)
343 os << std::left << std::setw(alignments_.average_time_);
347 if ( options.output_fraction && parent_time>0) {
348 std::ostringstream tmp;
349 tmp <<
" - "<<sum_[i]/active_[i]/parent_time*100<<
"%";
350 if (options.align_columns)
351 os << std::left << std::setw(alignments_.fraction_);
355 else if (options.output_fraction) {
356 if (options.align_columns)
357 os << std::setw(alignments_.fraction_) <<
" ";
361 std::ostringstream tmp;
362 tmp <<
" ["<<count_[i]/active_[i]<<
"]";
363 if (options.align_columns)
364 os << std::left << std::setw(alignments_.count_);
368 if ( options.output_total_updates ) {
369 std::ostringstream tmp;
370 tmp <<
" ("<<updates_[i]/active_[i]<<
")";
371 if (options.align_columns)
372 os << std::left << std::setw(alignments_.total_updates_);
376 if ( options.output_minmax && active_[i]>1) {
378 std::ostringstream tmp;
379 tmp <<
" {min="<<min_[i];
380 if (options.align_columns)
381 os << std::left << std::setw(alignments_.min_);
385 std::ostringstream tmp;
386 tmp <<
", max="<<max_[i];
389 if (options.align_columns)
390 os << std::left << std::setw(alignments_.max_);
394 std::ostringstream tmp;
395 tmp <<
", std dev="<<sqrt(std::max<double>(sum_sq_[i]-sum_[i]*sum_[i]/active_[i],0.0)/(active_[i]-1));
397 if (options.align_columns)
398 os << std::left << std::setw(alignments_.stddev_);
402 else if ( options.output_minmax) {
404 size_t offset = alignments_.min_ + alignments_.max_ + alignments_.stddev_;
405 for (
size_t j=0; j < offset; ++j)
410 if ( options.output_histogram && active_[i] >1 ) {
411 std::ostringstream tmp;
413 for (
int h=0;h<options.num_histogram; ++h) {
415 tmp <<
", "<<hist_[h][i];
420 if (options.align_columns)
421 os << std::left << std::setw(alignments_.histogram_);
424 else if ( options.output_histogram) {
426 for (
size_t j=0; j < alignments_.histogram_; ++j)
430 if (! options.print_names_before_values) {
431 std::ostringstream tmp;
433 for (
int l=0; l<level; ++l) {
437 tmp << split_names.second <<
": ";
443 double sub_time =
printLevel(flat_names_[i], level+1, os, printed, sum_[i]/active_[i], options);
447 if (options.print_names_before_values) {
448 std::ostringstream tmp;
449 for (
int l=0; l<=level; ++l)
451 tmp <<
"Remainder: ";
452 if (options.align_columns)
453 os << std::left << std::setw(alignments_.timer_names_);
457 std::ostringstream tmp;
458 tmp << sum_[i]/active_[i]- sub_time;
459 if (options.align_columns)
460 os << std::left << std::setw(alignments_.average_time_);
463 if ( options.output_fraction && (sum_[i]/active_[i] > 0.) ) {
464 if (options.align_columns)
465 os << std::left << std::setw(alignments_.fraction_);
466 std::ostringstream tmp;
467 tmp <<
" - "<< (sum_[i]/active_[i]- sub_time)/(sum_[i]/active_[i])*100 <<
"%";
470 if (! options.print_names_before_values) {
473 offset += alignments_.count_;
474 if (options.output_total_updates)
475 offset += alignments_.total_updates_;
476 if (options.output_minmax)
477 offset += alignments_.min_ + alignments_.max_ + alignments_.stddev_;
478 if (options.output_histogram)
479 offset += alignments_.histogram_;
480 for (
size_t j=0; j < offset; ++j)
483 std::ostringstream tmp;
485 for (
int l=0; l<=level; ++l)
487 tmp <<
"Remainder: ";
488 if (options.align_columns)
489 os << std::left << std::setw(alignments_.timer_names_);
494 total_time += sum_[i]/active_[i];
504 if (rank(*comm) == 0 ) {
505 if (options.print_warnings) {
506 os <<
"*** Teuchos::StackedTimer::report() - Remainder for a level will be ***"
507 <<
"\n*** incorrect if a timer in the level does not exist on every rank ***"
508 <<
"\n*** of the MPI Communicator. ***"
511 if ( (options.max_levels != INT_MAX) && options.print_warnings) {
512 os <<
"Teuchos::StackedTimer::report() - max_levels manually set to " << options.max_levels
513 <<
". \nTo print more levels, increase value of OutputOptions::max_levels." << std::endl;
515 if ( (! options.print_names_before_values) && (! options.align_columns)) {
516 options.align_columns =
true;
517 if (options.print_warnings)
518 os <<
"Teuchos::StackedTimer::report() - option print_names_before_values=false "
519 <<
"\nrequires that the option align_columns=true too. Setting the value for "
520 <<
"\nalign_column to true."
523 if (options.align_columns) {
524 std::vector<bool> printed(flat_names_.
size(),
false);
528 std::vector<bool> printed(flat_names_.
size(),
false);
533 void StackedTimer::enableVerbose(
const bool enable_verbose)
void merge(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.
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.
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="")
void report(std::ostream &os)
the basic timer used elsewhere, uses MPI_Wtime for time
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)
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
Deprecated .
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 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.
void error_out(const std::string &msg, const bool)
Error reporting function for stacked timer.
Abstract interface for distributed-memory communication.
LevelTimer()
Default constructor, shouldn't be used but needed for std::vector.
const BaseTimer * findBaseTimer(const std::string &name) const
Smart reference counting pointer class for automatic garbage collection.
Struct for controlling output options like histograms.