Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_ComparisonHelper.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Zoltan2: A package of combinatorial algorithms for scientific computing
4 //
5 // Copyright 2012 NTESS and the Zoltan2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
14 #pragma once
15 
16 #include "Zoltan2_TestHelpers.hpp"
18 #include <Zoltan2_Typedefs.hpp>
21 #include <AdapterForTests.hpp>
22 #include <Teuchos_DefaultComm.hpp>
23 #include <Teuchos_Time.hpp>
24 #include <Teuchos_StackedTimer.hpp>
25 
26 #include <sstream>
27 #include <string>
28 #include <map>
29 #include <iostream>
30 
31 using Teuchos::Comm;
32 using Teuchos::RCP;
33 using Teuchos::ParameterList;
34 using Teuchos::Time;
35 using std::string;
36 using std::map;
37 using std::pair;
38 using Teuchos::reduceAll;
39 using namespace Zoltan2_TestingFramework;
40 
45 {
46 public:
47 
48  ComparisonSource(Teuchos::RCP<Teuchos::StackedTimer>& stackedTimer,
49  const std::string& problemName)
50  : stackedTimer_(stackedTimer)
51  , problemName_(problemName) {}
52 
53  void startBaseTimer() {
54  stackedTimer_->start(problemName_);
55  }
56 
57  void stopBaseTimer() {
58  stackedTimer_->stop(problemName_);
59  }
60 
61  void startTimer(const std::string& timerName) {
62  stackedTimer_->start(timerName);
63  }
64 
65  void stopTimer(const std::string& timerName) {
66  stackedTimer_->stop(timerName);
67  }
68 
69  std::map<std::string, double> getTimingsMap() const {
70  // todo: get all sub-timers
71  std::map<std::string, double> timings;
72  std::string prefix = stackedTimer_->name()+"@"+problemName_+"@";
73  for (auto timerName : {"adapter construction timer", "problem construction time", "solve time"}) {
74  auto t = stackedTimer_->findTimer(prefix+timerName);
75  timings[timerName] = t.time;
76  }
77  return timings;
78  }
79 
80 private:
81  Teuchos::RCP<Teuchos::StackedTimer> stackedTimer_;
82  const std::string problemName_;
83 
84 public:
85  RCP<EvaluateFactory> evaluateFactory;
86  RCP<ProblemFactory> problemFactory;
87  RCP<AdapterFactory> adapterFactory;
88 };
89 
93 {
94 public:
95 
96  ComparisonHelper(Teuchos::RCP<Teuchos::StackedTimer>& stackedTimer)
97  :stackedTimer_(stackedTimer) {}
98 
99  /* \brief Compare the solutions, metrics or timers of two Zoltan2 solutions.
100  * \param pList is a parameter list defining the comparison
101  * \param comm is the process communicator
102  */
103  bool Compare(const ParameterList &pList, const RCP<const Comm<int> > &comm);
104 
105  /* \brief Add a new source by name to the comparison source map.
106  * \param name is the name of the new source
107  * \param source a problem source that to be used for comparison to another source
108  */
109  RCP<ComparisonSource> AddSource(const string &name);
110 
111  /* \brief Return the total number of saved sources.
112  */
113  size_t getNumberOfSources() const
114  {
115  return this->sources.size();
116  }
117 
118 private:
119  map<const string,RCP<const ComparisonSource> > sources;
120 
121  /* \brief Method called to compare two solutions
122  * \param p1 is the name of problem 1
123  * \param p2 is the name of problem 2
124  * \param comm is the process communicator
125  */
126  bool CompareSolutions(const string &p1,
127  const string &p2,
128  const RCP<const Comm<int> > &comm);
129 
130  /* \brief Safely get parts list by adapter type
131  * \param problemFactory is the ProblemFactory
132  */
133  const zpart_t * getPartListView(RCP<ProblemFactory> problemFactory) const;
134 
135  /* \brief Method called to compare two paritioning solutions
136  * \param sourceA is a ptr to problem A's comparison source
137  * \param sourceB is a ptr to problem B's comparison source
138  * \param comm is the process communicator
139  */
140  bool ComparePartitionSolutions(const ComparisonSource * sourceA,
141  const ComparisonSource * sourceB,
142  const RCP<const Comm<int> > &comm);
143 
144  /* \brief Method called to compare two coloring solutions
145  * \param sourceA is a ptr to problem A's comparison source
146  * \param sourceB is a ptr to problem B's comparison source
147  * \param comm is the process communicator
148  */
149  bool CompareColoringSolutions(const ComparisonSource * sourceA,
150  const ComparisonSource * sourceB,
151  const RCP<const Comm<int> > &comm);
152 
153  /* \brief Method called to compare two ordering solutions
154  * \param sourceA is a ptr to problem A's comparison source
155  * \param sourceB is a ptr to problem B's comparison source
156  * \param comm is the process communicator
157  */
158  bool CompareOrderingSolutions(const ComparisonSource * sourceA,
159  const ComparisonSource * sourceB,
160  const RCP<const Comm<int> > &comm);
161 
162  /* \brief Safely get metric info by adapter type.
163  * \param problemFactory is the ProblemFactory
164  * \param metricInfo will be filled
165  * \param metricsPlist are the parameters to read
166  */
167  void loadMetricInfo(RCP<EvaluateFactory> problemFactory,
168  std::vector<MetricAnalyzerInfo> & metricInfo,
169  const ParameterList &metricsPlist);
170 
171  /* \brief Method called to compare the metrics/timers of two problems.
172  * \param metricsPlist is a parameter list defining the comparison
173  * \param comm is the process communicator
174  */
175  bool CompareMetrics(const ParameterList &metricsPlist,
176  const RCP<const Comm<int> > &comm);
177 
178  /* \brief Method that compares two metrics and returns a pass/fail message.
179  * \param[in] comm is the process communicator
180  * \param[in] metric is the metric to be compared to a reference metric
181  * \param[in] ref_metric is the reference metric for comparison
182  * \param[in] metricPlist is the parameter list defining the metric tolerances
183  * \param[out] msg is a returned pass/fail message
184  *
185  * \return boolean value indicated pass/fail status
186  */
187  static bool
188  metricComparisonTest(const RCP<const Comm<int> > &comm,
189  const MetricAnalyzerInfo & metric,
190  const MetricAnalyzerInfo &ref_metric,
191  const Teuchos::ParameterList & metricPlist,
192  std::ostringstream &msg);
193 
194  /* \brief Method that compares two timers and returns a pass/fail message.
195  * \param[in] comm is the process communicator
196  * \param[in] time is the timer data to be compared to a reference metric
197  * \param[in] ref_time is the reference timer for comparison
198  * \param[in] metricPlist is the parameter list defining the timer tolerances
199  * \param[out] msg is a returned pass/fail message
200  *
201  * \return boolean value indicated pass/fail status
202  */
203  static bool
204  timerComparisonTest(const RCP<const Comm<int> > &comm,
205  const double time,
206  const double ref_time,
207  const Teuchos::ParameterList & metricPlist,
208  std::ostringstream &msg);
209 
210  /* \brief Method for inserting data from all timers to a map of clocked times
211  * param[in] timers a map of timers
212  *
213  * \return a map with clocked times from timers
214  */
215  static std::map<const string, const double>
216  timerDataToMap(const map<const std::string, RCP<Time> > &timers);
217 
218 
219  /* \brief Method for extracting all methods to compare from a parameter list
220  * param[in] plist a parameter list defining 1 or more metric/timer comparisons
221  *
222  * \return a queue of metric comparison definitions
223  */
224  static std::queue<ParameterList>
225  getMetricsToCompare(const ParameterList & pList);
226 
227  static void
228  reduceWithMessage(const RCP<const Comm<int> > &comm,
229  const std::string &msg_in,
230  int &local_status, std::ostringstream &msg);
231 
232 private:
233  RCP<Teuchos::StackedTimer> stackedTimer_;
234 
235 };
236 
237 
238 RCP<ComparisonSource> ComparisonHelper::AddSource(const string &name)
239 {
240  typedef std::pair<const string &, RCP<const ComparisonSource> > pair_t;
241  auto source = Teuchos::rcp(new ComparisonSource(stackedTimer_, name));
242  this->sources.insert(pair_t(name, source));
243  return source;
244 }
245 
246 bool ComparisonHelper::Compare(const ParameterList &pList,
247  const RCP<const Comm<int> > &comm)
248 {
249  if(pList.isParameter("A") && pList.isParameter("B")) {
250  // comparing solutions
251  string pA = pList.get<string>("A");
252  if(this->sources.find(pA) == this->sources.end())
253  {
254  std::cout << "\nProblem: " + pA + ", was not saved for comparison.";
255  std::cout << "\nThis typically indicates that an error ";
256  std::cout << "occurred while running the problem.";
257  std::cout << "\nSolution comparison FAILED." << std::endl;
258  return false;
259  }
260 
261  string pB = pList.get<string>("B");
262  if(this->sources.find(pB) == this->sources.end()) {
263  std::cout << "\nProblem: " + pB + ", was not saved for comparison.";
264  std::cout << "\nThis typically indicates that an error ";
265  std::cout << "occurred while running the problem.";
266  std::cout << "\nSolution comparison FAILED." << std::endl;
267  return false;
268  }
269 
270  bool bResult = this->CompareSolutions(pA, pB, comm);
271  return bResult;
272  }
273  else if (pList.isParameter("Problem") && pList.isParameter("Reference")) {
274  // comparing metrics/timers
275  string prb = pList.get<string>("Problem");
276  if(this->sources.find(prb) == this->sources.end()) {
277  std::cout << "\nProblem: " + prb + ", was not saved for comparison.";
278  std::cout << "\nThis typically indicates that an error ";
279  std::cout << "occurred while running the problem.";
280  std::cout << "\nMetric comparison FAILED." << std::endl;
281  return false;
282  }
283 
284  string ref = pList.get<string>("Reference");
285  if(this->sources.find(ref) == this->sources.end()) {
286  std::cout << "\nReference: " + ref + ", was not saved for comparison.";
287  std::cout << "\nThis typically indicates that an error ";
288  std::cout << "occurred while running the problem.";
289  std::cout << "\nMetric comparison FAILED." << std::endl;
290  return false;
291  }
292 
293  bool bResult = this->CompareMetrics(pList, comm);
294  return bResult;
295  }
296  else if (pList.isParameter("A") || pList.isParameter("B"))
297  {
298  if(comm->getRank() == 0)
299  {
300  std::cout << "Problem A or Problem B is not specified -- check input.";
301  std::cout <<"\nSolution comparison FAILED." << std::endl;
302  }
303  }
304  else if (pList.isParameter("Problem") || pList.isParameter("Reference")) {
305  if(comm->getRank() == 0) {
306  std::cout << "Problem or reference is not specified -- check input.";
307  std::cout <<"\nMetric comparison FAILED." << std::endl;
308  }
309  }
310  else {
311  if (comm->getRank() == 0) {
312  std::cout << "ComparisonHelper did not understand how to read the xml. ";
313  std::cout << "Test FAILED." << std::endl;
314  }
315  }
316  return false;
317 }
318 
319 bool ComparisonHelper::CompareSolutions(const string &p1,
320  const string &p2,
321  const RCP<const Comm<int> > &comm)
322 {
323  if(comm->getRank() == 0) printf( "\nComparing: %s and %s\n",
324  p1.c_str(), p2.c_str());
325  auto A = this->sources[p1];
326  auto B = this->sources[p2];
327  if(A->problemFactory->getProblemName() != B->problemFactory->getProblemName()) {
328  std::cout << "Problem A and B are of a different kind and cannot be compared.";
329  std::cout <<"\nSolution comparison FAILED." << std::endl;
330  }
331  else {
332  if(A->problemFactory->getProblemName() == "partitioning") {
333  return this->ComparePartitionSolutions(A.getRawPtr(), B.getRawPtr(), comm);
334  }
335  else if(A->problemFactory->getProblemName() == "coloring") {
336  return this->CompareColoringSolutions(A.getRawPtr(), B.getRawPtr(), comm);
337  }
338  else if(A->problemFactory->getProblemName() == "ordering"){
339  return this->CompareOrderingSolutions(A.getRawPtr(), B.getRawPtr(), comm);
340  }
341  else {
342  std::cout << "Problem kind: " << A->problemFactory->getProblemName() <<
343  " not recognized. Check spelling.";
344  std::cout <<"\nSolution comparison FAILED." << std::endl;
345  }
346  }
347  return false;
348 }
349 
350 void ComparisonHelper::reduceWithMessage(const RCP<const Comm<int> > &comm,
351  const std::string &msg_in,
352  int &local_status,
353  std::ostringstream &msg) {
354  comm->barrier();
355  int global_buff;
356  Teuchos::Ptr<int> global(&global_buff);
357  reduceAll<int,int>(*comm.get(), Teuchos::EReductionType::REDUCE_MAX,
358  local_status , global);
359  local_status = *global;
360  if (local_status == 1) {
361  msg << msg_in;
362  }
363 }
364 
365 const zpart_t * ComparisonHelper::getPartListView(
366  RCP<ProblemFactory> problemFactory) const {
367  #define GET_PROBLEM_PARTS(adapterClass) \
368  return (rcp_dynamic_cast<PartitioningProblem<adapterClass>>( \
369  problemFactory->getProblem()))->getSolution().getPartListView();
370  Z2_TEST_UPCAST(problemFactory->getAdapterType(), GET_PROBLEM_PARTS)
371 }
372 
373 bool ComparisonHelper::ComparePartitionSolutions(const ComparisonSource * sourceA,
374  const ComparisonSource * sourceB,
375  const RCP<const Comm<int> > &comm)
376 {
377  int rank = comm->getRank();
378  std::ostringstream status;
379  int failed = 0;
380 
381  if(sourceA->adapterFactory->getMainAdapter()->getLocalNumIDs()
382  != sourceB->adapterFactory->getMainAdapter()->getLocalNumIDs()) {
383  failed = 1;
384  }
385 
386  ComparisonHelper::reduceWithMessage(comm,
387  "Number of parts in Solution A != Solution B. \
388  Partitioning solution comparison FAILED.",
389  failed, status);
390 
391  if (!failed) {
392  for(size_t i = 0;
393  i < sourceA->adapterFactory->getMainAdapter()->getLocalNumIDs(); i++) {
394  if(!failed && getPartListView(sourceA->problemFactory)[i] !=
395  getPartListView(sourceB->problemFactory)[i]) {
396  failed = 1;
397  ComparisonHelper::reduceWithMessage(comm,
398  "Solution sets A and B have different values for getPartListView(). "
399  "Solution comparison FAILED.", failed, status);
400  }
401  }
402  }
403 
404  if(!failed) {
405  status << "Solution sets A and B are the same. ";
406  status << "Solution set comparison PASSED.";
407  }
408 
409  if(rank == 0) {
410  std::cout << status.str() << std::endl;
411  }
412  return (failed == 0);
413 }
414 
415 
416 bool ComparisonHelper::CompareColoringSolutions(const ComparisonSource * sourceA,
417  const ComparisonSource * sourceB,
418  const RCP<const Comm<int> > &comm)
419 {
420  int rank = comm->getRank();
421  std::ostringstream status;
422  int failed = 0;
423 
424  // TO DO - implement coloring comparison
425  /*
426  if(sourceA->problemFactory->getNumColors()
427  != sourceB->problemFactory->getNumColors()) {
428  failed = 1;
429  }
430 
431  ComparisonHelper::reduceWithMessage(comm,
432  "Number of colors for Solution A != Solution B. \
433  Coloring solution comparison FAILED.",
434  failed, status);
435 
436  if (!failed) {
437  if(sourceA->problemFactory->getColorsSize()
438  != sourceB->problemFactory->getColorsSize()) {
439  failed = 1;
440  }
441  ComparisonHelper::reduceWithMessage(comm,
442  "Size of colors array for Solution A != Solution B. \
443  Coloring solution comparison FAILED.",
444  failed,
445  status);
446  }
447 
448  if (!failed) {
449  for(size_t i = 0; i < sourceA->problemFactory->getColorsSize(); i++) {
450  if (sourceA->problemFactory->getColors()[i] !=
451  sourceB->problemFactory->getColors()[i]) {
452  failed = 1; // fail
453  }
454  }
455  ComparisonHelper::reduceWithMessage(comm,
456  "Coloring solution comparison FAILED.",
457  failed,
458  status);
459  }
460  */
461 
462  if (!failed) {
463  status << "Solution sets A and B are the same. ";
464  status << "Solution set comparison PASSED.";
465  }
466 
467  if (rank == 0) {
468  std::cout << status.str() << std::endl;
469  }
470  return (failed == 0);
471 }
472 
473 bool ComparisonHelper::CompareOrderingSolutions(const ComparisonSource * sourceA,
474  const ComparisonSource * sourceB,
475  const RCP<const Comm<int> > &comm)
476 {
477  int rank = comm->getRank();
478  std::ostringstream status;
479  int failed = 0;
480 
481  // TO DO - implement ordering comparison
482 
483  if(!failed) {
484  status << "Solution sets A and B are the same. ";
485  status << "Solution set comparison PASSED.";
486  }
487 
488  if(rank == 0) {
489  std::cout << status.str() << std::endl;
490  }
491  return (failed == 0);
492 }
493 
494 // Utility function for safe type conversion of adapter
495 void ComparisonHelper::loadMetricInfo(RCP<EvaluateFactory> evaluateFactory,
496  std::vector<MetricAnalyzerInfo> & metricInfo,
497  const ParameterList &metricsPlist) {
498 
499  #define LOAD_METRIC_INFO(adapterClass, metricAnalyzerClass) \
500  RCP<EvaluateBaseClass<adapterClass>> pCast = \
501  rcp_dynamic_cast<EvaluateBaseClass<adapterClass>>(evaluateFactory->getEvaluateClass()); \
502  if(pCast == Teuchos::null) throw std::logic_error( \
503  "Bad evaluate class cast in loadMetricInfo!" ); \
504  metricAnalyzerClass analyzer(pCast); \
505  analyzer.LoadMetricInfo(metricInfo, metricsPlist.sublist("Metrics"));
506 
507  #define LOAD_METRIC_INFO_PARTITIONING(adapterClass) \
508  LOAD_METRIC_INFO(adapterClass, MetricAnalyzerEvaluatePartition<adapterClass>)
509 
510  #define LOAD_METRIC_INFO_ORDERING(adapterClass) \
511  LOAD_METRIC_INFO(adapterClass, MetricAnalyzerEvaluateOrdering<adapterClass>)
512 
513  if(evaluateFactory->getProblemName() == "partitioning") {
514  Z2_TEST_UPCAST(evaluateFactory->getAdapterType(), LOAD_METRIC_INFO_PARTITIONING)
515  }
516  else if(evaluateFactory->getProblemName() == "ordering") {
517  Z2_TEST_UPCAST(evaluateFactory->getAdapterType(), LOAD_METRIC_INFO_ORDERING)
518  }
519  else {
520  throw std::logic_error(
521  "loadMetricInfo not implemented for this problem type!" );
522  }
523 }
524 
525 // compare metrics
526 bool ComparisonHelper::CompareMetrics(const ParameterList &metricsPlist, const RCP<const Comm<int> > &comm)
527 {
528  int rank = comm->getRank();
529 
530  //get sources for problema nd reference
531  const string prb_name = metricsPlist.get<string>("Problem");
532  const string ref_name = metricsPlist.get<string>("Reference");
533  if(rank == 0) {
534  std::cout << "\nMetric/Timer comparison of: " << prb_name << " and ";
535  std::cout << ref_name <<" (reference source)\n";
536  }
537 
538  // get sources
539  RCP<const ComparisonSource> sourcePrb = this->sources[prb_name];
540  RCP<const ComparisonSource> sourceRef = this->sources[ref_name];
541 
542  // get timing data
543  const std::map< string, double>& prb_timers = sourcePrb->getTimingsMap();
544  const std::map< string, double>& ref_timers = sourceRef->getTimingsMap();
545 
546  // get all of the metrics to be tested
547  std::queue<ParameterList> metrics = ComparisonHelper::getMetricsToCompare(metricsPlist);
548 
549  // run comparison
550  int all_tests_pass = 1;
551  string metric_name;
552 
553  while(!metrics.empty()) {
554  // print their names...
555  std::ostringstream msg;
556  metric_name = metrics.front().name();
557 
558  if (metric_name == "Metrics") { // special key word means compare the metrics list
559  std::vector<MetricAnalyzerInfo> metricInfoSetPrb;
560  std::vector<MetricAnalyzerInfo> metricInfoSetRef;
561 
562  loadMetricInfo(sourcePrb.get()->evaluateFactory, metricInfoSetPrb, metricsPlist);
563  loadMetricInfo(sourceRef.get()->evaluateFactory, metricInfoSetRef, metricsPlist);
564 
565  // there is some redundancy here because the metric info holds both the questions and the results
566  // this happened because I wanted to reuse the MetricAnalyzer code for loading metric checks or comparisons
567  // we can iterate over either to get the questions
568  for (size_t n = 0; n < metricInfoSetPrb.size(); ++n) {
569  if(!ComparisonHelper::metricComparisonTest(comm, metricInfoSetPrb[n], metricInfoSetRef[n], metrics.front(), msg)) {
570  all_tests_pass = 0;
571  }
572  if(rank == 0) {
573  std::cout << msg.str() << std::endl;
574  }
575  }
576  }
577  else if(prb_timers.find(metric_name) != prb_timers.end() && ref_timers.find(metric_name) != ref_timers.end()) {
578  if(rank == 0) std::cout << "\ncomparing timer: " << metric_name << std::endl;
579  if(!ComparisonHelper::timerComparisonTest(comm,
580  prb_timers.at(metric_name),
581  ref_timers.at(metric_name),
582  metrics.front(), msg)) {
583  all_tests_pass = 0;
584  if (rank == 0) {
585  std::cout << "timer comparison test caused a FAILED event." << std::endl;
586  }
587  }
588 
589  if(rank == 0) {
590  std::cout << msg.str() << std::endl;
591  }
592  }
593 
594  metrics.pop();
595  }
596 
597  if(rank == 0) {
598  if(all_tests_pass == 1) {
599  std::cout << "\nAll metric/timer comparisons PASSED." << std::endl;
600  }
601  else {
602  std::cout << "\nMetric/timer metric comparisons FAILED." << std::endl;
603  }
604  }
605 
606  return (all_tests_pass == 1);
607 }
608 
609 bool ComparisonHelper::metricComparisonTest(const RCP<const Comm<int> > &comm,
610  const MetricAnalyzerInfo & metric,
611  const MetricAnalyzerInfo & ref_metric,
612  const Teuchos::ParameterList & metricPlist,
613  std::ostringstream &msg)
614 {
615  // run a comparison of min and max against a given metric
616  // return an error message on failure
617  bool pass = true;
618  string test_name = metricPlist.name() + " test";
619  double ref_value = ref_metric.theValue;
620  double value = metric.theValue;
621 
622  if (ref_value == 0) {
623  throw std::logic_error( "The parameter list had a 0 value for the reference value so a percentage cannot be calculated." );
624  }
625  double percentRatio = value / ref_value;
626 
627  // want to reduce value to max value for all procs
628 
629  if (ref_metric.bFoundLowerBound) {
630  double min = ref_metric.lowerValue;
631  if (percentRatio < min) {
632  msg << test_name << " FAILED: " << ref_metric.parameterDescription << ": " << value << " is " << percentRatio << " percent of the reference value " << ref_value << ", which less than specified allowable minimum percent, " << min << ".\n";
633  pass = false;
634  }
635  else {
636  msg << test_name << " PASSED: " << ref_metric.parameterDescription << ": " << value << " is " << percentRatio << " percent of the reference value " << ref_value << ", which is greater than specified allowable minimum percent, " << min << ".\n";
637  }
638  }
639 
640  if (ref_metric.bFoundUpperBound) {
641  double max = ref_metric.upperValue;
642  if (percentRatio > max) {
643  msg << test_name << " FAILED: " << ref_metric.parameterDescription << ": " << value << " is " << percentRatio << " percent of the reference value " << ref_value << ", which is greater than specified allowable maximum percent, " << max << ".\n";
644  pass = false;
645  }
646  else {
647  msg << test_name << " PASSED: " << ref_metric.parameterDescription << ": " << value << " is " << percentRatio << " percent of the reference value " << ref_value << ", which is less than specified allowable maximum percent, " << max << ".\n";
648  }
649  }
650 
651  return pass;
652 }
653 // BDD, to do: print metrics even for pass
654 // reduce max metric to process 0
655 // print only on process 0 --- duh.
656 bool ComparisonHelper::timerComparisonTest(const RCP<const Comm<int> > &comm,
657  const double time,
658  const double ref_time,
659  const Teuchos::ParameterList & metricPlist,
660  std::ostringstream &msg)
661 {
662  // Reduce time from test
663  double global_time;
664  Teuchos::Ptr<double> global(&global_time);
665  comm->barrier();
666  reduceAll<int, double>(*comm.get(),Teuchos::EReductionType::REDUCE_MAX,time,global);
667 
668  // Reduce time from reference
669  double global_ref_time;
670  Teuchos::Ptr<double> globalRef(&global_ref_time);
671  comm->barrier();
672  reduceAll<int, double>(*comm.get(),Teuchos::EReductionType::REDUCE_MAX,ref_time,globalRef);
673 
674  // run a comparison of min and max against a given metric
675  // return an error message on failure
676  bool pass = true;
677  string test_name = metricPlist.name() + " test";
678 
679  if (metricPlist.isParameter("lower")) {
680  double min = metricPlist.get<double>("lower")*global_ref_time;
681 
682  if (global_time < min) {
683  msg << test_name << " FAILED: Minimum time, "
684  << time <<
685  "[s], less than specified allowable minimum time, " << min <<"[s]"<< ".\n";
686  pass = false;
687  }
688  else {
689  msg << test_name << " PASSED: Minimum time, "
690  << time <<
691  "[s], greater than specified allowable minimum time, " << min <<"[s]"<< ".\n";
692  }
693  }
694 
695  if (metricPlist.isParameter("upper" ) && pass != false) {
696  double max = metricPlist.get<double>("upper") * global_ref_time;
697  if (global_time > max) {
698  msg << test_name << " FAILED: Maximum time, "
699  << global_time <<
700  "[s], greater than specified allowable maximum time, " << max <<"[s]"<< ".\n";
701  pass = false;
702  }
703  else {
704  msg << test_name << " PASSED: Maximum time, "
705  << global_time <<
706  "[s], less than specified allowable maximum time, " << max <<"[s]"<< ".\n";
707  }
708  }
709 
710  return pass;
711 }
712 
713 std::queue<ParameterList> ComparisonHelper::getMetricsToCompare(const ParameterList &pList)
714 {
715  // extract all of the metrics to be tested
716  std::queue<ParameterList> metrics;
717  for(auto it = pList.begin(); it != pList.end(); ++it) {
718  if (pList.isSublist(it->first)) {
719  metrics.push(pList.sublist(it->first));
720  }
721  }
722  return metrics;
723 }
724 
keep typedefs that commonly appear in many places localized
const zpart_t * getPartListView(RCP< ProblemFactory > problemFactory)
void startTimer(const std::string &timerName)
RCP< ComparisonSource > AddSource(const string &name)
Returns a pointer to new test classes. Is not responsible for memory management!
RCP< ProblemFactory > problemFactory
common code used by tests
#define LOAD_METRIC_INFO_ORDERING(adapterClass)
bool Compare(const ParameterList &pList, const RCP< const Comm< int > > &comm)
int zpart_t
#define Z2_TEST_UPCAST(adptr, TEMPLATE_ACTION)
#define LOAD_METRIC_INFO_PARTITIONING(adapterClass)
size_t getNumberOfSources() const
RCP< EvaluateFactory > evaluateFactory
ComparisonHelper(Teuchos::RCP< Teuchos::StackedTimer > &stackedTimer)
A class for comparing solutions, metrics, and timing data of Zoltan2 problems.
std::map< std::string, double > getTimingsMap() const
void stopTimer(const std::string &timerName)
static const std::string pass
ComparisonSource(Teuchos::RCP< Teuchos::StackedTimer > &stackedTimer, const std::string &problemName)
A class used to save problem solutions and timers.
Generate Adapter for testing purposes.
RCP< AdapterFactory > adapterFactory
#define GET_PROBLEM_PARTS(adapterClass)