Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
stacked_timer.cpp
Go to the documentation of this file.
1 // @HEADER
2 // @HEADER
3 
10 #include "Teuchos_DefaultComm.hpp"
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 
22 TEUCHOS_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 
47 TEUCHOS_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 
70 TEUCHOS_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 
239 TEUCHOS_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 
297 TEUCHOS_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 
392 TEUCHOS_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 
466 TEUCHOS_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.
518 TEUCHOS_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
532 TEUCHOS_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.
549 int main( int argc, char* argv[] )
550 {
551  // Note that the dtor for GlobalMPISession will call
552  // Kokkos::finalize_all().
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_all();
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) )
574 TEUCHOS_UNIT_TEST(StackedTimer, VerboseTimestamps) {
575 
576  Teuchos::StackedTimer timer("My Timer");
577 
578  timer.enableVerbose(true);
579  timer.enableVerboseTimestamps(2);
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
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.
Unit testing support.
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
bool nonnull(const ArrayRCP< T > &p)
Returns true if p.get()!=NULL.
size_type size() const
void push_back(const value_type &x)
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.
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)
void setVerboseOstream(const Teuchos::RCP< std::ostream > &os)
void enableVerbose(const bool enable_verbose)
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 RCP< Time > getNewTimer(const std::string &name)
Return a new timer with the given name (class method).
static void setStackedTimer(const Teuchos::RCP< Teuchos::StackedTimer > &t)
Sets the StackedTimer into which the TimeMonitor will insert timings.
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.
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)
int main(int argc, char *argv[])
TEUCHOS_UNIT_TEST(PerformanceMonitorBase, UnsortedMergeUnion)