|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 - 2011 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 <math.h> 00010 #include <sstream> 00011 #include <iomanip> 00012 #include <algorithm> 00013 #include <functional> 00014 #include <stdexcept> 00015 #include <limits> 00016 00017 #include <sys/times.h> 00018 #include <sys/time.h> 00019 #include <sys/resource.h> 00020 00021 #ifdef __JVN 00022 #include <sys/wait.h> 00023 #endif 00024 00025 #include <stk_util/util/FeatureTest.hpp> 00026 00027 #ifdef SIERRA_INCLUDE_LIBPAPI 00028 # include <papi.h> 00029 # if defined(PAPI_VERSION) && (PAPI_VERSION_MAJOR(PAPI_VERSION) != 3) 00030 # error "Compiling against an unknown PAPI version" 00031 # endif 00032 #endif 00033 00034 // #include <fenv.h> 00035 #include <math.h> 00036 #include <sstream> 00037 #include <iomanip> 00038 #include <algorithm> 00039 #include <functional> 00040 #include <stdexcept> 00041 #include <limits> 00042 00043 #include <stk_util/diag/Writer.hpp> 00044 #include <stk_util/diag/Timer.hpp> 00045 #include <stk_util/diag/PrintTable.hpp> 00046 #include <stk_util/diag/Env.hpp> 00047 #include <stk_util/parallel/MPI.hpp> 00048 00049 #include <stk_util/util/string_case_compare.hpp> 00050 00051 #include <stk_util/diag/WriterExt.hpp> 00052 00053 namespace stk_classic { 00054 namespace diag { 00055 00056 namespace { 00057 00058 MetricsMask s_enabledMetricsMask = METRICS_LAP_COUNT | METRICS_CPU_TIME | METRICS_WALL_TIME; 00059 00060 template <class T> 00061 typename MetricTraits<T>::Type 00062 value_now() { 00063 if (MetricTraits<T>::METRIC & getEnabledTimerMetricsMask()) 00064 return MetricTraits<T>::value_now(); 00065 else 00066 return 0; 00067 } 00068 00069 std::vector<std::string> & 00070 split( 00071 const std::string & path, 00072 char separator, 00073 std::vector<std::string> & path_vector) 00074 { 00075 for (std::string::const_iterator it = path.begin(); ; ) { 00076 std::string::const_iterator it2 = std::find(it, path.end(), separator); 00077 path_vector.push_back(std::string(it, it2)); 00078 if (it2 == path.end()) 00079 break; 00080 it = it2 + 1; 00081 } 00082 00083 return path_vector; 00084 } 00085 00086 } // namespace <empty> 00087 00088 00089 MetricsMask getEnabledTimerMetricsMask() 00090 { 00091 return s_enabledMetricsMask; 00092 } 00093 00094 void 00095 setEnabledTimerMetricsMask( 00096 MetricsMask timer_mask) 00097 { 00098 s_enabledMetricsMask = timer_mask | METRICS_LAP_COUNT; 00099 } 00100 00101 00123 class TimerImpl 00124 { 00125 friend class Timer; 00126 00127 public: 00128 static void updateRootTimer(TimerImpl *root_timer); 00129 00130 static Timer createRootTimer(const std::string &name, const TimerSet &timer_set); 00131 00132 static void deleteRootTimer(TimerImpl *root_timer); 00133 00134 static std::vector<Timer> &findTimers(TimerImpl *root_timer, const std::string &path_tail, std::vector<Timer> &found_timers); 00135 00136 static void findTimer(TimerImpl *timer, std::vector<std::string> &path_tail_vector, std::vector<Timer> &found_timers); 00137 00138 private: 00148 static TimerImpl *reg(const std::string &name, TimerMask timer_mask, TimerImpl *parent_timer, const TimerSet &timer_set) { 00149 return parent_timer->addSubtimer(name, timer_mask, timer_set); 00150 } 00151 00159 TimerImpl(const std::string &name, TimerMask timer_mask, TimerImpl *parent_timer, const TimerSet &timer_set); 00160 00165 ~TimerImpl(); 00166 00167 TimerImpl(const TimerImpl &TimerImpl); 00168 TimerImpl &operator=(const TimerImpl &TimerImpl); 00169 00176 #ifdef __INTEL_COMPILER 00177 #pragma warning(push) 00178 #pragma warning(disable: 444) 00179 #endif 00180 class finder : private std::unary_function<Timer, bool> 00181 { 00182 public: 00183 explicit finder(const std::string &name) 00184 : m_name(name) 00185 {} 00186 00187 bool operator()(Timer timer) const { 00188 return equal_case(timer.getName(), m_name); 00189 } 00190 00191 private: 00192 std::string m_name; 00193 }; 00194 #ifdef __INTEL_COMPILER 00195 #pragma warning(pop) 00196 #endif 00197 00198 public: 00205 const std::string &getName() const { 00206 return m_name; 00207 } 00208 00214 TimerMask getTimerMask() const { 00215 return m_timerMask; 00216 } 00217 00223 const TimerSet &getTimerSet() const { 00224 return m_timerSet; 00225 } 00226 00235 bool shouldRecord() const { 00236 return m_timerSet.shouldRecord(m_timerMask) && s_enabledMetricsMask; 00237 } 00238 00245 double getSubtimerLapCount() const { 00246 return m_subtimerLapCount; 00247 } 00248 00249 void setSubtimerLapCount(double value) { 00250 m_subtimerLapCount = value; 00251 } 00252 00260 template <class T> 00261 const Timer::Metric<T> &getMetric() const; 00262 00270 const TimerList &getTimerList() const { 00271 return m_subtimerList; 00272 } 00273 00274 TimerList::iterator begin() { 00275 return m_subtimerList.begin(); 00276 } 00277 00278 TimerList::const_iterator begin() const { 00279 return m_subtimerList.begin(); 00280 } 00281 00282 TimerList::iterator end() { 00283 return m_subtimerList.end(); 00284 } 00285 00286 TimerList::const_iterator end() const { 00287 return m_subtimerList.end(); 00288 } 00289 00294 void reset(); 00295 00300 void checkpoint() const; 00301 00307 TimerImpl &start(); 00308 00314 TimerImpl &lap(); 00315 00322 TimerImpl &stop(); 00323 00331 double accumulateSubtimerLapCounts() const; 00332 00333 Timer getSubtimer(const std::string &name); 00334 00335 public: 00344 Writer &dump(Writer &dout) const; 00345 00346 private: 00358 TimerImpl *addSubtimer(const std::string &name, TimerMask timer_mask, const TimerSet &timer_set); 00359 00360 private: 00361 std::string m_name; 00362 TimerMask m_timerMask; 00363 TimerImpl * m_parentTimer; 00364 mutable double m_subtimerLapCount; 00365 unsigned m_lapStartCount; 00366 00367 TimerList m_subtimerList; 00368 00369 const TimerSet & m_timerSet; 00370 Timer::Metric<LapCount> m_lapCount; 00371 Timer::Metric<CPUTime> m_cpuTime; 00372 Timer::Metric<WallTime> m_wallTime; 00373 Timer::Metric<MPICount> m_MPICount; 00374 Timer::Metric<MPIByteCount> m_MPIByteCount; 00375 Timer::Metric<HeapAlloc> m_heapAlloc; 00376 }; 00377 00378 00388 inline Writer &operator<<(Writer &dout, const TimerImpl &timer) { 00389 return timer.dump(dout); 00390 } 00391 00392 00393 void 00394 updateRootTimer( 00395 Timer root_timer) 00396 { 00397 TimerImpl::updateRootTimer(root_timer.m_timerImpl); 00398 } 00399 00400 00401 Timer 00402 createRootTimer( 00403 const std::string & name, 00404 const TimerSet & timer_set) 00405 { 00406 return TimerImpl::createRootTimer(name, timer_set); 00407 } 00408 00409 00410 void 00411 deleteRootTimer( 00412 Timer timer) 00413 { 00414 TimerImpl::deleteRootTimer(timer.m_timerImpl); 00415 timer.m_timerImpl = 0; 00416 } 00417 00418 00419 std::vector<Timer> & 00420 findTimers(Timer root_timer, const std::string &path_tail, std::vector<Timer> &found_timers) { 00421 TimerImpl::findTimers(root_timer.m_timerImpl, path_tail, found_timers); 00422 return found_timers; 00423 } 00424 00425 00426 TimerImpl::TimerImpl( 00427 const std::string & name, 00428 TimerMask timer_mask, 00429 TimerImpl * parent_timer, 00430 const TimerSet & timer_set) 00431 : m_name(name), 00432 m_timerMask(timer_mask), 00433 m_parentTimer(parent_timer), 00434 m_subtimerLapCount(0.0), 00435 m_lapStartCount(0), 00436 m_subtimerList(), 00437 m_timerSet(timer_set) 00438 {} 00439 00440 00441 TimerImpl::~TimerImpl() 00442 { 00443 try { 00444 for (TimerList::iterator it = m_subtimerList.begin(); it != m_subtimerList.end(); ++it) 00445 delete (*it).m_timerImpl; 00446 } 00447 catch (std::exception &) { 00448 } 00449 } 00450 00451 00452 template<> 00453 const Timer::Metric<LapCount> & 00454 TimerImpl::getMetric<LapCount>() const { 00455 return m_lapCount; 00456 } 00457 00458 00459 template<> 00460 const Timer::Metric<CPUTime> & 00461 TimerImpl::getMetric<CPUTime>() const { 00462 return m_cpuTime; 00463 } 00464 00465 00466 template<> 00467 const Timer::Metric<WallTime> & 00468 TimerImpl::getMetric<WallTime>() const { 00469 return m_wallTime; 00470 } 00471 00472 00473 template<> 00474 const Timer::Metric<MPICount> & 00475 TimerImpl::getMetric<MPICount>() const { 00476 return m_MPICount; 00477 } 00478 00479 00480 template<> 00481 const Timer::Metric<MPIByteCount> & 00482 TimerImpl::getMetric<MPIByteCount>() const { 00483 return m_MPIByteCount; 00484 } 00485 00486 00487 template<> 00488 const Timer::Metric<HeapAlloc> & 00489 TimerImpl::getMetric<HeapAlloc>() const { 00490 return m_heapAlloc; 00491 } 00492 00493 00494 void 00495 TimerImpl::reset() 00496 { 00497 m_lapStartCount = 0; 00498 00499 m_lapCount.reset(); 00500 m_cpuTime.reset(); 00501 m_wallTime.reset(); 00502 m_MPICount.reset(); 00503 m_MPIByteCount.reset(); 00504 m_heapAlloc.reset(); 00505 } 00506 00507 00508 Timer 00509 TimerImpl::getSubtimer( 00510 const std::string & name) 00511 { 00512 TimerList::iterator it = std::find_if(m_subtimerList.begin(), m_subtimerList.end(), finder(name)); 00513 00514 if (it == m_subtimerList.end()) 00515 throw std::runtime_error("Timer not found"); 00516 else 00517 return *it; 00518 } 00519 00520 00521 TimerImpl * 00522 TimerImpl::addSubtimer( 00523 const std::string & name, 00524 TimerMask timer_mask, 00525 const TimerSet & timer_set) 00526 { 00527 TimerList::iterator it = std::find_if(m_subtimerList.begin(), m_subtimerList.end(), finder(name)); 00528 00529 if (it == m_subtimerList.end()) { 00530 TimerImpl *timer_impl = new TimerImpl(name, timer_mask, this, timer_set); 00531 m_subtimerList.push_back(Timer(timer_impl)); 00532 return timer_impl; 00533 } 00534 else 00535 return (*it).m_timerImpl; 00536 } 00537 00538 00539 TimerImpl & 00540 TimerImpl::start() 00541 { 00542 if (shouldRecord()) { 00543 if (m_lapStartCount++ == 0) { 00544 m_lapCount.m_lapStart = m_lapCount.m_lapStop; 00545 00546 m_cpuTime.m_lapStop = m_cpuTime.m_lapStart = value_now<CPUTime>(); 00547 m_wallTime.m_lapStop = m_wallTime.m_lapStart = value_now<WallTime>(); 00548 m_MPICount.m_lapStop = m_MPICount.m_lapStart = value_now<MPICount>(); 00549 m_MPIByteCount.m_lapStop = m_MPIByteCount.m_lapStart = value_now<MPIByteCount>(); 00550 m_heapAlloc.m_lapStop = m_heapAlloc.m_lapStart = value_now<HeapAlloc>(); 00551 } 00552 } 00553 00554 return *this; 00555 } 00556 00557 00558 TimerImpl & 00559 TimerImpl::lap() 00560 { 00561 if (shouldRecord()) { 00562 if (m_lapStartCount > 0) { 00563 m_cpuTime.m_lapStop = value_now<CPUTime>(); 00564 m_wallTime.m_lapStop = value_now<WallTime>(); 00565 m_MPICount.m_lapStop = value_now<MPICount>(); 00566 m_MPIByteCount.m_lapStop = value_now<MPIByteCount>(); 00567 m_heapAlloc.m_lapStop = value_now<HeapAlloc>(); 00568 } 00569 } 00570 00571 return *this; 00572 } 00573 00574 00575 TimerImpl & 00576 TimerImpl::stop() 00577 { 00578 if (shouldRecord()) { 00579 if (--m_lapStartCount <= 0) { 00580 m_lapStartCount = 0; 00581 m_lapCount.m_lapStop++; 00582 00583 m_cpuTime.m_lapStop = value_now<CPUTime>(); 00584 m_wallTime.m_lapStop = value_now<WallTime>(); 00585 m_MPICount.m_lapStop = value_now<MPICount>(); 00586 m_MPIByteCount.m_lapStop = value_now<MPIByteCount>(); 00587 m_heapAlloc.m_lapStop = value_now<HeapAlloc>(); 00588 00589 m_lapCount.addLap(); 00590 m_cpuTime.addLap(); 00591 m_wallTime.addLap(); 00592 m_MPICount.addLap(); 00593 m_MPIByteCount.addLap(); 00594 m_heapAlloc.addLap(); 00595 } 00596 } 00597 00598 return *this; 00599 } 00600 00601 00602 double 00603 TimerImpl::accumulateSubtimerLapCounts() const 00604 { 00605 m_subtimerLapCount = m_lapCount.getAccumulatedLap(false); 00606 00607 for (TimerList::const_iterator it = m_subtimerList.begin(); it != m_subtimerList.end(); ++it) 00608 (*it).m_timerImpl->accumulateSubtimerLapCounts(); 00609 00610 for (TimerList::const_iterator it = m_subtimerList.begin(); it != m_subtimerList.end(); ++it) 00611 m_subtimerLapCount += (*it).m_timerImpl->m_subtimerLapCount; 00612 00613 return m_subtimerLapCount; 00614 } 00615 00616 00617 void 00618 TimerImpl::checkpoint() const 00619 { 00620 m_lapCount.checkpoint(); 00621 m_cpuTime.checkpoint(); 00622 m_wallTime.checkpoint(); 00623 m_MPICount.checkpoint(); 00624 m_MPIByteCount.checkpoint(); 00625 m_heapAlloc.checkpoint(); 00626 00627 for (TimerList::const_iterator it = m_subtimerList.begin(); it != m_subtimerList.end(); ++it) 00628 (*it).m_timerImpl->checkpoint(); 00629 } 00630 00631 00632 void 00633 TimerImpl::updateRootTimer(TimerImpl *root_timer) 00634 { 00635 root_timer->m_lapCount.m_lapStop = value_now<LapCount>(); 00636 root_timer->m_cpuTime.m_lapStop = value_now<CPUTime>(); 00637 root_timer->m_wallTime.m_lapStop = value_now<WallTime>(); 00638 root_timer->m_MPICount.m_lapStop = value_now<MPICount>(); 00639 root_timer->m_MPIByteCount.m_lapStop = value_now<MPIByteCount>(); 00640 root_timer->m_heapAlloc.m_lapStop = value_now<HeapAlloc>(); 00641 00642 root_timer->m_lapCount.m_accumulatedLap = root_timer->m_lapCount.m_lapStop - root_timer->m_lapCount.m_lapStart; 00643 root_timer->m_cpuTime.m_accumulatedLap = root_timer->m_cpuTime.m_lapStop - root_timer->m_cpuTime.m_lapStart; 00644 root_timer->m_wallTime.m_accumulatedLap = root_timer->m_wallTime.m_lapStop - root_timer->m_wallTime.m_lapStart; 00645 root_timer->m_MPICount.m_accumulatedLap = root_timer->m_MPICount.m_lapStop - root_timer->m_MPICount.m_lapStart; 00646 root_timer->m_MPIByteCount.m_accumulatedLap = root_timer->m_MPIByteCount.m_lapStop - root_timer->m_MPIByteCount.m_lapStart; 00647 root_timer->m_heapAlloc.m_accumulatedLap = root_timer->m_heapAlloc.m_lapStop - root_timer->m_heapAlloc.m_lapStart; 00648 } 00649 00650 00651 00652 Timer 00653 TimerImpl::createRootTimer( 00654 const std::string & name, 00655 const TimerSet & timer_set) 00656 { 00657 TimerImpl *timer_impl = new TimerImpl(name, 0, 0, timer_set); 00658 return Timer(timer_impl); 00659 } 00660 00661 00662 void 00663 TimerImpl::deleteRootTimer( 00664 TimerImpl * root_timer) 00665 { 00666 delete root_timer; 00667 } 00668 00669 00670 void 00671 TimerImpl::findTimer( 00672 TimerImpl * timer, 00673 std::vector<std::string> & path_tail_vector, 00674 std::vector<Timer> & found_timers) 00675 { 00676 if (timer->begin() == timer->end()) { // at leaf 00677 00678 } 00679 else 00680 for (TimerList::const_iterator it = timer->begin(); it != timer->end(); ++it) 00681 findTimer((*it).m_timerImpl, path_tail_vector, found_timers); 00682 } 00683 00684 00685 std::vector<Timer> & 00686 TimerImpl::findTimers( 00687 TimerImpl * root_timer, 00688 const std::string & path_tail, 00689 std::vector<Timer> & found_timers) 00690 { 00691 std::vector<std::string> path_tail_vector; 00692 00693 findTimer(root_timer, split(path_tail, '.', path_tail_vector), found_timers); 00694 00695 return found_timers; 00696 } 00697 00698 00699 00700 Writer & 00701 TimerImpl::dump( 00702 Writer & dout) const 00703 { 00704 if (dout.shouldPrint()) { 00705 dout << "TimerImpl" << push << dendl; 00706 dout << "m_name, " << m_name << dendl; 00707 dout << "m_timerMask, " << m_timerMask << dendl; 00708 // dout << "m_parentTimer, " << c_ptr_name(m_parentTimer) << dendl; 00709 dout << "m_subtimerLapCount, " << m_subtimerLapCount << dendl; 00710 dout << "m_lapStartCount, " << m_lapStartCount << dendl; 00711 00712 dout << "m_lapCount, " << m_lapCount << dendl; 00713 dout << "m_cpuTime, " << m_cpuTime << dendl; 00714 dout << "m_wallTime, " << m_wallTime << dendl; 00715 dout << "m_MPICount, " << m_MPICount << dendl; 00716 dout << "m_MPIByteCount, " << m_MPIByteCount << dendl; 00717 dout << "m_heapAlloc, " << m_heapAlloc << dendl; 00718 00719 dout << "m_subtimerList, " << m_subtimerList << dendl; 00720 dout << pop; 00721 } 00722 00723 return dout; 00724 } 00725 00726 00727 Timer::Timer(const std::string &name, const Timer parent) 00728 : m_timerImpl(TimerImpl::reg(name, parent.getTimerMask(), parent.m_timerImpl, parent.getTimerSet())) 00729 {} 00730 00731 Timer::Timer(const std::string &name, TimerMask timer_mask, const Timer parent) 00732 : m_timerImpl(TimerImpl::reg(name, timer_mask, parent.m_timerImpl, parent.getTimerSet())) 00733 {} 00734 00735 Timer::Timer(const std::string &name, const Timer parent, const TimerSet &timer_set) 00736 : m_timerImpl(TimerImpl::reg(name, parent.getTimerMask(), parent.m_timerImpl, timer_set)) 00737 {} 00738 00739 Timer::Timer(const std::string &name, TimerMask timer_mask, const Timer parent, const TimerSet &timer_set) 00740 : m_timerImpl(TimerImpl::reg(name, timer_mask, parent.m_timerImpl, timer_set)) 00741 {} 00742 00743 00744 const std::string & 00745 Timer::getName() const { 00746 return m_timerImpl->m_name; 00747 } 00748 00749 TimerMask 00750 Timer::getTimerMask() const { 00751 return m_timerImpl->getTimerMask(); 00752 } 00753 00754 const TimerSet & 00755 Timer::getTimerSet() const { 00756 return m_timerImpl->getTimerSet(); 00757 } 00758 00759 double 00760 Timer::getSubtimerLapCount() const { 00761 return m_timerImpl->getSubtimerLapCount(); 00762 } 00763 00764 const TimerList & 00765 Timer::getTimerList() const { 00766 return m_timerImpl->getTimerList(); 00767 } 00768 00769 template<class T> 00770 const Timer::Metric<T> & 00771 Timer::getMetric() const { 00772 return m_timerImpl->getMetric<T>(); 00773 } 00774 00775 template const Timer::Metric<LapCount> &Timer::getMetric<LapCount>() const; 00776 template const Timer::Metric<CPUTime> &Timer::getMetric<CPUTime>() const; 00777 template const Timer::Metric<WallTime> &Timer::getMetric<WallTime>() const; 00778 template const Timer::Metric<MPICount> &Timer::getMetric<MPICount>() const; 00779 template const Timer::Metric<MPIByteCount> &Timer::getMetric<MPIByteCount>() const; 00780 template const Timer::Metric<HeapAlloc> &Timer::getMetric<HeapAlloc>() const; 00781 00782 00783 bool 00784 Timer::shouldRecord() const 00785 { 00786 return m_timerImpl->shouldRecord(); 00787 } 00788 00789 TimerList::iterator 00790 Timer::begin() 00791 { 00792 return m_timerImpl->begin(); 00793 } 00794 00795 TimerList::const_iterator 00796 Timer::begin() const 00797 { 00798 return m_timerImpl->begin(); 00799 } 00800 00801 TimerList::iterator 00802 Timer::end() 00803 { 00804 return m_timerImpl->end(); 00805 } 00806 00807 TimerList::const_iterator 00808 Timer::end() const 00809 { 00810 return m_timerImpl->end(); 00811 } 00812 00813 double 00814 Timer::accumulateSubtimerLapCounts() const { 00815 return m_timerImpl->accumulateSubtimerLapCounts(); 00816 } 00817 00818 Timer & 00819 Timer::start() { 00820 m_timerImpl->start(); 00821 return *this; 00822 } 00823 00824 Timer & 00825 Timer::lap() { 00826 m_timerImpl->lap(); 00827 return *this; 00828 } 00829 00830 Timer & 00831 Timer::stop() { 00832 m_timerImpl->stop(); 00833 return *this; 00834 } 00835 00836 void 00837 Timer::checkpoint() const { 00838 m_timerImpl->checkpoint(); 00839 } 00840 00841 Writer & 00842 Timer::dump(Writer& dout) const { 00843 return m_timerImpl->dump(dout); 00844 } 00845 00846 template <class T> 00847 Writer & 00848 Timer::Metric<T>::dump( 00849 Writer & dout) const 00850 { 00851 if (dout.shouldPrint()) { 00852 dout << "Timer::Metric<T>" << push << dendl; 00853 dout << "m_lapStart, " << m_lapStart << dendl; 00854 dout << "m_lapStop, " << m_lapStop << dendl; 00855 dout << "m_accumulatedLap, " << m_accumulatedLap << dendl; 00856 dout << "m_checkpoint, " << m_checkpoint << dendl; 00857 dout << pop; 00858 } 00859 return dout; 00860 } 00861 00862 template Writer &Timer::Metric<LapCount>::dump(Writer &) const; 00863 template Writer &Timer::Metric<CPUTime>::dump(Writer &) const; 00864 template Writer &Timer::Metric<WallTime>::dump(Writer &) const; 00865 template Writer &Timer::Metric<MPICount>::dump(Writer &) const; 00866 template Writer &Timer::Metric<MPIByteCount>::dump(Writer &) const; 00867 template Writer &Timer::Metric<HeapAlloc>::dump(Writer &) const; 00868 00869 00870 TimeBlockSynchronized::TimeBlockSynchronized( 00871 Timer & timer, 00872 MPI_Comm mpi_comm, 00873 bool start_timer) 00874 : m_timer(timer), 00875 m_mpiComm(mpi_comm), 00876 m_started(start_timer) 00877 { 00878 if (m_timer.m_timerImpl->shouldRecord()) { 00879 #ifdef STK_HAS_MPI 00880 if (mpi_comm != MPI_COMM_NULL) 00881 MPI_Barrier(mpi_comm); 00882 #endif 00883 00884 if (start_timer) 00885 m_timer.start(); 00886 } 00887 } 00888 00889 00890 TimeBlockSynchronized::~TimeBlockSynchronized() 00891 { 00892 if (m_started) { 00893 try { 00894 m_timer.stop(); 00895 } 00896 catch (...) { 00897 } 00898 } 00899 } 00900 00901 00902 void 00903 TimeBlockSynchronized::start() 00904 { 00905 // Place barrier here 00906 MPI_Barrier(m_mpiComm); 00907 m_started = true; 00908 m_timer.start(); 00909 } 00910 00911 00912 void 00913 TimeBlockSynchronized::stop() 00914 { 00915 m_started = false; 00916 m_timer.stop(); 00917 // Does a barrier need to be here? 00918 // MPI_Barrier(Env::parallel_comm()); 00919 } 00920 00921 } // namespace diag 00922 } // namespace stk_classic 00923 00924 00925 00926 #ifdef SIERRA_INCLUDE_LIBPAPI 00927 class PAPIRuntimeError : public std::runtime_error 00928 { 00929 public: 00930 PAPIRuntimeError(const char *message, int status) 00931 : std::runtime_error(message), 00932 m_status(status) 00933 {} 00934 00935 virtual const char *what() const throw() { 00936 static std::string message; 00937 static char papi_message[PAPI_MAX_STR_LEN]; 00938 00939 PAPI_perror(m_status, papi_message, sizeof(papi_message)); 00940 00941 message = std::runtime_error::what(); 00942 message += papi_message; 00943 00944 return message.c_str(); 00945 } 00946 00947 private: 00948 int m_status; 00949 }; 00950 #endif 00951 00952 00953 namespace sierra { 00954 namespace Diag { 00955 00956 namespace { 00957 00958 size_t 00959 s_timerNameMaxWidth = DEFAULT_TIMER_NAME_MAX_WIDTH; 00960 00961 } // namespace 00962 00963 00964 // 00965 // SierraRootTimer member functions: 00966 // 00967 SierraRootTimer::SierraRootTimer() 00968 : m_sierraTimer(stk_classic::diag::createRootTimer("Sierra", sierraTimerSet())) 00969 { } 00970 00971 00972 SierraRootTimer::~SierraRootTimer() 00973 { 00974 stk_classic::diag::deleteRootTimer(m_sierraTimer); 00975 } 00976 00977 00978 stk_classic::diag::Timer & SierraRootTimer::sierraTimer() 00979 { 00980 return m_sierraTimer; 00981 } 00982 00983 00984 TimerSet & 00985 sierraTimerSet() 00986 { 00987 static TimerSet s_sierraTimerSet(TIMER_PROCEDURE | TIMER_REGION); 00988 00989 return s_sierraTimerSet; 00990 } 00991 00992 00993 boost::shared_ptr<SierraRootTimer> sierraRootTimer() 00994 { 00995 static boost::shared_ptr<SierraRootTimer> s_sierraRootTimer(new SierraRootTimer()); 00996 if ( ! s_sierraRootTimer ) { 00997 s_sierraRootTimer.reset(new SierraRootTimer()); 00998 } 00999 return s_sierraRootTimer; 01000 } 01001 01002 01003 Timer & 01004 sierraTimer() 01005 { 01006 return sierraRootTimer()->sierraTimer(); 01007 } 01008 01009 void 01010 sierraTimerDestroy() 01011 { 01012 sierraRootTimer().reset(); 01013 } 01014 01015 01016 void 01017 setEnabledTimerMask( 01018 TimerMask timer_mask) 01019 { 01020 sierraTimerSet().setEnabledTimerMask(timer_mask); 01021 } 01022 01023 01024 TimerMask 01025 getEnabledTimerMask() 01026 { 01027 return sierraTimerSet().getEnabledTimerMask(); 01028 } 01029 01030 01031 void 01032 setTimeFormat(int time_format) { 01033 stk_classic::diag::setTimerTimeFormat(time_format); 01034 } 01035 01036 01037 void 01038 setTimeFormatMillis() 01039 { 01040 if ((getTimeFormat() & stk_classic::TIMEFORMAT_STYLE_MASK ) == stk_classic::TIMEFORMAT_HMS) { 01041 if (getSierraWallTime() > 3600.0) 01042 setTimeFormat(getTimeFormat() & ~stk_classic::TIMEFORMAT_MILLIS); 01043 else 01044 setTimeFormat(getTimeFormat() | stk_classic::TIMEFORMAT_MILLIS); 01045 } 01046 else if ((getTimeFormat() & stk_classic::TIMEFORMAT_STYLE_MASK ) == stk_classic::TIMEFORMAT_SECONDS) { 01047 if (getSierraWallTime() > 1000.0) 01048 setTimeFormat(getTimeFormat() & ~stk_classic::TIMEFORMAT_MILLIS); 01049 else 01050 setTimeFormat(getTimeFormat() | stk_classic::TIMEFORMAT_MILLIS); 01051 } 01052 } 01053 01054 01055 int 01056 getTimeFormat() 01057 { 01058 return stk_classic::diag::getTimerTimeFormat(); 01059 } 01060 01061 01062 void 01063 setTimerNameMaxWidth( 01064 size_t width) 01065 { 01066 s_timerNameMaxWidth = width; 01067 } 01068 01069 01070 size_t 01071 getTimerNameMaxWidth() 01072 { 01073 return s_timerNameMaxWidth; 01074 } 01075 01076 01077 stk_classic::diag::MetricTraits<stk_classic::diag::CPUTime>::Type 01078 getSierraCPUTime() 01079 { 01080 return sierraTimer().getMetric<stk_classic::diag::CPUTime>().getAccumulatedLap(false); 01081 } 01082 01083 01084 stk_classic::diag::MetricTraits<stk_classic::diag::WallTime>::Type 01085 getSierraWallTime() 01086 { 01087 return sierraTimer().getMetric<stk_classic::diag::WallTime>().getAccumulatedLap(false); 01088 } 01089 01090 01091 stk_classic::diag::MetricTraits<stk_classic::diag::CPUTime>::Type 01092 getCPULapTime(Timer timer) { 01093 return timer.getMetric<stk_classic::diag::CPUTime>().getLap(); 01094 } 01095 01096 stk_classic::diag::MetricTraits<stk_classic::diag::CPUTime>::Type 01097 getCPUAccumulatedLapTime(Timer timer) { 01098 return timer.getMetric<stk_classic::diag::CPUTime>().getAccumulatedLap(false); 01099 } 01100 01101 01102 TimerParser & 01103 theTimerParser() 01104 { 01105 static TimerParser parser; 01106 01107 return parser; 01108 } 01109 01110 01111 TimerParser::TimerParser() 01112 : sierra::OptionMaskParser() 01113 { 01114 mask("cpu", 0, "Display CPU times"); 01115 mask("wall", 0, "Display wall times"); 01116 01117 mask("hms", 0, "Display times in HH:MM:SS format"); 01118 mask("seconds", 0, "Display times in seconds"); 01119 01120 01121 // mask("table", TIMER_TABLE, "Format output as a table"); 01122 // mask("xml", TIMER_XML, "Format output as an XML file"); 01123 01124 mask("all", TIMER_ALL, "Enable all metrics"); 01125 mask("none", TIMER_NONE, "Disable all timers"); 01126 01127 mask("domain", TIMER_DOMAIN, "Enable metrics on the domain"); 01128 mask("region", TIMER_REGION, "Enable metrics on regions"); 01129 mask("procedure", TIMER_PROCEDURE, "Enable metrics on procedures"); 01130 mask("mechanics", TIMER_MECHANICS, "Enable metrics on mechanics"); 01131 mask("algorithm", TIMER_ALGORITHM, "Enable metrics on algorithms"); 01132 mask("solver", TIMER_SOLVER, "Enable metrics on solvers"); 01133 mask("contact", TIMER_CONTACT, "Enable metrics on contact"); 01134 mask("material", TIMER_MATERIAL, "Enable metrics on materials"); 01135 mask("search", TIMER_SEARCH, "Enable metrics on searches"); 01136 mask("transfer", TIMER_TRANSFER, "Enable metrics on user functions"); 01137 mask("adaptivity", TIMER_ADAPTIVITY, "Enable metrics on adaptivity"); 01138 mask("recovery", TIMER_RECOVERY, "Enable metrics on encore recovery"); 01139 mask("profile1", TIMER_PROFILE_1, "Enable app defined profiling metrics"); 01140 mask("profile2", TIMER_PROFILE_2, "Enable app defined profiling metrics"); 01141 mask("profile3", TIMER_PROFILE_3, "Enable app defined profiling metrics"); 01142 mask("profile4", TIMER_PROFILE_4, "Enable app defined profiling metrics"); 01143 mask("app1", TIMER_APP_1, "Enable app defined metrics"); 01144 mask("app2", TIMER_APP_2, "Enable app defined metrics"); 01145 mask("app3", TIMER_APP_3, "Enable app defined metrics"); 01146 mask("app4", TIMER_APP_4, "Enable app defined metrics"); 01147 } 01148 01149 01150 OptionMaskParser::Mask 01151 TimerParser::parse( 01152 const char * mask) const 01153 { 01154 m_metricsSetMask = 0; 01155 m_metricsMask = 0; 01156 m_optionMask = getEnabledTimerMask(); 01157 01158 m_optionMask = OptionMaskParser::parse(mask); 01159 01160 // if ((m_optionMask & TIMER_FORMAT) == 0) 01161 // m_optionMask |= TIMER_TABLE; 01162 01163 setEnabledTimerMask(m_optionMask); 01164 01165 if (m_metricsSetMask != 0) 01166 stk_classic::diag::setEnabledTimerMetricsMask(m_metricsMask); 01167 01168 return m_optionMask; 01169 } 01170 01171 01172 void 01173 TimerParser::parseArg( 01174 const std::string & name, 01175 const std::string & arg) const 01176 { 01177 if (name == "cpu") { 01178 m_metricsMask |= stk_classic::diag::METRICS_CPU_TIME; 01179 m_metricsSetMask |= stk_classic::diag::METRICS_CPU_TIME; 01180 } 01181 else if (name == "wall") { 01182 m_metricsMask |= stk_classic::diag::METRICS_WALL_TIME; 01183 m_metricsSetMask |= stk_classic::diag::METRICS_WALL_TIME; 01184 } 01185 else if (name == "heap") { 01186 m_metricsMask |= stk_classic::diag::METRICS_HEAP_ALLOC; 01187 m_metricsSetMask |= stk_classic::diag::METRICS_HEAP_ALLOC; 01188 } 01189 else if (name == "none") { 01190 m_optionMask = 0; 01191 m_metricsSetMask = stk_classic::diag::METRICS_WALL_TIME | stk_classic::diag::METRICS_CPU_TIME; 01192 } 01193 01194 else if (name == "hms") { 01195 Diag::setTimeFormat(stk_classic::TIMEFORMAT_HMS); 01196 } 01197 else if (name == "seconds") { 01198 Diag::setTimeFormat(stk_classic::TIMEFORMAT_SECONDS); 01199 } 01200 01201 else 01202 OptionMaskParser::parseArg(name, arg); 01203 } 01204 01205 } // namespace Diag 01206 } // namespace sierra