PrintTimer.cpp

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 &parallel_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 &parallel_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 &parallel_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 &parallel_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   const int parallel_root = 0 ;
00332   const int parallel_size = parallel_machine_size(comm);
00333   const int parallel_rank = parallel_machine_rank(comm);
00334 
00335   Marshal mout;
00336   mout << root_timer;
00337 
00338 #ifdef STK_HAS_MPI
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

Generated on Tue Jul 13 09:27:32 2010 for Sierra Toolkit by  doxygen 1.4.7