Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
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#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
22namespace {
23
24bool seconds_initialized = false;
25LARGE_INTEGER start_count, count_freq; // counts per sec.
26
27inline 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)
51namespace Kokkos {
52namespace Tools {
53extern void pushRegion (const std::string&);
54extern void popRegion ();
55} // namespace Profiling
56} // namespace Kokkos
57#endif
58
59#ifdef HAVE_TEUCHOSCORE_KOKKOS
60#include "Kokkos_Core.hpp"
61#endif
62
63namespace 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//=============================================================================
77Time::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
86void 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
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
142double Time::totalElapsedTime(bool readCurrentTime) const
143{
144 if(readCurrentTime)
145 return wallTime() - startTime_ + totalTime_;
146 return totalTime_;
147}
148
149void Time::reset () {
150 totalTime_ = 0;
151 numCalls_ = 0;
152}
153
155 enabled_ = false;
156}
157
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
Basic wall-clock timer class.
void enable()
"Enable" this timer, so that it (again) respects calls to start() and stop().
void incrementNumCalls()
Increment the number of times this timer has been called, if the timer is enabled (see disable()).
double totalElapsedTime(bool readCurrentTime=false) const
The total time in seconds accumulated by this timer.
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()).
void disable()
"Disable" this timer, so that it ignores calls to start() and stop().
Time(const std::string &name, bool start=false)
Constructor.
static double wallTime()
Current wall-clock time in seconds.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...