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.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
size_type size() const
void push_back(const value_type &x)
the basic timer used elsewhere, uses MPI_Wtime for time
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
Return the default global communicator.
Initialize, finalize, and query the global MPI session.
Smart reference counting pointer class for automatic garbage collection.
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)