MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
tic_toc.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#include "tic_toc.hpp"
13
14#if (MFEM_TIMER_TYPE == 0)
15#include <ctime>
16#elif (MFEM_TIMER_TYPE == 1)
17#include <sys/times.h>
18#include <climits>
19#include <unistd.h>
20#elif (MFEM_TIMER_TYPE == 2)
21#include <time.h>
22#if (!defined(CLOCK_MONOTONIC) || !defined(CLOCK_PROCESS_CPUTIME_ID))
23#error "CLOCK_MONOTONIC and CLOCK_PROCESS_CPUTIME_ID not defined in <time.h>"
24#endif
25#elif (MFEM_TIMER_TYPE == 3)
26#define NOMINMAX
27#include <windows.h>
28#undef NOMINMAX
29#elif (MFEM_TIMER_TYPE == 4)
30#include <ctime>
31#include <mach/mach_time.h>
32#elif (MFEM_TIMER_TYPE == 5)
33#include <sys/time.h> // gettimeofday
34#elif (MFEM_TIMER_TYPE == 6)
35#include <mpi.h> // MPI_Wtime()
36#else
37#error "Unknown MFEM_TIMER_TYPE"
38#endif
39
40namespace mfem
41{
42
43namespace internal
44{
45
46class StopWatch
47{
48private:
49#if (MFEM_TIMER_TYPE == 0)
50 std::clock_t user_time, start_utime;
51#elif (MFEM_TIMER_TYPE == 1)
52 clock_t real_time, user_time, syst_time;
53 clock_t start_rtime, start_utime, start_stime;
54 long my_CLK_TCK;
55 inline void Current(clock_t *, clock_t *, clock_t *);
56#elif (MFEM_TIMER_TYPE == 2)
57 struct timespec real_time, user_time;
58 struct timespec start_rtime, start_utime;
59 inline void GetRealTime(struct timespec &tp);
60 inline void GetUserTime(struct timespec &tp);
61#elif (MFEM_TIMER_TYPE == 3)
62 LARGE_INTEGER frequency, real_time, start_rtime;
63#elif (MFEM_TIMER_TYPE == 4)
64 std::clock_t user_time, start_utime;
65 mach_timebase_info_data_t ratio;
66 uint64_t real_time, start_rtime;
67#elif (MFEM_TIMER_TYPE == 5)
68 struct timeval real_time, start_rtime;
69#elif (MFEM_TIMER_TYPE == 6)
70 double real_time, start_rtime;
71#endif
72 short Running;
73
74public:
75 StopWatch();
76 inline void Clear();
77 inline void Start();
78 inline void Stop();
79 inline double Resolution();
80 inline double RealTime();
81 inline double UserTime();
82 inline double SystTime();
83};
84
85StopWatch::StopWatch()
86{
87#if (MFEM_TIMER_TYPE == 0)
88 user_time = 0;
89#elif (MFEM_TIMER_TYPE == 1)
90 my_CLK_TCK = sysconf(_SC_CLK_TCK);
91 real_time = user_time = syst_time = 0;
92#elif (MFEM_TIMER_TYPE == 2)
93 real_time.tv_sec = user_time.tv_sec = 0;
94 real_time.tv_nsec = user_time.tv_nsec = 0;
95#elif (MFEM_TIMER_TYPE == 3)
96 QueryPerformanceFrequency(&frequency);
97 real_time.QuadPart = 0;
98#elif (MFEM_TIMER_TYPE == 4)
99 user_time = 0;
100 real_time = 0;
101 mach_timebase_info(&ratio);
102#elif (MFEM_TIMER_TYPE == 5)
103 real_time.tv_sec = 0;
104 real_time.tv_usec = 0;
105#elif (MFEM_TIMER_TYPE == 6)
106 real_time = 0.0;
107#endif
108 Running = 0;
109}
110
111#if (MFEM_TIMER_TYPE == 1)
112inline void StopWatch::Current(clock_t *r, clock_t *u, clock_t *s)
113{
114 struct tms my_tms;
115
116 *r = times(&my_tms);
117 *u = my_tms.tms_utime;
118 *s = my_tms.tms_stime;
119}
120#elif (MFEM_TIMER_TYPE == 2)
121inline void StopWatch::GetRealTime(struct timespec &tp)
122{
123 clock_gettime(CLOCK_MONOTONIC, &tp);
124}
125
126inline void StopWatch::GetUserTime(struct timespec &tp)
127{
128 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
129}
130#endif
131
132inline void StopWatch::Clear()
133{
134#if (MFEM_TIMER_TYPE == 0)
135 user_time = 0;
136 if (Running)
137 {
138 start_utime = std::clock();
139 }
140#elif (MFEM_TIMER_TYPE == 1)
141 real_time = user_time = syst_time = 0;
142 if (Running)
143 {
144 Current(&start_rtime, &start_utime, &start_stime);
145 }
146#elif (MFEM_TIMER_TYPE == 2)
147 real_time.tv_sec = user_time.tv_sec = 0;
148 real_time.tv_nsec = user_time.tv_nsec = 0;
149 if (Running)
150 {
151 GetRealTime(start_rtime);
152 GetUserTime(start_utime);
153 }
154#elif (MFEM_TIMER_TYPE == 3)
155 real_time.QuadPart = 0;
156 if (Running)
157 {
158 QueryPerformanceCounter(&start_rtime);
159 }
160#elif (MFEM_TIMER_TYPE == 4)
161 user_time = 0;
162 real_time = 0;
163 if (Running)
164 {
165 start_utime = std::clock();
166 start_rtime = mach_absolute_time();
167 }
168#elif (MFEM_TIMER_TYPE == 5)
169 real_time.tv_sec = 0;
170 real_time.tv_usec = 0;
171 if (Running)
172 {
173 gettimeofday(&start_rtime, NULL);
174 }
175#elif (MFEM_TIMER_TYPE == 6)
176 real_time = 0.0;
177 if (Running)
178 {
179 start_rtime = MPI_Wtime();
180 }
181#endif
182}
183
184inline void StopWatch::Start()
185{
186 if (Running) { return; }
187#if (MFEM_TIMER_TYPE == 0)
188 start_utime = std::clock();
189#elif (MFEM_TIMER_TYPE == 1)
190 Current(&start_rtime, &start_utime, &start_stime);
191#elif (MFEM_TIMER_TYPE == 2)
192 GetRealTime(start_rtime);
193 GetUserTime(start_utime);
194#elif (MFEM_TIMER_TYPE == 3)
195 QueryPerformanceCounter(&start_rtime);
196#elif (MFEM_TIMER_TYPE == 4)
197 start_utime = std::clock();
198 start_rtime = mach_absolute_time();
199#elif (MFEM_TIMER_TYPE == 5)
200 gettimeofday(&start_rtime, NULL);
201#elif (MFEM_TIMER_TYPE == 6)
202 start_rtime = MPI_Wtime();
203#endif
204 Running = 1;
205}
206
207inline void StopWatch::Stop()
208{
209 if (!Running) { return; }
210#if (MFEM_TIMER_TYPE == 0)
211 user_time += ( std::clock() - start_utime );
212#elif (MFEM_TIMER_TYPE == 1)
213 clock_t curr_rtime, curr_utime, curr_stime;
214 Current(&curr_rtime, &curr_utime, &curr_stime);
215 real_time += ( curr_rtime - start_rtime );
216 user_time += ( curr_utime - start_utime );
217 syst_time += ( curr_stime - start_stime );
218#elif (MFEM_TIMER_TYPE == 2)
219 struct timespec curr_rtime, curr_utime;
220 GetRealTime(curr_rtime);
221 GetUserTime(curr_utime);
222 real_time.tv_sec += ( curr_rtime.tv_sec - start_rtime.tv_sec );
223 real_time.tv_nsec += ( curr_rtime.tv_nsec - start_rtime.tv_nsec );
224 user_time.tv_sec += ( curr_utime.tv_sec - start_utime.tv_sec );
225 user_time.tv_nsec += ( curr_utime.tv_nsec - start_utime.tv_nsec );
226#elif (MFEM_TIMER_TYPE == 3)
227 LARGE_INTEGER curr_rtime;
228 QueryPerformanceCounter(&curr_rtime);
229 real_time.QuadPart += (curr_rtime.QuadPart - start_rtime.QuadPart);
230#elif (MFEM_TIMER_TYPE == 4)
231 user_time += ( std::clock() - start_utime );
232 real_time += (mach_absolute_time() - start_rtime);
233#elif (MFEM_TIMER_TYPE == 5)
234 struct timeval curr_rtime;
235 gettimeofday(&curr_rtime, NULL);
236 real_time.tv_sec += ( curr_rtime.tv_sec - start_rtime.tv_sec );
237 real_time.tv_usec += ( curr_rtime.tv_usec - start_rtime.tv_usec );
238#elif (MFEM_TIMER_TYPE == 6)
239 real_time += (MPI_Wtime() - start_rtime);
240#endif
241 Running = 0;
242}
243
244inline double StopWatch::Resolution()
245{
246#if (MFEM_TIMER_TYPE == 0)
247 return 1.0 / CLOCKS_PER_SEC; // potential resolution
248#elif (MFEM_TIMER_TYPE == 1)
249 return 1.0 / my_CLK_TCK;
250#elif (MFEM_TIMER_TYPE == 2)
251 // return the resolution of the "real time" clock, CLOCK_MONOTONIC, which may
252 // be different from the resolution of the "user time" clock,
253 // CLOCK_PROCESS_CPUTIME_ID.
254 struct timespec res;
255 clock_getres(CLOCK_MONOTONIC, &res);
256 return res.tv_sec + 1e-9*res.tv_nsec;
257#elif (MFEM_TIMER_TYPE == 3)
258 return 1.0 / frequency.QuadPart;
259#elif (MFEM_TIMER_TYPE == 4)
260 return 1.0 / CLOCKS_PER_SEC; // potential resolution
261 // return 1e-9; // not real resolution
262#elif (MFEM_TIMER_TYPE == 5)
263 return 1e-6; // not real resolution
264#elif (MFEM_TIMER_TYPE == 6)
265 return MPI_Wtick();
266#endif
267}
268
269inline double StopWatch::RealTime()
270{
271#if (MFEM_TIMER_TYPE == 0)
272 return UserTime();
273#elif (MFEM_TIMER_TYPE == 1)
274 clock_t curr_rtime, curr_utime, curr_stime;
275 clock_t rtime = real_time;
276 if (Running)
277 {
278 Current(&curr_rtime, &curr_utime, &curr_stime);
279 rtime += (curr_rtime - start_rtime);
280 }
281 return (double)(rtime) / my_CLK_TCK;
282#elif (MFEM_TIMER_TYPE == 2)
283 if (Running)
284 {
285 struct timespec curr_rtime;
286 GetRealTime(curr_rtime);
287 return ((real_time.tv_sec + (curr_rtime.tv_sec - start_rtime.tv_sec)) +
288 1e-9*(real_time.tv_nsec +
289 (curr_rtime.tv_nsec - start_rtime.tv_nsec)));
290 }
291 else
292 {
293 return real_time.tv_sec + 1e-9*real_time.tv_nsec;
294 }
295#elif (MFEM_TIMER_TYPE == 3)
296 LARGE_INTEGER curr_rtime, rtime = real_time;
297 if (Running)
298 {
299 QueryPerformanceCounter(&curr_rtime);
300 rtime.QuadPart += (curr_rtime.QuadPart - start_rtime.QuadPart);
301 }
302 return (double)(rtime.QuadPart) / frequency.QuadPart;
303#elif (MFEM_TIMER_TYPE == 4)
304 uint64_t rtime = real_time;
305 if (Running)
306 {
307 rtime += (mach_absolute_time() - start_rtime);
308 }
309 return 1e-9*rtime*ratio.numer/ratio.denom;
310#elif (MFEM_TIMER_TYPE == 5)
311 if (Running)
312 {
313 struct timeval curr_rtime;
314 gettimeofday(&curr_rtime, NULL);
315 real_time.tv_sec += ( curr_rtime.tv_sec - start_rtime.tv_sec );
316 real_time.tv_usec += ( curr_rtime.tv_usec - start_rtime.tv_usec );
317 return ((real_time.tv_sec + (curr_rtime.tv_sec - start_rtime.tv_sec)) +
318 1e-6*(real_time.tv_usec +
319 (curr_rtime.tv_usec - start_rtime.tv_usec)));
320 }
321 else
322 {
323 return real_time.tv_sec + 1e-6*real_time.tv_usec;
324 }
325#elif (MFEM_TIMER_TYPE == 6)
326 double rtime = real_time;
327 if (Running)
328 {
329 rtime += (MPI_Wtime() - start_rtime);
330 }
331 return rtime;
332#endif
333}
334
335inline double StopWatch::UserTime()
336{
337#if (MFEM_TIMER_TYPE == 0)
338 std::clock_t utime = user_time;
339 if (Running)
340 {
341 utime += (std::clock() - start_utime);
342 }
343 return (double)(utime) / CLOCKS_PER_SEC;
344#elif (MFEM_TIMER_TYPE == 1)
345 clock_t curr_rtime, curr_utime, curr_stime;
346 clock_t utime = user_time;
347 if (Running)
348 {
349 Current(&curr_rtime, &curr_utime, &curr_stime);
350 utime += (curr_utime - start_utime);
351 }
352 return (double)(utime) / my_CLK_TCK;
353#elif (MFEM_TIMER_TYPE == 2)
354 if (Running)
355 {
356 struct timespec curr_utime;
357 GetUserTime(curr_utime);
358 return ((user_time.tv_sec + (curr_utime.tv_sec - start_utime.tv_sec)) +
359 1e-9*(user_time.tv_nsec +
360 (curr_utime.tv_nsec - start_utime.tv_nsec)));
361 }
362 else
363 {
364 return user_time.tv_sec + 1e-9*user_time.tv_nsec;
365 }
366#elif (MFEM_TIMER_TYPE == 3)
367 return RealTime();
368#elif (MFEM_TIMER_TYPE == 4)
369 std::clock_t utime = user_time;
370 if (Running)
371 {
372 utime += (std::clock() - start_utime);
373 }
374 return (double)(utime) / CLOCKS_PER_SEC;
375#elif (MFEM_TIMER_TYPE == 5)
376 return RealTime();
377#elif (MFEM_TIMER_TYPE == 6)
378 return RealTime();
379#endif
380}
381
382inline double StopWatch::SystTime()
383{
384#if (MFEM_TIMER_TYPE == 1)
385 clock_t curr_rtime, curr_utime, curr_stime;
386 clock_t stime = syst_time;
387 if (Running)
388 {
389 Current(&curr_rtime, &curr_utime, &curr_stime);
390 stime += (curr_stime - start_stime);
391 }
392 return (double)(stime) / my_CLK_TCK;
393#else
394 return 0.0;
395#endif
396}
397
398} // namespace internal
399
400
401StopWatch::StopWatch() : M(new internal::StopWatch) { }
402
404 : M(new internal::StopWatch(*(sw.M))) { }
405
407{
408 M->Clear();
409}
410
412{
413 M->Start();
414}
415
417{
418 Clear();
419 Start();
420}
421
423{
424 M->Stop();
425}
426
428{
429 return M->Resolution();
430}
431
433{
434 return M->RealTime();
435}
436
438{
439 return M->UserTime();
440}
441
443{
444 return M->SystTime();
445}
446
447StopWatch::~StopWatch() = default;
448
449
451
452void tic()
453{
454 tic_toc.Clear();
455 tic_toc.Start();
456}
457
458double toc()
459{
460 return tic_toc.UserTime();
461}
462
463}
Timing object.
Definition tic_toc.hpp:36
double SystTime()
Return the number of system seconds elapsed since the stopwatch was started.
Definition tic_toc.cpp:442
double RealTime()
Return the number of real seconds elapsed since the stopwatch was started.
Definition tic_toc.cpp:432
~StopWatch()
Default destructor.
void Start()
Start the stopwatch. The elapsed time is not cleared.
Definition tic_toc.cpp:411
void Restart()
Clears and restarts the stopwatch. Equivalent to Clear() followed by Start().
Definition tic_toc.cpp:416
StopWatch()
Creates a new (stopped) StopWatch object.
Definition tic_toc.cpp:401
double UserTime()
Return the number of user seconds elapsed since the stopwatch was started.
Definition tic_toc.cpp:437
double Resolution()
Return the time resolution available to the stopwatch.
Definition tic_toc.cpp:427
void Stop()
Stop the stopwatch.
Definition tic_toc.cpp:422
void Clear()
Clear the elapsed time on the stopwatch and restart it if it's running.
Definition tic_toc.cpp:406
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
double toc()
End timing and return the time from tic() to toc() in seconds.
Definition tic_toc.cpp:458
void tic()
Start the tic_toc timer.
Definition tic_toc.cpp:452
StopWatch tic_toc
Definition tic_toc.cpp:450
RefCoord s[3]