Sierra Toolkit  Version of the Day
Timer.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010 - 2011 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 #include <math.h>
10 #include <sstream>
11 #include <iomanip>
12 #include <algorithm>
13 #include <functional>
14 #include <stdexcept>
15 #include <limits>
16 
17 #include <sys/times.h>
18 #include <sys/time.h>
19 #include <sys/resource.h>
20 
21 #ifdef __JVN
22 #include <sys/wait.h>
23 #endif
24 
25 #include <stk_util/util/FeatureTest.hpp>
26 
27 #ifdef SIERRA_INCLUDE_LIBPAPI
28 # include <papi.h>
29 # if defined(PAPI_VERSION) && (PAPI_VERSION_MAJOR(PAPI_VERSION) != 3)
30 # error "Compiling against an unknown PAPI version"
31 # endif
32 #endif
33 
34 // #include <fenv.h>
35 #include <math.h>
36 #include <sstream>
37 #include <iomanip>
38 #include <algorithm>
39 #include <functional>
40 #include <stdexcept>
41 #include <limits>
42 
43 #include <stk_util/diag/Writer.hpp>
44 #include <stk_util/diag/Timer.hpp>
45 #include <stk_util/diag/PrintTable.hpp>
46 #include <stk_util/diag/Env.hpp>
47 #include <stk_util/parallel/MPI.hpp>
48 
49 #include <stk_util/util/string_case_compare.hpp>
50 
51 #include <stk_util/diag/WriterExt.hpp>
52 
53 namespace stk_classic {
54 namespace diag {
55 
56 namespace {
57 
58 MetricsMask s_enabledMetricsMask = METRICS_LAP_COUNT | METRICS_CPU_TIME | METRICS_WALL_TIME;
59 
60 template <class T>
61 typename MetricTraits<T>::Type
62 value_now() {
63  if (MetricTraits<T>::METRIC & getEnabledTimerMetricsMask())
64  return MetricTraits<T>::value_now();
65  else
66  return 0;
67 }
68 
69 std::vector<std::string> &
70 split(
71  const std::string & path,
72  char separator,
73  std::vector<std::string> & path_vector)
74 {
75  for (std::string::const_iterator it = path.begin(); ; ) {
76  std::string::const_iterator it2 = std::find(it, path.end(), separator);
77  path_vector.push_back(std::string(it, it2));
78  if (it2 == path.end())
79  break;
80  it = it2 + 1;
81  }
82 
83  return path_vector;
84 }
85 
86 } // namespace <empty>
87 
88 
89 MetricsMask getEnabledTimerMetricsMask()
90 {
91  return s_enabledMetricsMask;
92 }
93 
94 void
95 setEnabledTimerMetricsMask(
96  MetricsMask timer_mask)
97 {
98  s_enabledMetricsMask = timer_mask | METRICS_LAP_COUNT;
99 }
100 
101 
123 class TimerImpl
124 {
125  friend class Timer;
126 
127 public:
128  static void updateRootTimer(TimerImpl *root_timer);
129 
130  static Timer createRootTimer(const std::string &name, const TimerSet &timer_set);
131 
132  static void deleteRootTimer(TimerImpl *root_timer);
133 
134  static std::vector<Timer> &findTimers(TimerImpl *root_timer, const std::string &path_tail, std::vector<Timer> &found_timers);
135 
136  static void findTimer(TimerImpl *timer, std::vector<std::string> &path_tail_vector, std::vector<Timer> &found_timers);
137 
138 private:
148  static TimerImpl *reg(const std::string &name, TimerMask timer_mask, TimerImpl *parent_timer, const TimerSet &timer_set) {
149  return parent_timer->addSubtimer(name, timer_mask, timer_set);
150  }
151 
159  TimerImpl(const std::string &name, TimerMask timer_mask, TimerImpl *parent_timer, const TimerSet &timer_set);
160 
165  ~TimerImpl();
166 
167  TimerImpl(const TimerImpl &TimerImpl);
168  TimerImpl &operator=(const TimerImpl &TimerImpl);
169 
176 #ifdef __INTEL_COMPILER
177 #pragma warning(push)
178 #pragma warning(disable: 444)
179 #endif
180  class finder : private std::unary_function<Timer, bool>
181  {
182  public:
183  explicit finder(const std::string &name)
184  : m_name(name)
185  {}
186 
187  bool operator()(Timer timer) const {
188  return equal_case(timer.getName(), m_name);
189  }
190 
191  private:
192  std::string m_name;
193  };
194 #ifdef __INTEL_COMPILER
195 #pragma warning(pop)
196 #endif
197 
198 public:
205  const std::string &getName() const {
206  return m_name;
207  }
208 
214  TimerMask getTimerMask() const {
215  return m_timerMask;
216  }
217 
223  const TimerSet &getTimerSet() const {
224  return m_timerSet;
225  }
226 
235  bool shouldRecord() const {
236  return m_timerSet.shouldRecord(m_timerMask) && s_enabledMetricsMask;
237  }
238 
245  double getSubtimerLapCount() const {
246  return m_subtimerLapCount;
247  }
248 
249  void setSubtimerLapCount(double value) {
250  m_subtimerLapCount = value;
251  }
252 
260  template <class T>
261  const Timer::Metric<T> &getMetric() const;
262 
270  const TimerList &getTimerList() const {
271  return m_subtimerList;
272  }
273 
274  TimerList::iterator begin() {
275  return m_subtimerList.begin();
276  }
277 
278  TimerList::const_iterator begin() const {
279  return m_subtimerList.begin();
280  }
281 
282  TimerList::iterator end() {
283  return m_subtimerList.end();
284  }
285 
286  TimerList::const_iterator end() const {
287  return m_subtimerList.end();
288  }
289 
294  void reset();
295 
300  void checkpoint() const;
301 
307  TimerImpl &start();
308 
314  TimerImpl &lap();
315 
322  TimerImpl &stop();
323 
331  double accumulateSubtimerLapCounts() const;
332 
333  Timer getSubtimer(const std::string &name);
334 
335 public:
344  Writer &dump(Writer &dout) const;
345 
346 private:
358  TimerImpl *addSubtimer(const std::string &name, TimerMask timer_mask, const TimerSet &timer_set);
359 
360 private:
361  std::string m_name;
362  TimerMask m_timerMask;
363  TimerImpl * m_parentTimer;
364  mutable double m_subtimerLapCount;
365  unsigned m_lapStartCount;
366 
367  TimerList m_subtimerList;
368 
369  const TimerSet & m_timerSet;
370  Timer::Metric<LapCount> m_lapCount;
371  Timer::Metric<CPUTime> m_cpuTime;
372  Timer::Metric<WallTime> m_wallTime;
373  Timer::Metric<MPICount> m_MPICount;
374  Timer::Metric<MPIByteCount> m_MPIByteCount;
375  Timer::Metric<HeapAlloc> m_heapAlloc;
376 };
377 
378 
388 inline Writer &operator<<(Writer &dout, const TimerImpl &timer) {
389  return timer.dump(dout);
390 }
391 
392 
393 void
394 updateRootTimer(
395  Timer root_timer)
396 {
397  TimerImpl::updateRootTimer(root_timer.m_timerImpl);
398 }
399 
400 
401 Timer
402 createRootTimer(
403  const std::string & name,
404  const TimerSet & timer_set)
405 {
406  return TimerImpl::createRootTimer(name, timer_set);
407 }
408 
409 
410 void
411 deleteRootTimer(
412  Timer timer)
413 {
414  TimerImpl::deleteRootTimer(timer.m_timerImpl);
415  timer.m_timerImpl = 0;
416 }
417 
418 
419 std::vector<Timer> &
420 findTimers(Timer root_timer, const std::string &path_tail, std::vector<Timer> &found_timers) {
421  TimerImpl::findTimers(root_timer.m_timerImpl, path_tail, found_timers);
422  return found_timers;
423 }
424 
425 
426 TimerImpl::TimerImpl(
427  const std::string & name,
428  TimerMask timer_mask,
429  TimerImpl * parent_timer,
430  const TimerSet & timer_set)
431  : m_name(name),
432  m_timerMask(timer_mask),
433  m_parentTimer(parent_timer),
434  m_subtimerLapCount(0.0),
435  m_lapStartCount(0),
436  m_subtimerList(),
437  m_timerSet(timer_set)
438 {}
439 
440 
441 TimerImpl::~TimerImpl()
442 {
443  try {
444  for (TimerList::iterator it = m_subtimerList.begin(); it != m_subtimerList.end(); ++it)
445  delete (*it).m_timerImpl;
446  }
447  catch (std::exception &) {
448  }
449 }
450 
451 
452 template<>
453 const Timer::Metric<LapCount> &
454 TimerImpl::getMetric<LapCount>() const {
455  return m_lapCount;
456 }
457 
458 
459 template<>
460 const Timer::Metric<CPUTime> &
461 TimerImpl::getMetric<CPUTime>() const {
462  return m_cpuTime;
463 }
464 
465 
466 template<>
467 const Timer::Metric<WallTime> &
468 TimerImpl::getMetric<WallTime>() const {
469  return m_wallTime;
470 }
471 
472 
473 template<>
474 const Timer::Metric<MPICount> &
475 TimerImpl::getMetric<MPICount>() const {
476  return m_MPICount;
477 }
478 
479 
480 template<>
481 const Timer::Metric<MPIByteCount> &
482 TimerImpl::getMetric<MPIByteCount>() const {
483  return m_MPIByteCount;
484 }
485 
486 
487 template<>
488 const Timer::Metric<HeapAlloc> &
489 TimerImpl::getMetric<HeapAlloc>() const {
490  return m_heapAlloc;
491 }
492 
493 
494 void
496 {
497  m_lapStartCount = 0;
498 
499  m_lapCount.reset();
500  m_cpuTime.reset();
501  m_wallTime.reset();
502  m_MPICount.reset();
503  m_MPIByteCount.reset();
504  m_heapAlloc.reset();
505 }
506 
507 
508 Timer
509 TimerImpl::getSubtimer(
510  const std::string & name)
511 {
512  TimerList::iterator it = std::find_if(m_subtimerList.begin(), m_subtimerList.end(), finder(name));
513 
514  if (it == m_subtimerList.end())
515  throw std::runtime_error("Timer not found");
516  else
517  return *it;
518 }
519 
520 
521 TimerImpl *
522 TimerImpl::addSubtimer(
523  const std::string & name,
524  TimerMask timer_mask,
525  const TimerSet & timer_set)
526 {
527  TimerList::iterator it = std::find_if(m_subtimerList.begin(), m_subtimerList.end(), finder(name));
528 
529  if (it == m_subtimerList.end()) {
530  TimerImpl *timer_impl = new TimerImpl(name, timer_mask, this, timer_set);
531  m_subtimerList.push_back(Timer(timer_impl));
532  return timer_impl;
533  }
534  else
535  return (*it).m_timerImpl;
536 }
537 
538 
539 TimerImpl &
540 TimerImpl::start()
541 {
542  if (shouldRecord()) {
543  if (m_lapStartCount++ == 0) {
544  m_lapCount.m_lapStart = m_lapCount.m_lapStop;
545 
546  m_cpuTime.m_lapStop = m_cpuTime.m_lapStart = value_now<CPUTime>();
547  m_wallTime.m_lapStop = m_wallTime.m_lapStart = value_now<WallTime>();
548  m_MPICount.m_lapStop = m_MPICount.m_lapStart = value_now<MPICount>();
549  m_MPIByteCount.m_lapStop = m_MPIByteCount.m_lapStart = value_now<MPIByteCount>();
550  m_heapAlloc.m_lapStop = m_heapAlloc.m_lapStart = value_now<HeapAlloc>();
551  }
552  }
553 
554  return *this;
555 }
556 
557 
558 TimerImpl &
559 TimerImpl::lap()
560 {
561  if (shouldRecord()) {
562  if (m_lapStartCount > 0) {
563  m_cpuTime.m_lapStop = value_now<CPUTime>();
564  m_wallTime.m_lapStop = value_now<WallTime>();
565  m_MPICount.m_lapStop = value_now<MPICount>();
566  m_MPIByteCount.m_lapStop = value_now<MPIByteCount>();
567  m_heapAlloc.m_lapStop = value_now<HeapAlloc>();
568  }
569  }
570 
571  return *this;
572 }
573 
574 
575 TimerImpl &
576 TimerImpl::stop()
577 {
578  if (shouldRecord()) {
579  if (--m_lapStartCount <= 0) {
580  m_lapStartCount = 0;
581  m_lapCount.m_lapStop++;
582 
583  m_cpuTime.m_lapStop = value_now<CPUTime>();
584  m_wallTime.m_lapStop = value_now<WallTime>();
585  m_MPICount.m_lapStop = value_now<MPICount>();
586  m_MPIByteCount.m_lapStop = value_now<MPIByteCount>();
587  m_heapAlloc.m_lapStop = value_now<HeapAlloc>();
588 
589  m_lapCount.addLap();
590  m_cpuTime.addLap();
591  m_wallTime.addLap();
592  m_MPICount.addLap();
593  m_MPIByteCount.addLap();
594  m_heapAlloc.addLap();
595  }
596  }
597 
598  return *this;
599 }
600 
601 
602 double
603 TimerImpl::accumulateSubtimerLapCounts() const
604 {
605  m_subtimerLapCount = m_lapCount.getAccumulatedLap(false);
606 
607  for (TimerList::const_iterator it = m_subtimerList.begin(); it != m_subtimerList.end(); ++it)
608  (*it).m_timerImpl->accumulateSubtimerLapCounts();
609 
610  for (TimerList::const_iterator it = m_subtimerList.begin(); it != m_subtimerList.end(); ++it)
611  m_subtimerLapCount += (*it).m_timerImpl->m_subtimerLapCount;
612 
613  return m_subtimerLapCount;
614 }
615 
616 
617 void
618 TimerImpl::checkpoint() const
619 {
620  m_lapCount.checkpoint();
621  m_cpuTime.checkpoint();
622  m_wallTime.checkpoint();
623  m_MPICount.checkpoint();
624  m_MPIByteCount.checkpoint();
625  m_heapAlloc.checkpoint();
626 
627  for (TimerList::const_iterator it = m_subtimerList.begin(); it != m_subtimerList.end(); ++it)
628  (*it).m_timerImpl->checkpoint();
629 }
630 
631 
632 void
633 TimerImpl::updateRootTimer(TimerImpl *root_timer)
634 {
635  root_timer->m_lapCount.m_lapStop = value_now<LapCount>();
636  root_timer->m_cpuTime.m_lapStop = value_now<CPUTime>();
637  root_timer->m_wallTime.m_lapStop = value_now<WallTime>();
638  root_timer->m_MPICount.m_lapStop = value_now<MPICount>();
639  root_timer->m_MPIByteCount.m_lapStop = value_now<MPIByteCount>();
640  root_timer->m_heapAlloc.m_lapStop = value_now<HeapAlloc>();
641 
642  root_timer->m_lapCount.m_accumulatedLap = root_timer->m_lapCount.m_lapStop - root_timer->m_lapCount.m_lapStart;
643  root_timer->m_cpuTime.m_accumulatedLap = root_timer->m_cpuTime.m_lapStop - root_timer->m_cpuTime.m_lapStart;
644  root_timer->m_wallTime.m_accumulatedLap = root_timer->m_wallTime.m_lapStop - root_timer->m_wallTime.m_lapStart;
645  root_timer->m_MPICount.m_accumulatedLap = root_timer->m_MPICount.m_lapStop - root_timer->m_MPICount.m_lapStart;
646  root_timer->m_MPIByteCount.m_accumulatedLap = root_timer->m_MPIByteCount.m_lapStop - root_timer->m_MPIByteCount.m_lapStart;
647  root_timer->m_heapAlloc.m_accumulatedLap = root_timer->m_heapAlloc.m_lapStop - root_timer->m_heapAlloc.m_lapStart;
648 }
649 
650 
651 
652 Timer
653 TimerImpl::createRootTimer(
654  const std::string & name,
655  const TimerSet & timer_set)
656 {
657  TimerImpl *timer_impl = new TimerImpl(name, 0, 0, timer_set);
658  return Timer(timer_impl);
659 }
660 
661 
662 void
663 TimerImpl::deleteRootTimer(
664  TimerImpl * root_timer)
665 {
666  delete root_timer;
667 }
668 
669 
670 void
671 TimerImpl::findTimer(
672  TimerImpl * timer,
673  std::vector<std::string> & path_tail_vector,
674  std::vector<Timer> & found_timers)
675 {
676  if (timer->begin() == timer->end()) { // at leaf
677 
678  }
679  else
680  for (TimerList::const_iterator it = timer->begin(); it != timer->end(); ++it)
681  findTimer((*it).m_timerImpl, path_tail_vector, found_timers);
682 }
683 
684 
685 std::vector<Timer> &
686 TimerImpl::findTimers(
687  TimerImpl * root_timer,
688  const std::string & path_tail,
689  std::vector<Timer> & found_timers)
690 {
691  std::vector<std::string> path_tail_vector;
692 
693  findTimer(root_timer, split(path_tail, '.', path_tail_vector), found_timers);
694 
695  return found_timers;
696 }
697 
698 
699 
700 Writer &
702  Writer & dout) const
703 {
704  if (dout.shouldPrint()) {
705  dout << "TimerImpl" << push << dendl;
706  dout << "m_name, " << m_name << dendl;
707  dout << "m_timerMask, " << m_timerMask << dendl;
708 // dout << "m_parentTimer, " << c_ptr_name(m_parentTimer) << dendl;
709  dout << "m_subtimerLapCount, " << m_subtimerLapCount << dendl;
710  dout << "m_lapStartCount, " << m_lapStartCount << dendl;
711 
712  dout << "m_lapCount, " << m_lapCount << dendl;
713  dout << "m_cpuTime, " << m_cpuTime << dendl;
714  dout << "m_wallTime, " << m_wallTime << dendl;
715  dout << "m_MPICount, " << m_MPICount << dendl;
716  dout << "m_MPIByteCount, " << m_MPIByteCount << dendl;
717  dout << "m_heapAlloc, " << m_heapAlloc << dendl;
718 
719  dout << "m_subtimerList, " << m_subtimerList << dendl;
720  dout << pop;
721  }
722 
723  return dout;
724 }
725 
726 
727 Timer::Timer(const std::string &name, const Timer parent)
728  : m_timerImpl(TimerImpl::reg(name, parent.getTimerMask(), parent.m_timerImpl, parent.getTimerSet()))
729 {}
730 
731 Timer::Timer(const std::string &name, TimerMask timer_mask, const Timer parent)
732  : m_timerImpl(TimerImpl::reg(name, timer_mask, parent.m_timerImpl, parent.getTimerSet()))
733 {}
734 
735 Timer::Timer(const std::string &name, const Timer parent, const TimerSet &timer_set)
736  : m_timerImpl(TimerImpl::reg(name, parent.getTimerMask(), parent.m_timerImpl, timer_set))
737 {}
738 
739 Timer::Timer(const std::string &name, TimerMask timer_mask, const Timer parent, const TimerSet &timer_set)
740  : m_timerImpl(TimerImpl::reg(name, timer_mask, parent.m_timerImpl, timer_set))
741 {}
742 
743 
744 const std::string &
745 Timer::getName() const {
746  return m_timerImpl->m_name;
747 }
748 
749 TimerMask
751  return m_timerImpl->getTimerMask();
752 }
753 
754 const TimerSet &
756  return m_timerImpl->getTimerSet();
757 }
758 
759 double
761  return m_timerImpl->getSubtimerLapCount();
762 }
763 
764 const TimerList &
765 Timer::getTimerList() const {
766  return m_timerImpl->getTimerList();
767 }
768 
769 template<class T>
770 const Timer::Metric<T> &
772  return m_timerImpl->getMetric<T>();
773 }
774 
775 template const Timer::Metric<LapCount> &Timer::getMetric<LapCount>() const;
776 template const Timer::Metric<CPUTime> &Timer::getMetric<CPUTime>() const;
777 template const Timer::Metric<WallTime> &Timer::getMetric<WallTime>() const;
778 template const Timer::Metric<MPICount> &Timer::getMetric<MPICount>() const;
779 template const Timer::Metric<MPIByteCount> &Timer::getMetric<MPIByteCount>() const;
780 template const Timer::Metric<HeapAlloc> &Timer::getMetric<HeapAlloc>() const;
781 
782 
783 bool
784 Timer::shouldRecord() const
785 {
786  return m_timerImpl->shouldRecord();
787 }
788 
789 TimerList::iterator
790 Timer::begin()
791 {
792  return m_timerImpl->begin();
793 }
794 
795 TimerList::const_iterator
796 Timer::begin() const
797 {
798  return m_timerImpl->begin();
799 }
800 
801 TimerList::iterator
802 Timer::end()
803 {
804  return m_timerImpl->end();
805 }
806 
807 TimerList::const_iterator
808 Timer::end() const
809 {
810  return m_timerImpl->end();
811 }
812 
813 double
815  return m_timerImpl->accumulateSubtimerLapCounts();
816 }
817 
818 Timer &
820  m_timerImpl->start();
821  return *this;
822 }
823 
824 Timer &
826  m_timerImpl->lap();
827  return *this;
828 }
829 
830 Timer &
832  m_timerImpl->stop();
833  return *this;
834 }
835 
836 void
838  m_timerImpl->checkpoint();
839 }
840 
841 Writer &
842 Timer::dump(Writer& dout) const {
843  return m_timerImpl->dump(dout);
844 }
845 
846 template <class T>
847 Writer &
849  Writer & dout) const
850 {
851  if (dout.shouldPrint()) {
852  dout << "Timer::Metric<T>" << push << dendl;
853  dout << "m_lapStart, " << m_lapStart << dendl;
854  dout << "m_lapStop, " << m_lapStop << dendl;
855  dout << "m_accumulatedLap, " << m_accumulatedLap << dendl;
856  dout << "m_checkpoint, " << m_checkpoint << dendl;
857  dout << pop;
858  }
859  return dout;
860 }
861 
862 template Writer &Timer::Metric<LapCount>::dump(Writer &) const;
863 template Writer &Timer::Metric<CPUTime>::dump(Writer &) const;
864 template Writer &Timer::Metric<WallTime>::dump(Writer &) const;
865 template Writer &Timer::Metric<MPICount>::dump(Writer &) const;
867 template Writer &Timer::Metric<HeapAlloc>::dump(Writer &) const;
868 
869 
871  Timer & timer,
872  MPI_Comm mpi_comm,
873  bool start_timer)
874  : m_timer(timer),
875  m_mpiComm(mpi_comm),
876  m_started(start_timer)
877 {
878  if (m_timer.m_timerImpl->shouldRecord()) {
879 #ifdef STK_HAS_MPI
880  if (mpi_comm != MPI_COMM_NULL)
881  MPI_Barrier(mpi_comm);
882 #endif
883 
884  if (start_timer)
885  m_timer.start();
886  }
887 }
888 
889 
891 {
892  if (m_started) {
893  try {
894  m_timer.stop();
895  }
896  catch (...) {
897  }
898  }
899 }
900 
901 
902 void
904 {
905  // Place barrier here
906  MPI_Barrier(m_mpiComm);
907  m_started = true;
908  m_timer.start();
909 }
910 
911 
912 void
914 {
915  m_started = false;
916  m_timer.stop();
917  // Does a barrier need to be here?
918  // MPI_Barrier(Env::parallel_comm());
919 }
920 
921 } // namespace diag
922 } // namespace stk_classic
923 
924 
925 
926 #ifdef SIERRA_INCLUDE_LIBPAPI
927 class PAPIRuntimeError : public std::runtime_error
928 {
929 public:
930  PAPIRuntimeError(const char *message, int status)
931  : std::runtime_error(message),
932  m_status(status)
933  {}
934 
935  virtual const char *what() const throw() {
936  static std::string message;
937  static char papi_message[PAPI_MAX_STR_LEN];
938 
939  PAPI_perror(m_status, papi_message, sizeof(papi_message));
940 
941  message = std::runtime_error::what();
942  message += papi_message;
943 
944  return message.c_str();
945  }
946 
947 private:
948  int m_status;
949 };
950 #endif
951 
952 
953 namespace sierra {
954 namespace Diag {
955 
956 namespace {
957 
958 size_t
959 s_timerNameMaxWidth = DEFAULT_TIMER_NAME_MAX_WIDTH;
960 
961 } // namespace
962 
963 
964 //
965 // SierraRootTimer member functions:
966 //
967 SierraRootTimer::SierraRootTimer()
968  : m_sierraTimer(stk_classic::diag::createRootTimer("Sierra", sierraTimerSet()))
969 { }
970 
971 
972 SierraRootTimer::~SierraRootTimer()
973 {
974  stk_classic::diag::deleteRootTimer(m_sierraTimer);
975 }
976 
977 
978 stk_classic::diag::Timer & SierraRootTimer::sierraTimer()
979 {
980  return m_sierraTimer;
981 }
982 
983 
984 TimerSet &
985 sierraTimerSet()
986 {
987  static TimerSet s_sierraTimerSet(TIMER_PROCEDURE | TIMER_REGION);
988 
989  return s_sierraTimerSet;
990 }
991 
992 
993 boost::shared_ptr<SierraRootTimer> sierraRootTimer()
994 {
995  static boost::shared_ptr<SierraRootTimer> s_sierraRootTimer(new SierraRootTimer());
996  if ( ! s_sierraRootTimer ) {
997  s_sierraRootTimer.reset(new SierraRootTimer());
998  }
999  return s_sierraRootTimer;
1000 }
1001 
1002 
1003 Timer &
1004 sierraTimer()
1005 {
1006  return sierraRootTimer()->sierraTimer();
1007 }
1008 
1009 void
1010 sierraTimerDestroy()
1011 {
1012  sierraRootTimer().reset();
1013 }
1014 
1015 
1016 void
1017 setEnabledTimerMask(
1018  TimerMask timer_mask)
1019 {
1020  sierraTimerSet().setEnabledTimerMask(timer_mask);
1021 }
1022 
1023 
1024 TimerMask
1025 getEnabledTimerMask()
1026 {
1027  return sierraTimerSet().getEnabledTimerMask();
1028 }
1029 
1030 
1031 void
1032 setTimeFormat(int time_format) {
1033  stk_classic::diag::setTimerTimeFormat(time_format);
1034 }
1035 
1036 
1037 void
1038 setTimeFormatMillis()
1039 {
1040  if ((getTimeFormat() & stk_classic::TIMEFORMAT_STYLE_MASK ) == stk_classic::TIMEFORMAT_HMS) {
1041  if (getSierraWallTime() > 3600.0)
1042  setTimeFormat(getTimeFormat() & ~stk_classic::TIMEFORMAT_MILLIS);
1043  else
1044  setTimeFormat(getTimeFormat() | stk_classic::TIMEFORMAT_MILLIS);
1045  }
1046  else if ((getTimeFormat() & stk_classic::TIMEFORMAT_STYLE_MASK ) == stk_classic::TIMEFORMAT_SECONDS) {
1047  if (getSierraWallTime() > 1000.0)
1048  setTimeFormat(getTimeFormat() & ~stk_classic::TIMEFORMAT_MILLIS);
1049  else
1050  setTimeFormat(getTimeFormat() | stk_classic::TIMEFORMAT_MILLIS);
1051  }
1052 }
1053 
1054 
1055 int
1056 getTimeFormat()
1057 {
1058  return stk_classic::diag::getTimerTimeFormat();
1059 }
1060 
1061 
1062 void
1063 setTimerNameMaxWidth(
1064  size_t width)
1065 {
1066  s_timerNameMaxWidth = width;
1067 }
1068 
1069 
1070 size_t
1071 getTimerNameMaxWidth()
1072 {
1073  return s_timerNameMaxWidth;
1074 }
1075 
1076 
1077 stk_classic::diag::MetricTraits<stk_classic::diag::CPUTime>::Type
1078 getSierraCPUTime()
1079 {
1080  return sierraTimer().getMetric<stk_classic::diag::CPUTime>().getAccumulatedLap(false);
1081 }
1082 
1083 
1084 stk_classic::diag::MetricTraits<stk_classic::diag::WallTime>::Type
1085 getSierraWallTime()
1086 {
1087  return sierraTimer().getMetric<stk_classic::diag::WallTime>().getAccumulatedLap(false);
1088 }
1089 
1090 
1091 stk_classic::diag::MetricTraits<stk_classic::diag::CPUTime>::Type
1092 getCPULapTime(Timer timer) {
1093  return timer.getMetric<stk_classic::diag::CPUTime>().getLap();
1094 }
1095 
1096 stk_classic::diag::MetricTraits<stk_classic::diag::CPUTime>::Type
1097 getCPUAccumulatedLapTime(Timer timer) {
1098  return timer.getMetric<stk_classic::diag::CPUTime>().getAccumulatedLap(false);
1099 }
1100 
1101 
1102 TimerParser &
1103 theTimerParser()
1104 {
1105  static TimerParser parser;
1106 
1107  return parser;
1108 }
1109 
1110 
1111 TimerParser::TimerParser()
1113 {
1114  mask("cpu", 0, "Display CPU times");
1115  mask("wall", 0, "Display wall times");
1116 
1117  mask("hms", 0, "Display times in HH:MM:SS format");
1118  mask("seconds", 0, "Display times in seconds");
1119 
1120 
1121 // mask("table", TIMER_TABLE, "Format output as a table");
1122 // mask("xml", TIMER_XML, "Format output as an XML file");
1123 
1124  mask("all", TIMER_ALL, "Enable all metrics");
1125  mask("none", TIMER_NONE, "Disable all timers");
1126 
1127  mask("domain", TIMER_DOMAIN, "Enable metrics on the domain");
1128  mask("region", TIMER_REGION, "Enable metrics on regions");
1129  mask("procedure", TIMER_PROCEDURE, "Enable metrics on procedures");
1130  mask("mechanics", TIMER_MECHANICS, "Enable metrics on mechanics");
1131  mask("algorithm", TIMER_ALGORITHM, "Enable metrics on algorithms");
1132  mask("solver", TIMER_SOLVER, "Enable metrics on solvers");
1133  mask("contact", TIMER_CONTACT, "Enable metrics on contact");
1134  mask("material", TIMER_MATERIAL, "Enable metrics on materials");
1135  mask("search", TIMER_SEARCH, "Enable metrics on searches");
1136  mask("transfer", TIMER_TRANSFER, "Enable metrics on user functions");
1137  mask("adaptivity", TIMER_ADAPTIVITY, "Enable metrics on adaptivity");
1138  mask("recovery", TIMER_RECOVERY, "Enable metrics on encore recovery");
1139  mask("profile1", TIMER_PROFILE_1, "Enable app defined profiling metrics");
1140  mask("profile2", TIMER_PROFILE_2, "Enable app defined profiling metrics");
1141  mask("profile3", TIMER_PROFILE_3, "Enable app defined profiling metrics");
1142  mask("profile4", TIMER_PROFILE_4, "Enable app defined profiling metrics");
1143  mask("app1", TIMER_APP_1, "Enable app defined metrics");
1144  mask("app2", TIMER_APP_2, "Enable app defined metrics");
1145  mask("app3", TIMER_APP_3, "Enable app defined metrics");
1146  mask("app4", TIMER_APP_4, "Enable app defined metrics");
1147 }
1148 
1149 
1152  const char * mask) const
1153 {
1154  m_metricsSetMask = 0;
1155  m_metricsMask = 0;
1156  m_optionMask = getEnabledTimerMask();
1157 
1159 
1160 // if ((m_optionMask & TIMER_FORMAT) == 0)
1161 // m_optionMask |= TIMER_TABLE;
1162 
1163  setEnabledTimerMask(m_optionMask);
1164 
1165  if (m_metricsSetMask != 0)
1166  stk_classic::diag::setEnabledTimerMetricsMask(m_metricsMask);
1167 
1168  return m_optionMask;
1169 }
1170 
1171 
1172 void
1174  const std::string & name,
1175  const std::string & arg) const
1176 {
1177  if (name == "cpu") {
1178  m_metricsMask |= stk_classic::diag::METRICS_CPU_TIME;
1179  m_metricsSetMask |= stk_classic::diag::METRICS_CPU_TIME;
1180  }
1181  else if (name == "wall") {
1182  m_metricsMask |= stk_classic::diag::METRICS_WALL_TIME;
1183  m_metricsSetMask |= stk_classic::diag::METRICS_WALL_TIME;
1184  }
1185  else if (name == "heap") {
1186  m_metricsMask |= stk_classic::diag::METRICS_HEAP_ALLOC;
1187  m_metricsSetMask |= stk_classic::diag::METRICS_HEAP_ALLOC;
1188  }
1189  else if (name == "none") {
1190  m_optionMask = 0;
1191  m_metricsSetMask = stk_classic::diag::METRICS_WALL_TIME | stk_classic::diag::METRICS_CPU_TIME;
1192  }
1193 
1194  else if (name == "hms") {
1195  Diag::setTimeFormat(stk_classic::TIMEFORMAT_HMS);
1196  }
1197  else if (name == "seconds") {
1198  Diag::setTimeFormat(stk_classic::TIMEFORMAT_SECONDS);
1199  }
1200 
1201  else
1202  OptionMaskParser::parseArg(name, arg);
1203 }
1204 
1205 } // namespace Diag
1206 } // namespace sierra
CPU runtime metric tag.
std::ostream & dout()
Diagnostic output stream.
Definition: OutputLog.cpp:674
TimerMask getEnabledTimerMask() const
Definition: Timer.hpp:145
Definition: Env.cpp:53
Timer(const std::string &name, const Timer parent)
Definition: Timer.cpp:727
virtual void parseArg(const std::string &name, const std::string &arg) const
Definition: Option.cpp:93
void setEnabledTimerMask(TimerMask timer_mask)
Definition: Timer.hpp:157
double getSubtimerLapCount() const
Definition: Timer.cpp:760
bool shouldRecord(TimerMask timer_mask) const
Definition: Timer.hpp:169
void mask(const std::string &name, const Mask l_mask, const std::string &description)
Definition: Option.hpp:332
OptionMask m_optionMask
Most recently parsed mask.
Definition: Option.hpp:346
std::ostream & operator<<(std::ostream &s, const Bucket &k)
Print the part names for which this bucket is a subset.
Definition: Bucket.cpp:239
void checkpoint() const
Definition: Timer.cpp:837
virtual Mask parse(const char *mask) const
Definition: Option.cpp:15
Writer & dendl(Writer &dout)
Writer function dendl calls the Writer::dendl manipulator.
Definition: Writer.hpp:520
Writer & dump(Writer &dout, const std::vector< T > &t)
Template dump prints the object contained within a std::vector object to the diagnostic writer...
Definition: WriterExt.hpp:115
TimerMask getTimerMask() const
Definition: Timer.cpp:750
Writer & dump(Writer &dout) const
Definition: Timer.cpp:842
Mask parse(const char *mask_string) const
Member function parse parses the mask string and generates the corresponding bit mask.
Definition: Timer.cpp:1151
Class TimerSet implements a set of timer classifications. A time classification consists of a bit mas...
Definition: Timer.hpp:117
Sierra Toolkit.
TimeBlockSynchronized(Timer &timer, ParallelMachine mpi_comm, bool start_timer=true)
Definition: Timer.cpp:870
const TimerSet & getTimerSet() const
Definition: Timer.cpp:755
Class Writer implements a runtime selectable diagnostic output writer to aid in the development and d...
Definition: Writer.hpp:49
bool equal_case(const char *lhs, const char *rhs)
Case-insensitive equality compare.
virtual void parseArg(const std::string &name, const std::string &arg) const
Definition: Timer.cpp:1173
void reset(MPI_Comm new_comm)
Function reset determines new parallel_size and parallel_rank. Flushes, closes, and reopens log files...
Definition: Env.cpp:1067
OptionMask Mask
Mask for this option.
Definition: Option.hpp:261
Wall clock metric tag.
double accumulateSubtimerLapCounts() const
Definition: Timer.cpp:814
const std::string & getName() const
Definition: Timer.cpp:745
const Metric< T > & getMetric() const
Definition: Timer.cpp:771
Writer & dump(Writer &dout) const
Definition: Timer.cpp:848
Part * find(const PartVector &parts, const std::string &name)
Find a part by name in a collection of parts.
Definition: Part.cpp:22
Class Timer implements a diagnostic timer and timer container for the collection and display of execu...
Definition: Timer.hpp:185