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 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 // Kris
43 // 07.08.03 -- Move into Teuchos package/namespace
44 
45 #include "Teuchos_Time.hpp"
46 
47 #if defined(__INTEL_COMPILER) && defined(_WIN32)
48 
49 #define WIN32_LEAN_AND_MEAN
50 #include <windows.h>
51 #include <cassert>
52 
53 namespace {
54 
55 bool seconds_initialized = false;
56 LARGE_INTEGER start_count, count_freq; // counts per sec.
57 
58 inline void seconds_initialize() {
59  if( seconds_initialized ) return;
60  std::cout << "\nCalling Win32 version of Teuchos::seconds_initialize()!\n";
61  // Figure out how often the performance counter increments
62  ::QueryPerformanceFrequency( &count_freq );
63  // Set this thread's priority as high as reasonably possible to prevent
64  // timeslice interruptions
65  ::SetThreadPriority( ::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
66  // Get the first count.
67  assert( QueryPerformanceCounter( &start_count ) );
68  seconds_initialized = true;
69 }
70 
71 } // end namespace
72 
73 #endif // defined(__INTEL_COMPILER) && defined(_WIN32)
74 
75 #ifdef HAVE_TEUCHOS_TIME_MASSIF_SNAPSHOTS
76 #include <valgrind.h>
77 #include <algorithm>
78 #include <unistd.h>
79 #endif
80 
81 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
82 namespace Kokkos {
83 namespace Profiling {
84 extern void pushRegion (const std::string&);
85 extern void popRegion ();
86 } // namespace Profiling
87 } // namespace Kokkos
88 #endif
89 
90 namespace Teuchos {
91 
92 #ifdef HAVE_TEUCHOS_TIME_MASSIF_SNAPSHOTS
93  void removeIllegalChars(std::string& s){
94  std::string illegalChars = "\\/:?\"<>|";
95  for (auto it = s.begin() ; it < s.end() ; ++it){
96  bool found = illegalChars.find(*it) != std::string::npos;
97  if(found)
98  *it = ' ';
99  }
100  }
101 #endif
102 
103 //=============================================================================
104 Time::Time(const std::string& name_in, bool start_in)
105  : startTime_(0), totalTime_(0), isRunning_(false), enabled_ (true), name_(name_in), numCalls_(0)
106 {
107  if(start_in) this->start();
108 #ifdef HAVE_TEUCHOS_TIME_MASSIF_SNAPSHOTS
109  numCallsMassifSnapshots_ = 0;
110 #endif
111 }
112 
113 void Time::start(bool reset_in)
114 {
115  if (enabled_) {
116  isRunning_ = true;
117  if (reset_in) totalTime_ = 0;
118 #ifdef HAVE_TEUCHOS_TIME_MASSIF_SNAPSHOTS
119  if (numCallsMassifSnapshots_ < 100) {
120  std::string filename = "massif.out." + std::to_string(::getpid()) + "." + name_ + "." + std::to_string(numCallsMassifSnapshots_) + ".start.out";
121  removeIllegalChars(filename);
122  std::replace(filename.begin(), filename.end(), ' ', '_');
123  std::string cmd = "snapshot " + filename;
124  VALGRIND_MONITOR_COMMAND(cmd.data());
125  }
126 #endif
127  startTime_ = wallTime();
128 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
129  ::Kokkos::Profiling::pushRegion (name_);
130 #endif
131  }
132 }
133 
134 double Time::stop()
135 {
136  if (enabled_) {
137  if (isRunning_) {
138  totalTime_ += ( wallTime() - startTime_ );
139  isRunning_ = false;
140  startTime_ = 0;
141 #ifdef HAVE_TEUCHOS_TIME_MASSIF_SNAPSHOTS
142  if (numCallsMassifSnapshots_ < 100) {
143  std::string filename = "massif.out." + std::to_string(::getpid()) + "." + name_ + "." + std::to_string(numCallsMassifSnapshots_) + ".stop.out";
144  removeIllegalChars(filename);
145  std::replace(filename.begin(), filename.end(), ' ', '_');
146  std::string cmd = "snapshot " + filename;
147  VALGRIND_MONITOR_COMMAND(cmd.data());
148  numCallsMassifSnapshots_++;
149  }
150 #endif
151 #if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
152  ::Kokkos::Profiling::popRegion ();
153 #endif
154  }
155  }
156  return totalTime_;
157 }
158 
159 double Time::totalElapsedTime(bool readCurrentTime) const
160 {
161  if(readCurrentTime)
162  return wallTime() - startTime_ + totalTime_;
163  return totalTime_;
164 }
165 
166 void Time::reset () {
167  totalTime_ = 0;
168  numCalls_ = 0;
169 }
170 
171 void Time::disable () {
172  enabled_ = false;
173 }
174 
175 void Time::enable () {
176  enabled_ = true;
177 }
178 
180  if (enabled_) {
181  ++numCalls_;
182  }
183 }
184 
186 {
187  /* KL: warning: this code is probably not portable! */
188  /* HT: have added some preprocessing to address problem compilers */
189  /* RAB: I modifed so that timer will work if MPI support is compiled in but not initialized */
190 
191 #ifdef HAVE_MPI
192 
193  int mpiInitialized;
194  MPI_Initialized(&mpiInitialized);
195 
196  if( mpiInitialized ) {
197 
198  return(MPI_Wtime());
199 
200  }
201  else {
202 
203  clock_t start;
204 
205  start = clock();
206  return( (double)( start ) / CLOCKS_PER_SEC );
207 
208  }
209 
210 #elif defined(__INTEL_COMPILER) && defined(_WIN32)
211 
212  seconds_initialize();
213  LARGE_INTEGER count;
214  QueryPerformanceCounter( &count );
215  // "QuadPart" is a 64 bit integer (__int64). VC++ supports them!
216  const double
217  sec = (double)( count.QuadPart - start_count.QuadPart ) / count_freq.QuadPart;
218  //std::cout << "ticks = " << ticks << ", sec = " << sec << std::endl;
219  return sec;
220 
221 #elif ICL || defined(_WIN32)
222 
223  clock_t start;
224 
225  start = clock();
226  return( (double)( start ) / CLOCKS_PER_SEC );
227 
228 #else
229 
230 # ifndef MINGW
231  struct timeval tp;
232  static long start = 0, startu;
233  if (!start)
234  {
235  gettimeofday(&tp, NULL);
236  start = tp.tv_sec;
237  startu = tp.tv_usec;
238  return(0.0);
239  }
240  gettimeofday(&tp, NULL);
241  return( ((double) (tp.tv_sec - start)) + (tp.tv_usec-startu)/1000000.0 );
242 # else // MINGW
243  return( (double) clock() / CLOCKS_PER_SEC );
244 # endif // MINGW
245 
246 #endif
247 
248 }
249 
250 } // 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().
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())...