Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
stacked_timer.cpp
Go to the documentation of this file.
1// @HEADER
2// @HEADER
3
11#include <sstream>
12#include <thread> // std::this_thread::sleep_for;
13#include <tuple>
14#include <regex>
15#include <iterator>
16#include <limits>
17
18#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
19#include "Kokkos_Core.hpp"
20#endif
21
22TEUCHOS_UNIT_TEST(PerformanceMonitorBase, UnsortedMergeUnion) {
23
25
26 Teuchos::Array<std::string> a,b, tmp_a, tmp_b;
27
28 a.push_back("foo");
29 a.push_back("bar");
30 a.push_back("car");
31
32 b.push_back("car");
33 b.push_back("bar");
34 b.push_back("cat");
35
36
37 tmp_a=a;
38 tmp_b=b;
40 TEST_EQUALITY(tmp_b.size(),4);
41 TEST_EQUALITY(tmp_b[0], "car");
42 TEST_EQUALITY(tmp_b[1], "bar");
43 TEST_EQUALITY(tmp_b[2], "cat");
44 TEST_EQUALITY(tmp_b[3], "foo");
45}
46
47TEUCHOS_UNIT_TEST(PerformanceMonitorBase, UnsortedMergeIntersection) {
48
50
51 Teuchos::Array<std::string> a,b, tmp_a, tmp_b;
52
53 a.push_back("foo");
54 a.push_back("bar");
55 a.push_back("car");
56
57 b.push_back("car");
58 b.push_back("bar");
59 b.push_back("cat");
60
61
62 tmp_a=a;
63 tmp_b=b;
65 TEST_EQUALITY(tmp_b.size(),2);
66 TEST_EQUALITY(tmp_b[0], "car");
67 TEST_EQUALITY(tmp_b[1], "bar");
68}
69
70TEUCHOS_UNIT_TEST(StackedTimer, Basic)
71{
73 const int myRank = Teuchos::rank(*comm);
74
75 Teuchos::StackedTimer timer("My New Timer");
76 timer.enableVerbose(true);
77 timer.setVerboseOstream(Teuchos::rcpFromRef(std::cout));
78 timer.start("Total Time");
79 {
80 for (int i=0; i < 10; ++i) {
81
82 timer.start("Assembly");
83 std::this_thread::sleep_for(std::chrono::milliseconds{100});
84 timer.stop("Assembly");
85
86 timer.start("Solve");
87 {
88 timer.start("Prec");
89 std::this_thread::sleep_for(std::chrono::milliseconds{50});
90 timer.stop("Prec");
91
92 // Test different timers on different mpi processes
93 if (myRank == 0 ) {
94 const std::string label = "Rank 0 ONLY";
95 timer.start(label);
96 std::this_thread::sleep_for(std::chrono::milliseconds{50});
97 TEST_ASSERT((timer.findTimer("My New Timer@Total Time@Solve@Rank 0 ONLY")).running);
98 timer.stop(label);
99 TEST_ASSERT(!(timer.findTimer("My New Timer@Total Time@Solve@Rank 0 ONLY")).running);
100 } else {
101 timer.start("Not Rank 0");
102 std::this_thread::sleep_for(std::chrono::milliseconds{50});
103 TEST_ASSERT((timer.findTimer("My New Timer@Total Time@Solve@Not Rank 0")).running);
104 timer.stop("Not Rank 0");
105 TEST_ASSERT(!(timer.findTimer("My New Timer@Total Time@Solve@Not Rank 0")).running);
106 }
107 }
108 timer.stop("Solve");
109
110 }
111 }
112 timer.stop("Total Time");
113 timer.stopBaseTimer();
114
115 TEST_EQUALITY((timer.findTimer("My New Timer@Total Time")).count, 1);
116 TEST_EQUALITY((timer.findTimer("My New Timer@Total Time@Assembly")).count, 10);
117 TEST_EQUALITY((timer.findTimer("My New Timer@Total Time@Solve")).count, 10);
118 TEST_EQUALITY((timer.findTimer("My New Timer@Total Time@Solve@Prec")).count, 10);
119
120 // Test for exception for bad timer name
121 TEST_THROW(timer.findTimer("Testing misspelled timer name!"),std::runtime_error);
122
123 // Pre-aggregation
124 if (myRank == 0) {
125 TEST_EQUALITY((timer.findTimer("My New Timer@Total Time@Solve@Rank 0 ONLY")).count, 10);
126 }
127 else {
128 TEST_EQUALITY((timer.findTimer("My New Timer@Total Time@Solve@Not Rank 0")).count, 10);
129 }
130
132 options.output_histogram=true;
133 options.num_histogram=3;
134 options.print_warnings=false;
135
136 // Get the report
137 std::stringstream sout1;
138 timer.report(sout1, comm, options);
139
140 // Make sure can call report() multiple times, i.e. aggregation
141 // resets correctly for each call report()
142 std::stringstream sout2;
143 timer.report(sout2, comm, options);
144 TEST_EQUALITY(sout1.str(),sout2.str());
145
146 // Gold file results (timer name,expected runtime,number of calls)
147 std::vector<std::tuple<std::string,double,unsigned long>> lineChecks;
148 lineChecks.push_back(std::make_tuple("My New Timer:",2.0,1));
149 lineChecks.push_back(std::make_tuple("Total Time:",2.0,1));
150 lineChecks.push_back(std::make_tuple("Assembly:",1.0,10));
151 lineChecks.push_back(std::make_tuple("Solve:",1.0,10));
152 lineChecks.push_back(std::make_tuple("Prec:",0.5,10));
153
154 // Check the report() output. Read the first few lines and parse the
155 // expected timer label, the runtime and the counts.
156 //
157 // * NOTE: The report only combines values to a single MPI process, so
158 // only check on that process.
159 // * NOTE: regex not supported in gcc until 4.9. Can drop this check
160 // when Trilinos drops support for gcc 4.8.
161#if !defined(__GNUC__) \
162 || ( defined(__GNUC__) && (__GNUC__ > 4) ) \
163 || ( defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC__MINOR__ > 8) )
164
165 if (myRank == 0) {
166 const double timerTolerance = 0.25; // +- 0.25 seconds
167 std::istringstream is(sout1.str());
168 for (const auto& check : lineChecks) {
169
170 std::string line;
171 std::getline(is,line);
172 std::smatch regexSMatch;
173 std::regex timerName(std::get<0>(check));
174 std::regex_search(line,regexSMatch,timerName);
175 TEST_ASSERT(!regexSMatch.empty());
176
177 // Split string to get time and count
178 std::regex delimiter(":\\s|\\s\\[|\\]\\s");
179 std::sregex_token_iterator tok(line.begin(), line.end(),delimiter,-1);
180
181 const std::string timeAsString = (++tok)->str();
182 const double time = std::stod(timeAsString);
183 TEST_FLOATING_EQUALITY(time,std::get<1>(check),timerTolerance);
184
185 const std::string countAsString = (++tok)->str();
186 const unsigned long count = std::stoul(countAsString);
187 TEST_EQUALITY(count,std::get<2>(check));
188 }
189 }
190#endif
191
192 // Print to screen
193 out << "\n### Printing default report ###" << std::endl;
195 timer.report(out, comm, defaultOptions);
196
197 // Test some options
198 out << "\n### Printing aligned_column with timers names on left ###" << std::endl;
199 options.output_fraction = true;
200 options.output_total_updates = true;
201 options.output_minmax = true;
202 options.output_histogram = true;
203 options.num_histogram = 3;
204 options.align_columns = true;
205 timer.report(out, comm, options);
206
207 // Toggle names before values
209 out << "\n### Printing aligned_column with timers names on right ###" << std::endl;
210 options.print_names_before_values = false;
211 // Make sure neither report() nor reportXML() have side effects that change the output:
212 // calling them any number of times with no new starts/stops and the same OutputOptions
213 // should produce identical output.
214 //
215 // This is very important as performance tests will
216 // typically call both report() and reportWatchrXML().
217 std::string reportOut;
218 {
219 std::ostringstream reportOut1;
220 timer.report(reportOut1, comm, options);
221 std::ostringstream reportOut2;
222 timer.report(reportOut2, comm, options);
223 reportOut = reportOut1.str();
224 TEST_EQUALITY(reportOut, reportOut2.str());
225 }
226 std::string reportXmlOut;
227 {
228 std::ostringstream reportOut1;
229 timer.reportXML(reportOut1, "2020_01_01", "2020-01-01T01:02:03", comm);
230 std::ostringstream reportOut2;
231 timer.reportXML(reportOut2, "2020_01_01", "2020-01-01T01:02:03", comm);
232 reportXmlOut = reportOut1.str();
233 TEST_EQUALITY(reportXmlOut, reportOut2.str());
234 }
235 out << reportOut << '\n';
236 out << reportXmlOut << '\n';
237}
238
239TEUCHOS_UNIT_TEST(StackedTimer, UnitTestSupport)
240{
242 const int myRank = Teuchos::rank(*comm);
243
244 const auto timeMonitorDefaultStackedTimer = Teuchos::TimeMonitor::getStackedTimer();
245 const auto timer = Teuchos::rcp(new Teuchos::StackedTimer("Total Time", false));
246 timer->startBaseTimer();
247 for (int i=0; i < 10; ++i) {
248 timer-> start("Subtask");
249 timer->incrementUpdates();
250 timer->incrementUpdates(2);
251 timer-> stop("Subtask");
252 }
253 timer->stopBaseTimer();
254
255 // If users want to set timer values for unit testing, force them to
256 // const_cast the timer by returning a const Timer object.
257 auto top_timer = const_cast<Teuchos::BaseTimer*>(timer->findBaseTimer("Total Time"));
258 auto sub_timer = const_cast<Teuchos::BaseTimer*>(timer->findBaseTimer("Total Time@Subtask"));
259 TEST_ASSERT(top_timer != nullptr);
260 TEST_ASSERT(sub_timer != nullptr);
261
262 // Test for exception for bad timer name
263 TEST_THROW(timer->findBaseTimer("Testing misspelled timer name!"),std::runtime_error);
264
265 {
266 TEST_EQUALITY(top_timer->numCalls(),1);
267 TEST_EQUALITY(top_timer->numUpdates(),0);
268 TEST_EQUALITY(sub_timer->numCalls(),10);
269 TEST_EQUALITY(sub_timer->numUpdates(),30);
270 }
271
272 // Test the serial version of report
273 if (myRank == 0)
274 timer->report(out);
275
276 // Override timers for unit testing
277 top_timer->setAccumulatedTime(5000.0);
278 top_timer->overrideNumCallsForUnitTesting(2);
279 top_timer->overrideNumUpdatesForUnitTesting(3);
280 sub_timer->setAccumulatedTime(4000.0);
281 sub_timer->overrideNumCallsForUnitTesting(4);
282 sub_timer->overrideNumUpdatesForUnitTesting(5);
283 {
284 const double timerTolerance = 100.0 * std::numeric_limits<double>::epsilon();
285 TEST_FLOATING_EQUALITY(5000.0,top_timer->accumulatedTime(),timerTolerance);
286 TEST_EQUALITY(top_timer->numCalls(),2);
287 TEST_EQUALITY(top_timer->numUpdates(),3);
288 TEST_FLOATING_EQUALITY(4000.0,sub_timer->accumulatedTime(),timerTolerance);
289 TEST_EQUALITY(sub_timer->numCalls(),4);
290 TEST_EQUALITY(sub_timer->numUpdates(),5);
291 }
292
293 if (myRank == 0)
294 timer->report(out);
295}
296
297TEUCHOS_UNIT_TEST(StackedTimer, TimeMonitorInteroperability)
298{
300
301 const auto diffTimer = Teuchos::TimeMonitor::getNewTimer("Diffusion Term");
302 const auto rxnTimer = Teuchos::TimeMonitor::getNewTimer("Reaction Term");
303 const auto precTimer = Teuchos::TimeMonitor::getNewTimer("Prec");
304 const auto gmresTimer = Teuchos::TimeMonitor::getNewTimer("GMRES");
305
306 // Test the set and get stacked timer methods on TimeMonitor
307 const auto timeMonitorDefaultStackedTimer = Teuchos::TimeMonitor::getStackedTimer();
308 const auto timer = Teuchos::rcp(new Teuchos::StackedTimer("TM:Interoperability"));
309 TEST_ASSERT(nonnull(timeMonitorDefaultStackedTimer));
310 TEST_ASSERT(nonnull(timer));
311 TEST_ASSERT(timeMonitorDefaultStackedTimer != timer);
314
315 timer->start("Total Time");
316 {
317 for (int i=0; i < 10; ++i) {
318
319 timer->start("Assembly");
320 {
321 {
322 Teuchos::TimeMonitor tm(*diffTimer);
323 std::this_thread::sleep_for(std::chrono::milliseconds{25});
324 }
325 {
326 Teuchos::TimeMonitor tm(*rxnTimer);
327 std::this_thread::sleep_for(std::chrono::milliseconds{75});
328 }
329 // Remainder
330 std::this_thread::sleep_for(std::chrono::milliseconds{100});
331 }
332 timer->stop("Assembly");
333 timer->start("Solve");
334 {
335 {
336 Teuchos::TimeMonitor tm(*precTimer);
337 std::this_thread::sleep_for(std::chrono::milliseconds{50});
338 }
339 {
340 Teuchos::TimeMonitor tm(*gmresTimer);
341 std::this_thread::sleep_for(std::chrono::milliseconds{50});
342 }
343 // Remainder
344 std::this_thread::sleep_for(std::chrono::milliseconds{100});
345 }
346 timer->stop("Solve");
347 std::this_thread::sleep_for(std::chrono::milliseconds{100});
348 }
349 }
350 timer->stop("Total Time");
351 timer->stopBaseTimer();
352
353 assert(size(*comm)>0);
354
355 TEST_EQUALITY((timer->findTimer("TM:Interoperability@Total Time")).count, 1);
356 TEST_EQUALITY((timer->findTimer("TM:Interoperability@Total Time@Assembly")).count, 10);
357
358 // Make sure the TimeMonitor added the timers
359#ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
360 TEST_EQUALITY((timer->findTimer("TM:Interoperability@Total Time@Solve@Prec")).count, 10);
361 TEST_EQUALITY((timer->findTimer("TM:Interoperability@Total Time@Solve@GMRES")).count, 10);
362#endif
363
365 out << "\n### Printing default report ###" << std::endl;
366 options.output_histogram=true;
367 options.num_histogram=3;
368 options.output_fraction=true;
369 timer->report(out, comm, options);
370
371 out << "\n### Printing aligned_column with timers names on left ###" << std::endl;
372 options.align_columns = true;
373 timer->report(out, comm, options);
374
375 out << "\n### Printing aligned_column with timers names on right ###" << std::endl;
376 // options.print_names_before_values=false requires that
377 // options.align_output=true. The code will automatically fix this
378 // and print a warning if warnings are enabled. Testing this here by
379 // specifying the incorrect logic.
380 options.align_columns = false;
381 options.print_names_before_values = false;
382 timer->report(out, comm, options);
383
384 //Testing limited number of levels in printing
385 out << "\n### Printing with max_levels=2 ###" << std::endl;
386 options.max_levels=2;
387 options.align_columns = true;
388 options.print_names_before_values = true;
389 timer->report(out, comm, options);
390}
391
392TEUCHOS_UNIT_TEST(StackedTimer, drop_time)
393{
394
395 Teuchos::StackedTimer timer("L0");
396 timer.start("L1a");
397 timer.start("L2a");
398 timer.stop("L2a");
399 timer.start("L2b");
400 timer.stop("L2b");
401 timer.stop("L1a");
402 timer.start("L1b");
403 timer.start("L2c");
404 timer.stop("L2c");
405 timer.start("L2d");
406 timer.stop("L2d");
407 timer.stop("L1b");
408 timer.stopBaseTimer();
409
410 const_cast<Teuchos::BaseTimer*>(timer.findBaseTimer("L0"))->setAccumulatedTime(5.0);
411 const_cast<Teuchos::BaseTimer*>(timer.findBaseTimer("L0@L1a"))->setAccumulatedTime(3.0);
412 const_cast<Teuchos::BaseTimer*>(timer.findBaseTimer("L0@L1a@L2a"))->setAccumulatedTime(0.4);
413 const_cast<Teuchos::BaseTimer*>(timer.findBaseTimer("L0@L1a@L2b"))->setAccumulatedTime(1.01);
414 const_cast<Teuchos::BaseTimer*>(timer.findBaseTimer("L0@L1b"))->setAccumulatedTime(0.1);
415 const_cast<Teuchos::BaseTimer*>(timer.findBaseTimer("L0@L1b@L2c"))->setAccumulatedTime(0.05);
416 const_cast<Teuchos::BaseTimer*>(timer.findBaseTimer("L0@L1b@L2d"))->setAccumulatedTime(0.04);
417
419 const int myRank = Teuchos::rank(*comm);
421 options.drop_time = 1.0;
422
423 out << "\n### Printing default report ###" << std::endl;
424 options.output_histogram=true;
425 options.num_histogram=3;
426 options.output_fraction=true;
427 timer.report(out, comm, options);
428 {
429 std::ostringstream os;
430 timer.report(os, comm, options);
431 if (myRank == 0) {
432 TEST_ASSERT(os.str().find("L2a") == std::string::npos); // should be dropped
433 TEST_ASSERT(os.str().find("L2b") != std::string::npos); // should be printed
434 TEST_ASSERT(os.str().find("L1b") == std::string::npos); // should be dropped
435 }
436 }
437
438 out << "\n### Printing aligned_column with timers names on left ###" << std::endl;
439 options.align_columns = true;
440 timer.report(out, comm, options);
441 {
442 std::ostringstream os;
443 timer.report(os, comm, options);
444 if (myRank == 0) {
445 TEST_ASSERT(os.str().find("L2a") == std::string::npos); // should be dropped
446 TEST_ASSERT(os.str().find("L2b") != std::string::npos); // should be printed
447 TEST_ASSERT(os.str().find("L1b") == std::string::npos); // should be dropped
448 }
449 }
450
451 out << "\n### Printing aligned_column with timers names on right ###" << std::endl;
452 options.align_columns = false;
453 options.print_names_before_values = false;
454 timer.report(out, comm, options);
455 {
456 std::ostringstream os;
457 timer.report(os, comm, options);
458 if (myRank == 0) {
459 TEST_ASSERT(os.str().find("L2a") == std::string::npos); // should be dropped
460 TEST_ASSERT(os.str().find("L2b") != std::string::npos); // should be printed
461 TEST_ASSERT(os.str().find("L1b") == std::string::npos); // should be dropped
462 }
463 }
464}
465
466TEUCHOS_UNIT_TEST(StackedTimer, proc_minmax)
467{
468
469 Teuchos::StackedTimer timer("L0");
470 timer.stopBaseTimer();
471
473 if (comm->getSize() < 2)
474 return;
475 const int myRank = Teuchos::rank(*comm);
476
477 if (myRank == 0)
478 const_cast<Teuchos::BaseTimer*>(timer.findBaseTimer("L0"))->setAccumulatedTime(1.0);
479 else if (myRank == 1)
480 const_cast<Teuchos::BaseTimer*>(timer.findBaseTimer("L0"))->setAccumulatedTime(5.0);
481 else
482 const_cast<Teuchos::BaseTimer*>(timer.findBaseTimer("L0"))->setAccumulatedTime(2.0);
483
485
486 out << "\n### Printing default report ###" << std::endl;
487 options.output_minmax=true;
488 options.output_proc_minmax=true;
489 options.output_histogram=true;
490 options.num_histogram=3;
491 options.output_fraction=true;
492 timer.report(out, comm, options);
493 {
494 std::ostringstream os;
495 timer.report(os, comm, options);
496 if (myRank == 0) {
497 TEST_ASSERT(os.str().find("proc min=0") != std::string::npos);
498 TEST_ASSERT(os.str().find("proc max=1") != std::string::npos);
499 }
500 }
501}
502
503
504// Overlapping timers are not allowed in a StackedTimer, but are in
505// TimeMonitor. Since StackedTimer is automatically used in
506// TimeMonitor by default, we have seen this error - a throw from the
507// stacked timer. In every instance so far, the intention was not to
508// actually overlap but a constructor/destructor ordering issue
509// (usually involving RCPs). To prevent tests from failing,
510// StackedTimer now automatically shuts itself off if it detects
511// overlaped timers in a TimeMonitor instance, reports a warning on
512// how to fix and allows the code to continue runnning. Where this has
513// occurred in Trilinos is when a TimeMonitor object is stored in an
514// RCP and then the RCP is reassigned to a new timer. The intention
515// was to stop one and start another. But the destruction of one and
516// the creation of the new one occurs in the wrong order. This test
517// demonstrates the issue.
518TEUCHOS_UNIT_TEST(StackedTimer, OverlappingTimersException)
519{
520 Teuchos::StackedTimer timer("My Timer");
521 timer.start("Outer");
522 timer.start("Inner");
523 // Should stop inner before outer
524 TEST_THROW(timer.stop("Outer"),std::runtime_error);
525 timer.stop("Inner");
526 timer.stop("Outer");
527 timer.stopBaseTimer();
528}
529
530
531#ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
532TEUCHOS_UNIT_TEST(StackedTimer, OverlappingTimersViaRCP)
533{
534 const auto precTimer = Teuchos::TimeMonitor::getNewTimer("Prec");
535 const auto gmresTimer = Teuchos::TimeMonitor::getNewTimer("GMRES");
536
538 timer = Teuchos::rcp(new Teuchos::TimeMonitor(*gmresTimer));
539
541}
542#endif
543
544// Use our own main to initialize kokkos before calling
545// runUnitTestsFromMain(). The kokkos space_time_stack profiler seg
546// faults due to inconsistent push/pop of timers in the teuchos unit
547// test startup code. By calling initialize here we can use the
548// space_time_stack profiler with this unit test.
549int main( int argc, char* argv[] )
550{
551 // Note that the dtor for GlobalMPISession will call
552 // Kokkos::finalize().
553 Teuchos::GlobalMPISession mpiSession(&argc, &argv);
554#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
555 Kokkos::initialize(argc,argv);
556#endif
557 {
558 Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout));
559 out.setOutputToRootOnly(0);
560 }
562
563 auto return_val = Teuchos::UnitTestRepository::runUnitTestsFromMain(argc, argv);
564#if defined(HAVE_TEUCHOS_KOKKOS_PROFILING) && defined(HAVE_TEUCHOSCORE_KOKKOSCORE)
565 if (Kokkos::is_initialized())
566 Kokkos::finalize();
567#endif
568 return return_val;
569}
570
571// gcc 4.X is incomplete in c++11 standard - missing
572// std::put_time. We'll disable this feature for gcc 4.
573#if !defined(__GNUC__) || ( defined(__GNUC__) && (__GNUC__ > 4) )
574TEUCHOS_UNIT_TEST(StackedTimer, VerboseTimestamps) {
575
576 Teuchos::StackedTimer timer("My Timer");
577
578 timer.enableVerbose(true);
580 std::ostringstream os;
581 timer.setVerboseOstream(Teuchos::rcpFromRef(os));
582
583 timer.start("L1");
584 timer.start("L2");
585 timer.start("L3");
586 timer.stop("L3");
587 timer.stop("L2");
588 timer.stop("L1");
589 timer.stopBaseTimer();
590
591 out << os.str() << std::endl;
592
593 TEST_ASSERT(os.str().find("TIMESTAMP:"));
594
595 // Printing restricted to first two levels, thrid level should not
596 // be printed.
597 TEST_ASSERT(os.str().find("L1") != std::string::npos);
598 TEST_ASSERT(os.str().find("L2") != std::string::npos);
599 TEST_ASSERT(os.str().find("L3") == std::string::npos);
600}
601#endif
602
603// Tests that we can turn off timers for regions of asychronous
604// execution.
605TEUCHOS_UNIT_TEST(StackedTimer, DisableTimers)
606{
607 Teuchos::StackedTimer timer("My New Timer");
608 timer.start("Total Time");
609 {
610 for (int i=0; i < 10; ++i) {
611
612 timer.start("Assembly");
613 timer.stop("Assembly");
614
615 // Async execution means the timers will stop out of order. Out
616 // of order timers causes exception to be thrown.
617
618 timer.disableTimers(); // Stop recording timers
619 timer.start("Solve");
620 {
621 timer.start("Prec");
622
623 // This stop() is out of order and would trigger an exception
624 // if we did not disable the timers above.
625 timer.stop("Solve");
626
627 timer.stop("Prec");
628 }
629 timer.enableTimers(); // Start recording timers
630
631 // Make sure the timers are reenabled
632 timer.start("Restarted");
633 timer.stop("Restarted");
634 }
635 }
636 timer.stop("Total Time");
637 timer.stopBaseTimer();
638
639 TEST_EQUALITY((timer.findTimer("My New Timer@Total Time")).count, 1);
640 TEST_EQUALITY((timer.findTimer("My New Timer@Total Time@Assembly")).count, 10);
641 TEST_EQUALITY((timer.findTimer("My New Timer@Total Time@Restarted")).count, 10);
642 // Should not exist since we disabled the timers
643 TEST_THROW(timer.findTimer("My New Timer@Total Time@Solve"),std::runtime_error);
644 TEST_THROW(timer.findTimer("My New Timer@Total Time@Solve@Prec"),std::runtime_error);
645}
A MPI utilities class, providing methods for initializing, finalizing, and querying the global MPI se...
#define TEST_ASSERT(v1)
Assert the given statement is true.
#define TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
#define TEST_THROW(code, ExceptType)
Assert that the statement 'code' throws the exception 'ExceptType' (otherwise the test fails).
#define TEST_FLOATING_EQUALITY(v1, v2, tol)
Assert the relative floating-point equality of rel_error(v1,v2) <= tol.
Common capabilities for collecting and reporting performance data collectively across MPI processes.
Scope guard for Teuchos::Time, with MPI collective timer reporting.
Unit testing support.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
Unit testing support.
the basic timer used elsewhere, uses MPI_Wtime for time
int size(const Comm< Ordinal > &comm)
Get the number of processes in the communicator.
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
Return the default global communicator.
Initialize, finalize, and query the global MPI session.
Concrete serial communicator subclass.
This class allows one to push and pop timers on and off a stack.
void start(const std::string name, const bool push_kokkos_profiling_region=true)
BaseTimer::TimeInfo findTimer(const std::string &name)
void stop(const std::string &name, const bool pop_kokkos_profiling_region=true)
const BaseTimer * findBaseTimer(const std::string &name) const
void report(std::ostream &os)
void enableVerboseTimestamps(const unsigned levels)
Enable timestamps in verbose mode for the number of levels specified.
void setVerboseOstream(const Teuchos::RCP< std::ostream > &os)
Set the ostream for verbose mode(defaults to std::cout).
void enableVerbose(const bool enable_verbose)
If set to true, print timer start/stop to verbose ostream.
void reportXML(std::ostream &os, const std::string &datestamp, const std::string &timestamp, Teuchos::RCP< const Teuchos::Comm< int > > comm)
Scope guard for Time, that can compute MPI collective timer statistics.
static Teuchos::RCP< Teuchos::StackedTimer > getStackedTimer()
The StackedTimer used by the TimeMonitor.
static void setStackedTimer(const Teuchos::RCP< Teuchos::StackedTimer > &t)
Sets the StackedTimer into which the TimeMonitor will insert timings.
static RCP< Time > getNewTimer(const std::string &name)
Return a new timer with the given name (class method).
static int runUnitTestsFromMain(int argc, char *argv[])
Run the unit tests from main() passing in (argc, argv).
static void setGloballyReduceTestResult(const bool globallyReduceUnitTestResult)
Set if the unit tests should reduce pass/fail across processes.
std::ostream subclass that performs the magic of indenting data sent to an std::ostream object among ...
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
Set the stream to print only on the (MPI) process with the given rank.
int main()
Definition evilMain.cpp:75
bool is_null(const boost::shared_ptr< T > &p)
Returns true if p.get()==NULL.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
void unsortedMergePair(const Array< std::string > &localNames, Array< std::string > &globalNames, const ECounterSetOp setOp)