Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_Time.cpp
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 // Kris
11 // 07.08.03 -- Move into Teuchos package/namespace
12 
13 #include "Teuchos_Time.hpp"
14 
15 #if defined(__INTEL_COMPILER) && defined(_WIN32)
16 
17 #define WIN32_LEAN_AND_MEAN
18 #include <windows.h>
19 #include <cassert>
20 
21 namespace {
22 
23 bool seconds_initialized = false;
24 LARGE_INTEGER start_count, count_freq; // counts per sec.
25 
26 inline void seconds_initialize() {
27  if( seconds_initialized ) return;
28  std::cout << "\nCalling Win32 version of Teuchos::seconds_initialize()!\n";
29  // Figure out how often the performance counter increments
30  ::QueryPerformanceFrequency( &count_freq );
31  // Set this thread's priority as high as reasonably possible to prevent
32  // timeslice interruptions
33  ::SetThreadPriority( ::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
34  // Get the first count.
35  assert( QueryPerformanceCounter( &start_count ) );
36  seconds_initialized = true;
37 }
38 
39 } // end namespace
40 
41 #endif // defined(__INTEL_COMPILER) && defined(_WIN32)
42 
43 #ifdef HAVE_TEUCHOS_TIME_MASSIF_SNAPSHOTS
44 #include <valgrind.h>
45 #include <algorithm>
46 #include <unistd.h>
47 #endif
48 
49 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOS)
50 namespace Kokkos {
51 namespace Tools {
52 extern void pushRegion (const std::string&);
53 extern void popRegion ();
54 } // namespace Profiling
55 } // namespace Kokkos
56 #endif
57 
58 #ifdef HAVE_TEUCHOS_TIMER_KOKKOS_FENCE
59 #include "Kokkos_Core.hpp"
60 #endif
61 
62 namespace Teuchos {
63 
64 #ifdef HAVE_TEUCHOS_TIME_MASSIF_SNAPSHOTS
65  void removeIllegalChars(std::string& s){
66  std::string illegalChars = "\\/:?\"<>|";
67  for (auto it = s.begin() ; it < s.end() ; ++it){
68  bool found = illegalChars.find(*it) != std::string::npos;
69  if(found)
70  *it = ' ';
71  }
72  }
73 #endif
74 
75 //=============================================================================
76 Time::Time(const std::string& name_in, bool start_in)
77  : startTime_(0), totalTime_(0), isRunning_(false), enabled_ (true), name_(name_in), numCalls_(0)
78 {
79  if(start_in) this->start();
80 #ifdef HAVE_TEUCHOS_TIME_MASSIF_SNAPSHOTS
81  numCallsMassifSnapshots_ = 0;
82 #endif
83 }
84 
85 void Time::start(bool reset_in)
86 {
87  if (enabled_) {
88  isRunning_ = true;
89  if (reset_in) totalTime_ = 0;
90 #ifdef HAVE_TEUCHOS_TIME_MASSIF_SNAPSHOTS
91  if (numCallsMassifSnapshots_ < 100) {
92  std::string filename = "massif.out." + std::to_string(::getpid()) + "." + name_ + "." + std::to_string(numCallsMassifSnapshots_) + ".start.out";
93  removeIllegalChars(filename);
94  std::replace(filename.begin(), filename.end(), ' ', '_');
95  std::string cmd = "snapshot " + filename;
96  VALGRIND_MONITOR_COMMAND(cmd.data());
97  }
98 #endif
99  startTime_ = wallTime();
100 #ifdef HAVE_TEUCHOS_TIMER_KOKKOS_FENCE
101  Kokkos::fence();
102 #endif
103 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOS)
104  ::Kokkos::Tools::pushRegion (name_);
105 #endif
106  }
107 }
108 
109 double Time::stop()
110 {
111  if (enabled_) {
112  if (isRunning_) {
113  totalTime_ += ( wallTime() - startTime_ );
114  isRunning_ = false;
115  startTime_ = 0;
116 #ifdef HAVE_TEUCHOS_TIME_MASSIF_SNAPSHOTS
117  if (numCallsMassifSnapshots_ < 100) {
118  std::string filename = "massif.out." + std::to_string(::getpid()) + "." + name_ + "." + std::to_string(numCallsMassifSnapshots_) + ".stop.out";
119  removeIllegalChars(filename);
120  std::replace(filename.begin(), filename.end(), ' ', '_');
121  std::string cmd = "snapshot " + filename;
122  VALGRIND_MONITOR_COMMAND(cmd.data());
123  numCallsMassifSnapshots_++;
124  }
125 #endif
126 #ifdef HAVE_TEUCHOS_TIMER_KOKKOS_FENCE
127  Kokkos::fence();
128 #endif
129 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOS)
130  ::Kokkos::Tools::popRegion ();
131 #endif
132  }
133  }
134  return totalTime_;
135 }
136 
137 double Time::totalElapsedTime(bool readCurrentTime) const
138 {
139  if(readCurrentTime)
140  return wallTime() - startTime_ + totalTime_;
141  return totalTime_;
142 }
143 
144 void Time::reset () {
145  totalTime_ = 0;
146  numCalls_ = 0;
147 }
148 
149 void Time::disable () {
150  enabled_ = false;
151 }
152 
153 void Time::enable () {
154  enabled_ = true;
155 }
156 
158  if (enabled_) {
159  ++numCalls_;
160  }
161 }
162 
164 {
165  /* KL: warning: this code is probably not portable! */
166  /* HT: have added some preprocessing to address problem compilers */
167  /* RAB: I modifed so that timer will work if MPI support is compiled in but not initialized */
168 
169 #ifdef HAVE_MPI
170 
171  int mpiInitialized;
172  MPI_Initialized(&mpiInitialized);
173 
174  if( mpiInitialized ) {
175 
176  return(MPI_Wtime());
177 
178  }
179  else {
180 
181  clock_t start;
182 
183  start = clock();
184  return( (double)( start ) / CLOCKS_PER_SEC );
185 
186  }
187 
188 #elif defined(__INTEL_COMPILER) && defined(_WIN32)
189 
190  seconds_initialize();
191  LARGE_INTEGER count;
192  QueryPerformanceCounter( &count );
193  // "QuadPart" is a 64 bit integer (__int64). VC++ supports them!
194  const double
195  sec = (double)( count.QuadPart - start_count.QuadPart ) / count_freq.QuadPart;
196  //std::cout << "ticks = " << ticks << ", sec = " << sec << std::endl;
197  return sec;
198 
199 #elif ICL || defined(_WIN32)
200 
201  clock_t start;
202 
203  start = clock();
204  return( (double)( start ) / CLOCKS_PER_SEC );
205 
206 #else
207 
208 # ifndef MINGW
209  struct timeval tp;
210  static long start = 0, startu;
211  if (!start)
212  {
213  gettimeofday(&tp, NULL);
214  start = tp.tv_sec;
215  startu = tp.tv_usec;
216  return(0.0);
217  }
218  gettimeofday(&tp, NULL);
219  return( ((double) (tp.tv_sec - start)) + (tp.tv_usec-startu)/1000000.0 );
220 # else // MINGW
221  return( (double) clock() / CLOCKS_PER_SEC );
222 # endif // MINGW
223 
224 #endif
225 
226 }
227 
228 } // namespace Teuchos
void disable()
&quot;Disable&quot; this timer, so that it ignores calls to start() and stop().
Basic wall-clock timer class.
void reset()
Reset the cummulative time and call count.
void start(bool reset=false)
Start the timer, if the timer is enabled (see disable()).
double stop()
Stop the timer, if the timer is enabled (see disable()).
Time(const std::string &name, bool start=false)
Constructor.
void enable()
&quot;Enable&quot; this timer, so that it (again) respects calls to start() and stop().
double totalElapsedTime(bool readCurrentTime=false) const
The total time in seconds accumulated by this timer.
static double wallTime()
Current wall-clock time in seconds.
void incrementNumCalls()
Increment the number of times this timer has been called, if the timer is enabled (see disable())...