|
Sierra Toolkit Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <stk_util/diag/PrintTimer.hpp> 00010 #include <stk_util/util/PrintTable.hpp> 00011 00012 #include <iomanip> 00013 #include <ostream> 00014 #include <stdexcept> 00015 #include <typeinfo> 00016 #include <utility> 00017 #include <algorithm> 00018 #include <limits> 00019 00020 #include <stk_util/diag/Writer.hpp> 00021 #include <stk_util/diag/WriterManip.hpp> 00022 #include <stk_util/diag/WriterExt.hpp> 00023 #include <stk_util/util/string_case_compare.hpp> 00024 #include <stk_util/util/Marshal.hpp> 00025 00026 namespace stk { 00027 namespace diag { 00028 namespace { 00029 struct ParallelTimer; 00030 }} 00031 00032 template <class T> 00033 Marshal &operator<<(Marshal &mout, const diag::Timer::Metric<T> &t); 00034 00035 Marshal &operator<<(Marshal &mout, const diag::Timer &t); 00036 00037 Marshal &operator>>(Marshal &min, diag::ParallelTimer &t); 00038 } 00039 00040 namespace stk { 00041 namespace diag { 00042 00043 namespace { 00044 00051 struct Percent 00052 { 00053 Percent(double numerator, double denominator) 00054 : m_numerator(numerator), 00055 m_denominator(denominator) 00056 {} 00057 00068 std::ostream &operator()(std::ostream &os) const; 00069 00070 private: 00071 double m_numerator; 00072 double m_denominator; 00073 }; 00074 00075 00076 std::ostream & 00077 Percent::operator()( 00078 std::ostream & os) const 00079 { 00080 std::ostringstream strout; 00081 00082 if (m_numerator == 0.0) 00083 strout << "(0.00%)"; 00084 else if (m_denominator == 0.0) 00085 strout << "( NaN)"; 00086 else { 00087 double ratio = m_numerator/m_denominator*100.0; 00088 if (ratio < 0.01) 00089 strout << "(<0.01%)"; 00090 else if (ratio >= 100.0) 00091 strout << "(" << std::setw(5) << std::setprecision(1) << std::fixed << ratio << "%)"; 00092 else 00093 strout << "(" << std::setw(5) << std::setprecision(2) << std::fixed << ratio << "%)"; 00094 } 00095 00096 return os << strout.str(); 00097 } 00098 00099 00109 inline std::ostream &operator<<(std::ostream &os, const Percent &p) { 00110 return p(os); 00111 } 00112 00113 struct ParallelTimer 00114 { 00115 template <typename T> 00116 struct Metric 00117 { 00118 Metric() 00119 : m_value(0), 00120 m_sum(0.0), 00121 m_min(std::numeric_limits<double>::max()), 00122 m_max(0.0) 00123 {} 00124 00125 typename MetricTraits<T>::Type m_value; 00126 typename MetricTraits<T>::Type m_checkpoint; 00127 double m_sum; 00128 double m_min; 00129 double m_max; 00130 00131 void accumulate(const Metric<T> &metric, bool checkpoint) { 00132 double value = static_cast<double>(metric.m_value); 00133 if (checkpoint) 00134 value -= static_cast<double>(metric.m_checkpoint); 00135 00136 m_sum += value; 00137 m_min = std::min(m_min, value); 00138 m_max = std::max(m_max, value); 00139 } 00140 00141 Writer &dump(Writer &dout) const { 00142 if (dout.shouldPrint()) { 00143 dout << "Metric<" << typeid(typename MetricTraits<T>::Type) << ">" << push << dendl; 00144 dout << "m_value " << m_value << dendl; 00145 dout << "m_checkpoint " << m_value << dendl; 00146 dout << "m_sum " << m_sum << dendl; 00147 dout << "m_min " << m_min << dendl; 00148 dout << "m_max " << m_max << dendl; 00149 dout << pop; 00150 } 00151 return dout; 00152 } 00153 }; 00154 00155 ParallelTimer() 00156 : m_name(), 00157 m_timerMask(0), 00158 m_subtimerLapCount(0), 00159 m_lapCount(), 00160 m_cpuTime(), 00161 m_wallTime(), 00162 m_MPICount(), 00163 m_MPIByteCount(), 00164 m_subtimerList() 00165 {} 00166 00167 ParallelTimer(const ParallelTimer ¶llel_timer) 00168 : m_name(parallel_timer.m_name), 00169 m_timerMask(parallel_timer.m_timerMask), 00170 m_subtimerLapCount(parallel_timer.m_subtimerLapCount), 00171 m_lapCount(parallel_timer.m_lapCount), 00172 m_cpuTime(parallel_timer.m_cpuTime), 00173 m_wallTime(parallel_timer.m_wallTime), 00174 m_MPICount(parallel_timer.m_MPICount), 00175 m_MPIByteCount(parallel_timer.m_MPIByteCount), 00176 m_subtimerList(parallel_timer.m_subtimerList) 00177 {} 00178 00179 ParallelTimer &operator=(const ParallelTimer ¶llel_timer) { 00180 m_name = parallel_timer.m_name; 00181 m_timerMask = parallel_timer.m_timerMask; 00182 m_subtimerLapCount = parallel_timer.m_subtimerLapCount; 00183 m_lapCount = parallel_timer.m_lapCount; 00184 m_cpuTime = parallel_timer.m_cpuTime; 00185 m_wallTime = parallel_timer.m_wallTime; 00186 m_MPICount = parallel_timer.m_MPICount; 00187 m_MPIByteCount = parallel_timer.m_MPIByteCount; 00188 m_subtimerList = parallel_timer.m_subtimerList; 00189 00190 return *this; 00191 } 00192 00193 template <class T> 00194 const Metric<T> &getMetric() const; 00195 00196 std::string m_name; 00197 TimerMask m_timerMask; 00198 double m_subtimerLapCount; 00199 00200 Metric<LapCount> m_lapCount; 00201 Metric<CPUTime> m_cpuTime; 00202 Metric<WallTime> m_wallTime; 00203 Metric<MPICount> m_MPICount; 00204 Metric<MPIByteCount> m_MPIByteCount; 00205 00206 std::list<ParallelTimer> m_subtimerList; 00207 00208 Writer &dump(Writer &dout) const; 00209 }; 00210 00211 template<> 00212 const ParallelTimer::Metric<LapCount> & 00213 ParallelTimer::getMetric<LapCount>() const { 00214 return m_lapCount; 00215 } 00216 00217 00218 template<> 00219 const ParallelTimer::Metric<CPUTime> & 00220 ParallelTimer::getMetric<CPUTime>() const { 00221 return m_cpuTime; 00222 } 00223 00224 00225 template<> 00226 const ParallelTimer::Metric<WallTime> & 00227 ParallelTimer::getMetric<WallTime>() const { 00228 return m_wallTime; 00229 } 00230 00231 00232 template<> 00233 const ParallelTimer::Metric<MPICount> & 00234 ParallelTimer::getMetric<MPICount>() const { 00235 return m_MPICount; 00236 } 00237 00238 00239 template<> 00240 const ParallelTimer::Metric<MPIByteCount> & 00241 ParallelTimer::getMetric<MPIByteCount>() const { 00242 return m_MPIByteCount; 00243 } 00244 00245 00246 template <typename T> 00247 Writer &operator<<(Writer &dout, const ParallelTimer::Metric<T> &t) { 00248 return t.dump(dout); 00249 } 00250 00251 Writer &operator<<(Writer &dout, const ParallelTimer ¶llel_timer) { 00252 return parallel_timer.dump(dout); 00253 } 00254 00255 Writer & 00256 ParallelTimer::dump(Writer &dout) const { 00257 if (dout.shouldPrint()) { 00258 dout << "ParallelTimer " << m_name << push << dendl; 00259 dout << "m_name " << m_name << dendl; 00260 dout << "m_timerMask " << hex << m_timerMask << dendl; 00261 dout << "m_subtimerLapCount " << m_subtimerLapCount << dendl; 00262 dout << "m_lapCount " << m_lapCount << dendl; 00263 dout << "m_cpuTime " << m_cpuTime << dendl; 00264 dout << "m_wallTime " << m_wallTime << dendl; 00265 dout << "m_MPICount " << m_MPICount << dendl; 00266 dout << "m_MPIByteCount " << m_MPIByteCount << dendl; 00267 dout << "m_subtimerList " << m_subtimerList << dendl; 00268 dout << pop; 00269 } 00270 return dout; 00271 } 00272 00273 #ifdef __INTEL_COMPILER 00274 #pragma warning(push) 00275 #pragma warning(disable: 444) 00276 #endif 00277 class finder : public std::unary_function<ParallelTimer, bool> 00278 { 00279 public: 00280 finder(const std::string &name) 00281 : m_name(name) 00282 {} 00283 00284 bool operator()(const ParallelTimer ¶llel_timer) const { 00285 return equal_case(parallel_timer.m_name, m_name); 00286 } 00287 00288 private: 00289 std::string m_name; 00290 }; 00291 #ifdef __INTEL_COMPILER 00292 #pragma warning(pop) 00293 #endif 00294 00295 00296 void 00297 merge_parallel_timer( 00298 ParallelTimer & p0, 00299 const ParallelTimer & p1, 00300 bool checkpoint) 00301 { 00302 p0.m_timerMask = p1.m_timerMask; 00303 p0.m_subtimerLapCount += p1.m_subtimerLapCount; 00304 p0.m_lapCount.accumulate(p1.m_lapCount, checkpoint); 00305 p0.m_cpuTime.accumulate(p1.m_cpuTime, checkpoint); 00306 p0.m_wallTime.accumulate(p1.m_wallTime, checkpoint); 00307 p0.m_MPICount.accumulate(p1.m_MPICount, checkpoint); 00308 p0.m_MPIByteCount.accumulate(p1.m_MPIByteCount, checkpoint); 00309 00310 00311 for (std::list<ParallelTimer>::const_iterator p1_it = p1.m_subtimerList.begin(); p1_it != p1.m_subtimerList.end(); ++p1_it) { 00312 std::list<ParallelTimer>::iterator p0_it = std::find_if(p0.m_subtimerList.begin(), p0.m_subtimerList.end(), finder((*p1_it).m_name)); 00313 if (p0_it == p0.m_subtimerList.end()) { 00314 p0.m_subtimerList.push_back((*p1_it)); 00315 p0_it = --p0.m_subtimerList.end(); 00316 merge_parallel_timer(*p0_it, *p1_it, checkpoint); 00317 } 00318 else 00319 merge_parallel_timer(*p0_it, *p1_it, checkpoint); 00320 } 00321 } 00322 00323 00324 void 00325 collect_timers( 00326 Timer & root_timer, 00327 ParallelTimer & parallel_timer, 00328 bool checkpoint, 00329 ParallelMachine comm) 00330 { 00331 Marshal mout; 00332 mout << root_timer; 00333 00334 #ifdef STK_HAS_MPI 00335 const int parallel_root = 0 ; 00336 const int parallel_size = parallel_machine_size(comm); 00337 const int parallel_rank = parallel_machine_rank(comm); 00338 00339 // Gather the send counts on root processor 00340 std::string send_string(mout.str()); 00341 int send_count = send_string.size(); 00342 std::vector<int> recv_count(parallel_size, 0); 00343 int * const recv_count_ptr = &recv_count[0] ; 00344 00345 int result = MPI_Gather(&send_count, 1, MPI_INT, 00346 recv_count_ptr, 1, MPI_INT, 00347 parallel_root, comm); 00348 if (MPI_SUCCESS != result) { 00349 std::ostringstream message ; 00350 message << "stk::diag::collect_timers FAILED: MPI_Gather = " << result ; 00351 throw std::runtime_error(message.str()); 00352 } 00353 00354 // Receive counts are only non-zero on the root processor: 00355 std::vector<int> recv_displ(parallel_size + 1, 0); 00356 00357 for (int i = 0 ; i < parallel_size ; ++i) { 00358 recv_displ[i + 1] = recv_displ[i] + recv_count[i] ; 00359 } 00360 00361 const int recv_size = recv_displ[parallel_size] ; 00362 00363 std::vector<char> buffer(recv_size); 00364 00365 { 00366 const char * const send_ptr = send_string.data(); 00367 char * const recv_ptr = recv_size ? & buffer[0] : 0; 00368 int * const recv_displ_ptr = & recv_displ[0] ; 00369 00370 result = MPI_Gatherv((void *) send_ptr, send_count, MPI_CHAR, 00371 recv_ptr, recv_count_ptr, recv_displ_ptr, MPI_CHAR, 00372 parallel_root, comm); 00373 if (MPI_SUCCESS != result) { 00374 std::ostringstream message ; 00375 message << "stk::diag::collect_timers FAILED: MPI_Gatherv = " << result ; 00376 throw std::runtime_error(message.str()); 00377 } 00378 00379 std::vector<ParallelTimer> parallel_timer_vector(parallel_size); 00380 00381 if (parallel_rank == parallel_root) { 00382 for (int j = 0; j < parallel_size; ++j) { 00383 Marshal min(std::string(recv_ptr + recv_displ[j], recv_ptr + recv_displ[j + 1])); 00384 min >> parallel_timer_vector[j]; 00385 } 00386 00387 parallel_timer = parallel_timer_vector[0]; 00388 00389 for (size_t j = 0; j < parallel_timer_vector.size(); ++j) 00390 merge_parallel_timer(parallel_timer, parallel_timer_vector[j], checkpoint); 00391 } 00392 } 00393 #endif 00394 } 00395 00396 // PrintTable &printTable(PrintTable &table, MPI_Comm mpi_comm, MetricsMask metrics_mask) const; 00397 00398 PrintTable & 00399 printSubtable( 00400 PrintTable & table, 00401 const Timer & root_timer, 00402 const Timer & timer, 00403 MetricsMask metrics_mask, 00404 int depth, 00405 bool timer_checkpoint) 00406 { 00407 if (timer.getSubtimerLapCount() != 0.0) { 00408 if (timer.shouldRecord()) { 00409 if (timer.getTimerMask() == 0 || timer.getMetric<LapCount>().getAccumulatedLap(timer_checkpoint) > 0) { 00410 table << justify(PrintTable::Cell::LEFT) << indent(depth) << timer.getName() << end_col 00411 << justify(PrintTable::Cell::RIGHT) << timer.getMetric<LapCount>().getAccumulatedLap(timer_checkpoint) << end_col; 00412 00413 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<CPUTime>::METRIC) 00414 table << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<CPUTime>::format(timer.getMetric<CPUTime>().getAccumulatedLap(timer_checkpoint)) 00415 << " " << std::setw(8) << Percent(timer.getMetric<CPUTime>().getAccumulatedLap(timer_checkpoint), root_timer.getMetric<CPUTime>().getAccumulatedLap(timer_checkpoint)) << end_col; 00416 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<WallTime>::METRIC) 00417 table << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<WallTime>::format(timer.getMetric<WallTime>().getAccumulatedLap(timer_checkpoint)) 00418 << " " << std::setw(8) << Percent(timer.getMetric<WallTime>().getAccumulatedLap(timer_checkpoint), root_timer.getMetric<WallTime>().getAccumulatedLap(timer_checkpoint)) << end_col; 00419 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<MPICount>::METRIC) 00420 table << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<MPICount>::format(timer.getMetric<MPICount>().getAccumulatedLap(timer_checkpoint)) 00421 << " " << std::setw(8) << Percent(timer.getMetric<MPICount>().getAccumulatedLap(timer_checkpoint), root_timer.getMetric<MPICount>().getAccumulatedLap(timer_checkpoint)) << end_col; 00422 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<MPIByteCount>::METRIC) 00423 table << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<MPIByteCount>::format(timer.getMetric<MPIByteCount>().getAccumulatedLap(timer_checkpoint)) 00424 << " " << std::setw(8) << Percent(timer.getMetric<MPIByteCount>().getAccumulatedLap(timer_checkpoint), root_timer.getMetric<MPIByteCount>().getAccumulatedLap(timer_checkpoint)) << end_col; 00425 } 00426 else 00427 table << justify(PrintTable::Cell::LEFT) << indent(depth) << span << timer.getName() << end_col; 00428 00429 table << end_row; 00430 depth++; 00431 } 00432 00433 for (TimerList::const_iterator it = timer.begin(); it != timer.end(); ++it) 00434 printSubtable(table, root_timer, *it, metrics_mask, depth, timer_checkpoint); 00435 } 00436 00437 return table; 00438 } 00439 00440 00441 PrintTable & 00442 printSubtable( 00443 PrintTable & table, 00444 const ParallelTimer & root_timer, 00445 const ParallelTimer & timer, 00446 MetricsMask metrics_mask, 00447 int depth, 00448 bool timer_checkpoint) 00449 { 00450 if (timer.m_subtimerLapCount != 0.0) { 00451 if (timer.m_timerMask == 0 || timer.getMetric<LapCount>().m_sum > 0) { 00452 table << justify(PrintTable::Cell::LEFT) << indent(depth) << timer.m_name << end_col 00453 << justify(PrintTable::Cell::RIGHT) << timer.getMetric<LapCount>().m_sum << end_col; 00454 00455 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<CPUTime>::METRIC) 00456 table << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<CPUTime>::format(timer.getMetric<CPUTime>().m_sum) 00457 << " " << std::setw(8) << Percent(timer.getMetric<CPUTime>().m_sum, root_timer.getMetric<CPUTime>().m_sum) << end_col 00458 << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<CPUTime>::format(timer.getMetric<CPUTime>().m_min) 00459 << " " << std::setw(8) << Percent(timer.getMetric<CPUTime>().m_min, root_timer.getMetric<CPUTime>().m_sum) << end_col 00460 << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<CPUTime>::format(timer.getMetric<CPUTime>().m_max) 00461 << " " << std::setw(8) << Percent(timer.getMetric<CPUTime>().m_max, root_timer.getMetric<CPUTime>().m_sum) << end_col; 00462 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<WallTime>::METRIC) 00463 table << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<WallTime>::format(timer.getMetric<WallTime>().m_sum) 00464 << " " << std::setw(8) << Percent(timer.getMetric<WallTime>().m_sum, root_timer.getMetric<WallTime>().m_sum) << end_col 00465 << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<WallTime>::format(timer.getMetric<WallTime>().m_min) 00466 << " " << std::setw(8) << Percent(timer.getMetric<WallTime>().m_min, root_timer.getMetric<WallTime>().m_sum) << end_col 00467 << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<WallTime>::format(timer.getMetric<WallTime>().m_max) 00468 << " " << std::setw(8) << Percent(timer.getMetric<WallTime>().m_max, root_timer.getMetric<WallTime>().m_sum) << end_col; 00469 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<MPICount>::METRIC) 00470 table << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<MPICount>::format(timer.getMetric<MPICount>().m_sum) 00471 << " " << std::setw(8) << Percent(timer.getMetric<MPICount>().m_sum, root_timer.getMetric<MPICount>().m_sum) << end_col 00472 << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<MPICount>::format(timer.getMetric<MPICount>().m_min) 00473 << " " << std::setw(8) << Percent(timer.getMetric<MPICount>().m_min, root_timer.getMetric<MPICount>().m_sum) << end_col 00474 << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<MPICount>::format(timer.getMetric<MPICount>().m_max) 00475 << " " << std::setw(8) << Percent(timer.getMetric<MPICount>().m_max, root_timer.getMetric<MPICount>().m_sum) << end_col; 00476 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<MPIByteCount>::METRIC) 00477 table << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<MPIByteCount>::format(timer.getMetric<MPIByteCount>().m_sum) 00478 << " " << std::setw(8) << Percent(timer.getMetric<MPIByteCount>().m_sum, root_timer.getMetric<MPIByteCount>().m_sum) << end_col 00479 << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<MPIByteCount>::format(timer.getMetric<MPIByteCount>().m_min) 00480 << " " << std::setw(8) << Percent(timer.getMetric<MPIByteCount>().m_min, root_timer.getMetric<MPIByteCount>().m_sum) << end_col 00481 << justify(PrintTable::Cell::RIGHT) << std::setw(12) << MetricTraits<MPIByteCount>::format(timer.getMetric<MPIByteCount>().m_max) 00482 << " " << std::setw(8) << Percent(timer.getMetric<MPIByteCount>().m_max, root_timer.getMetric<MPIByteCount>().m_sum) << end_col; 00483 } 00484 else 00485 table << justify(PrintTable::Cell::LEFT) << indent(depth) << span << timer.m_name << end_col; 00486 00487 table << end_row; 00488 depth++; 00489 } 00490 00491 for (std::list<ParallelTimer>::const_iterator it = timer.m_subtimerList.begin(); it != timer.m_subtimerList.end(); ++it) 00492 printSubtable(table, root_timer, *it, metrics_mask, depth, timer_checkpoint); 00493 00494 return table; 00495 } 00496 00497 00498 PrintTable & 00499 printTable( 00500 PrintTable & table, 00501 Timer & root_timer, 00502 MetricsMask metrics_mask, 00503 size_t name_width, 00504 bool timer_checkpoint) 00505 { 00506 updateRootTimer(root_timer); 00507 00508 root_timer.accumulateSubtimerLapCounts(); 00509 00510 if (metrics_mask & getEnabledTimerMetricsMask()) { 00511 table.setAutoEndCol(false); 00512 00513 table << cell_width(name_width) << justify(PrintTable::Cell::CENTER) << "Timer" << (timer_checkpoint ? " (delta time)" : "") << end_col 00514 << justify(PrintTable::Cell::CENTER) << "Count" << end_col; 00515 00516 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<CPUTime>::METRIC) 00517 table << justify(PrintTable::Cell::CENTER) << MetricTraits<CPUTime>::table_header() << end_col; 00518 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<WallTime>::METRIC) 00519 table << justify(PrintTable::Cell::CENTER) << MetricTraits<WallTime>::table_header() << end_col; 00520 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<MPICount>::METRIC) 00521 table << justify(PrintTable::Cell::CENTER) << MetricTraits<MPICount>::table_header() << end_col; 00522 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<MPIByteCount>::METRIC) 00523 table << justify(PrintTable::Cell::CENTER) << MetricTraits<MPIByteCount>::table_header() << end_col; 00524 00525 table << end_header; 00526 00527 printSubtable(table, root_timer, root_timer, metrics_mask, 0, timer_checkpoint); 00528 00529 if (timer_checkpoint) 00530 root_timer.checkpoint(); 00531 } 00532 00533 return table; 00534 } 00535 00536 00537 PrintTable & 00538 printTable( 00539 PrintTable & table, 00540 Timer & root_timer, 00541 MetricsMask metrics_mask, 00542 size_t name_width, 00543 bool timer_checkpoint, 00544 ParallelMachine parallel_machine) 00545 { 00546 updateRootTimer(root_timer); 00547 00548 root_timer.accumulateSubtimerLapCounts(); 00549 00550 ParallelTimer parallel_timer; 00551 00552 stk::diag::collect_timers(root_timer, parallel_timer, timer_checkpoint, parallel_machine); 00553 00554 int parallel_rank = parallel_machine_rank(parallel_machine); 00555 if (parallel_rank == 0) { 00556 if (metrics_mask & getEnabledTimerMetricsMask()) { 00557 table.setAutoEndCol(false); 00558 00559 table << end_col << end_col; 00560 00561 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<CPUTime>::METRIC) 00562 table << justify(PrintTable::Cell::CENTER) << MetricTraits<CPUTime>::table_header() << end_col 00563 << justify(PrintTable::Cell::CENTER) << MetricTraits<CPUTime>::table_header() << end_col 00564 << justify(PrintTable::Cell::CENTER) << MetricTraits<CPUTime>::table_header() << end_col; 00565 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<WallTime>::METRIC) 00566 table << justify(PrintTable::Cell::CENTER) << MetricTraits<WallTime>::table_header() << end_col 00567 << justify(PrintTable::Cell::CENTER) << MetricTraits<WallTime>::table_header() << end_col 00568 << justify(PrintTable::Cell::CENTER) << MetricTraits<WallTime>::table_header() << end_col; 00569 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<MPICount>::METRIC) 00570 table << justify(PrintTable::Cell::CENTER) << MetricTraits<MPICount>::table_header() << end_col 00571 << justify(PrintTable::Cell::CENTER) << MetricTraits<MPICount>::table_header() << end_col 00572 << justify(PrintTable::Cell::CENTER) << MetricTraits<MPICount>::table_header() << end_col; 00573 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<MPIByteCount>::METRIC) 00574 table << justify(PrintTable::Cell::CENTER) << MetricTraits<MPIByteCount>::table_header() << end_col 00575 << justify(PrintTable::Cell::CENTER) << MetricTraits<MPIByteCount>::table_header() << end_col 00576 << justify(PrintTable::Cell::CENTER) << MetricTraits<MPIByteCount>::table_header() << end_col; 00577 00578 table << end_header; 00579 table << cell_width(name_width) << justify(PrintTable::Cell::CENTER) << "Timer" << (timer_checkpoint ? " (delta time)" : "") << end_col 00580 << justify(PrintTable::Cell::CENTER) << "Count" << end_col; 00581 00582 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<CPUTime>::METRIC) 00583 table << justify(PrintTable::Cell::CENTER) << "Sum (% of System)" << end_col 00584 << justify(PrintTable::Cell::CENTER) << "Min (% of System)" << end_col 00585 << justify(PrintTable::Cell::CENTER) << "Max (% of System)" << end_col; 00586 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<WallTime>::METRIC) 00587 table << justify(PrintTable::Cell::CENTER) << "Sum (% of System)" << end_col 00588 << justify(PrintTable::Cell::CENTER) << "Min (% of System)" << end_col 00589 << justify(PrintTable::Cell::CENTER) << "Max (% of System)" << end_col; 00590 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<MPICount>::METRIC) 00591 table << justify(PrintTable::Cell::CENTER) << "Sum (% of System)" << end_col 00592 << justify(PrintTable::Cell::CENTER) << "Min (% of System)" << end_col 00593 << justify(PrintTable::Cell::CENTER) << "Max (% of System)" << end_col; 00594 if (metrics_mask & getEnabledTimerMetricsMask() & MetricTraits<MPIByteCount>::METRIC) 00595 table << justify(PrintTable::Cell::CENTER) << "Sum (% of System)" << end_col 00596 << justify(PrintTable::Cell::CENTER) << "Min (% of System)" << end_col 00597 << justify(PrintTable::Cell::CENTER) << "Max (% of System)" << end_col; 00598 00599 table << end_header; 00600 00601 printSubtable(table, parallel_timer, parallel_timer, metrics_mask, 0, timer_checkpoint); 00602 } 00603 00604 if (timer_checkpoint) 00605 root_timer.checkpoint(); 00606 } 00607 00608 return table; 00609 } 00610 00611 } // namespace <empty> 00612 00613 00614 std::ostream &printTimersTable(std::ostream& os, Timer root_timer, MetricsMask metrics_mask, bool timer_checkpoint) 00615 { 00616 stk::PrintTable print_table; 00617 00618 printTable(print_table, root_timer, metrics_mask, 40, timer_checkpoint); 00619 00620 os << print_table; 00621 00622 return os; 00623 } 00624 00625 00626 std::ostream &printTimersTable(std::ostream& os, Timer root_timer, MetricsMask metrics_mask, bool timer_checkpoint, ParallelMachine parallel_machine) 00627 { 00628 stk::PrintTable print_table; 00629 00630 int parallel_size = parallel_machine_size(parallel_machine); 00631 if (parallel_size == 1) 00632 printTable(print_table, root_timer, metrics_mask, 40, timer_checkpoint); 00633 else 00634 printTable(print_table, root_timer, metrics_mask, 40, timer_checkpoint, parallel_machine); 00635 00636 os << print_table; 00637 00638 return os; 00639 } 00640 00641 00642 // std::ostream &printXML(std::ostream &os, MPI_Comm mpi_comm, MetricsMask metrics_mask) const; 00643 std::ostream &printXML(std::ostream &os, MetricsMask metrics_mask, bool timer_checkpoint); 00644 00645 std::ostream &printSubXML(std::ostream &os, MetricsMask metrics_mask, int depth, bool timer_checkpoint); 00646 00647 } // namespace diag 00648 00649 Marshal &operator<<(stk::Marshal &mout, const diag::Timer &t); 00650 00651 template <class T> 00652 Marshal &operator<<(Marshal &mout, const diag::Timer::Metric<T> &t) { 00653 mout << t.getAccumulatedLap(false) << t.getAccumulatedLap(true); 00654 00655 return mout; 00656 } 00657 00658 Marshal &operator<<(Marshal &mout, const diag::Timer &t) { 00659 mout << t.getName() << t.getTimerMask() << t.getSubtimerLapCount() 00660 << t.getMetric<diag::LapCount>() << t.getMetric<diag::CPUTime>() << t.getMetric<diag::WallTime>() 00661 << t.getMetric<diag::MPICount>() << t.getMetric<diag::MPIByteCount>(); 00662 00663 mout << t.getTimerList(); 00664 00665 return mout; 00666 } 00667 00668 Marshal &operator>>(Marshal &min, diag::ParallelTimer &t) { 00669 min >> t.m_name >> t.m_timerMask >> t.m_subtimerLapCount 00670 >> t.m_lapCount.m_value 00671 >> t.m_lapCount.m_checkpoint 00672 >> t.m_cpuTime.m_value 00673 >> t.m_cpuTime.m_checkpoint 00674 >> t.m_wallTime.m_value 00675 >> t.m_wallTime.m_checkpoint 00676 >> t.m_MPICount.m_value 00677 >> t.m_MPICount.m_checkpoint 00678 >> t.m_MPIByteCount.m_value 00679 >> t.m_MPIByteCount.m_checkpoint; 00680 00681 min >> t.m_subtimerList; 00682 00683 return min; 00684 } 00685 00686 } // namespace stk