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