58 #include <Teuchos_DefaultComm.hpp> 59 #include <Teuchos_Time.hpp> 68 using Teuchos::ParameterList;
75 using std::ostringstream;
76 using Teuchos::reduceAll;
106 delete reinterpret_cast<xcrsGraph_t *
>(
adapter.getRawPtr())->getCoordinateInput();
108 delete reinterpret_cast<xcrsMatrix_t *
>(
adapter.getRawPtr())->getCoordinateInput();
115 timers.insert(std::pair<
const std::string &, RCP<Time> >(name,rcp(
new Time(name))));
123 std::map<const std::string, RCP<Time> >
timers;
154 void Compare(
const ParameterList &pList,
const RCP<
const Comm<int> > &comm);
166 return this->sources.size();
170 map<const string,RCP<const ComparisonSource> > sources;
178 void CompareSolutions(
const string &p1,
180 const RCP<
const Comm<int> > &comm);
189 const RCP<
const Comm<int> > &comm);
198 const RCP<
const Comm<int> > &comm);
207 const RCP<
const Comm<int> > &comm);
213 void CompareMetrics(
const ParameterList &metricsPlist,
214 const RCP<
const Comm<int> > &comm);
226 metricComparisonTest(
const RCP<
const Comm<int> > &comm,
227 const metric_t & metric,
228 const metric_t &ref_metric,
229 const Teuchos::ParameterList & metricPlist,
242 timerComparisonTest(
const RCP<
const Comm<int> > &comm,
244 const double ref_time,
245 const Teuchos::ParameterList & metricPlist,
253 static std::map<const string, const metric_t>
254 metricArrayToMap(
const ArrayRCP<const metric_t> &metrics);
261 static std::map<const string, const double>
262 timerDataToMap(
const map<
const std::string, RCP<Time> > &
timers);
270 static std::queue<ParameterList>
271 getMetricsToCompare(
const ParameterList & pList);
274 reduceWithMessage(
const RCP<
const Comm<int> > &comm,
const std::string &msg_in,
275 int &local_status, std::ostringstream &msg);
282 typedef std::pair<const string &, RCP<const ComparisonSource> > pair_t;
283 this->sources.insert(pair_t(name, RCP<ComparisonSource>(source)));
288 if(pList.isParameter(
"A") && pList.isParameter(
"B"))
292 string pA = pList.get<
string>(
"A");
293 if(this->sources.find(pA) == this->sources.end())
295 cout <<
"\nProblem: " + pA +
", was not saved for comparison.";
296 cout <<
"\nThis typically indicates that an error occured while running the problem.";
297 cout <<
"\nSolution comparison FAILED." << endl;
301 string pB = pList.get<
string>(
"B");
302 if(this->sources.find(pB) == this->sources.end())
304 cout <<
"\nProblem: " + pB +
", was not saved for comparison.";
305 cout <<
"\nThis typically indicates that an error occured while running the problem.";
306 cout <<
"\nSolution comparison FAILED." << endl;
311 this->CompareSolutions(pA, pB, comm);
312 }
else if (pList.isParameter(
"Problem") && pList.isParameter(
"Reference"))
315 string prb = pList.get<
string>(
"Problem");
316 if(this->sources.find(prb) == this->sources.end())
318 cout <<
"\nProblem: " + prb +
", was not saved for comparison.";
319 cout <<
"\nThis typically indicates that an error occured while running the problem.";
320 cout <<
"\nMetric comparison FAILED." << endl;
324 string ref = pList.get<
string>(
"Reference");
325 if(this->sources.find(ref) == this->sources.end())
327 cout <<
"\nReference: " + ref +
", was not saved for comparison.";
328 cout <<
"\nThis typically indicates that an error occured while running the problem.";
329 cout <<
"\nMetric comparison FAILED." << endl;
333 this->CompareMetrics(pList,
336 }
else if (pList.isParameter(
"A") || pList.isParameter(
"B"))
338 if(comm->getRank() == 0)
340 cout <<
"Problem A or Problem B is not specified -- check input.";
341 cout <<
"\nSolution comparison FAILED." << endl;
344 }
else if (pList.isParameter(
"Problem") || pList.isParameter(
"Reference"))
346 if(comm->getRank() == 0)
348 cout <<
"Problem or reference is not specified -- check input.";
349 cout <<
"\nMetric comparison FAILED." << endl;
356 void ComparisonHelper::CompareSolutions(
const string &p1,
358 const RCP<
const Comm<int> > &comm)
361 if(comm->getRank() == 0) printf(
"\nComparing: %s and %s\n",p1.c_str(),p2.c_str());
362 auto A = this->sources[p1];
363 auto B = this->sources[p2];
364 if(A->problem_kind != B->problem_kind)
366 cout <<
"Problem A and B are of a different kind and cannot be compared.";
367 cout <<
"\nSolution comparison FAILED." << endl;
370 if(A->problem_kind ==
"partitioning")
372 this->ComparePartitionSolutions(A.getRawPtr(), B.getRawPtr(), comm);
374 }
else if(A->problem_kind ==
"coloring")
376 this->CompareColoringSolutions(A.getRawPtr(), B.getRawPtr(), comm);
378 }
else if(A->problem_kind ==
"ordering"){
380 this->CompareOrderingSolutions(A.getRawPtr(), B.getRawPtr(), comm);
383 cout <<
"Problem kind not recognized. Check spelling.";
384 cout <<
"\nSolution comparison FAILED." << endl;
391 ComparisonHelper::reduceWithMessage(
const RCP<
const Comm<int> > &comm,
const std::string &msg_in,
392 int &local_status, std::ostringstream &msg)
396 Teuchos::Ptr<int> global(&global_buff);
397 reduceAll<int,int>(*comm.get(), Teuchos::EReductionType::REDUCE_MAX, local_status , global);
399 local_status = *global;
400 if(local_status == 1)
407 void ComparisonHelper::ComparePartitionSolutions(
const ComparisonSource * sourceA,
409 const RCP<
const Comm<int> > &comm)
411 int rank = comm->getRank();
412 ostringstream status;
415 if(!sourceA->
problem.getRawPtr()){ failed = 1;}
416 ComparisonHelper::reduceWithMessage(comm,
417 "Solution A is NULL. Solution comparison FAILED.",
421 if(!failed && !sourceB->
problem.getRawPtr()){ failed = 1;}
422 ComparisonHelper::reduceWithMessage(comm,
423 "Solution B is NULL. Solution comparison FAILED.",
435 auto solution_a = problem_a->getSolution();
436 auto solution_b = problem_b->getSolution();
438 if(sourceA->
adapter->getLocalNumIDs() != sourceB->
adapter->getLocalNumIDs()){failed = 1;}
439 ComparisonHelper::reduceWithMessage(comm,
440 "Number of parts in Solution A != Solution B. \ 441 Partitioning solution comparison FAILED.",
447 for(
size_t i = 0; i < sourceA->
adapter->getLocalNumIDs(); i++)
449 if(solution_a.getPartListView()[i] != solution_b.getPartListView()[i])
451 if(!failed){ failed = 1; }
455 ComparisonHelper::reduceWithMessage(comm,
456 "Partitioning solution comparison FAILED.",
462 ComparisonHelper::reduceWithMessage(comm,
463 "Solution sets A and B are from different problem types. \ 464 Solution comparison FAILED.",
471 ComparisonHelper::reduceWithMessage(comm,
472 "Could not cast solution A to valid problem type. \ 473 Solution comparison FAILED.",
481 status <<
"Solution sets A and B are the same. ";
482 status <<
"Solution set comparison PASSED.";
488 cout << status.str() << endl;
494 void ComparisonHelper::CompareColoringSolutions(
const ComparisonSource * sourceA,
496 const RCP<
const Comm<int> > &comm)
498 int rank = comm->getRank();
499 ostringstream status;
502 if(!sourceA->
problem.getRawPtr())
506 ComparisonHelper::reduceWithMessage(comm,
507 "Solution A is NULL. Solution comparison FAILED.",
511 if(!failed && !sourceB->
problem.getRawPtr())
515 ComparisonHelper::reduceWithMessage(comm,
516 "Solution B is NULL. Solution comparison FAILED.",
525 if(coloring_problem_t * problem_a = reinterpret_cast<coloring_problem_t *>(sourceA->
problem.getRawPtr()))
527 if(coloring_problem_t * problem_b = reinterpret_cast<coloring_problem_t *>(sourceB->
problem.getRawPtr()))
530 auto solution_b = problem_b->getSolution();
532 if(solution_a->getNumColors() != solution_b->getNumColors())
536 ComparisonHelper::reduceWithMessage(comm,
537 "Number of colors for Solution A != Solution B. \ 538 Coloring solution comparison FAILED.",
544 if(solution_a->getColorsSize() != solution_b->getColorsSize())
548 ComparisonHelper::reduceWithMessage(comm,
549 "Size of colors array for Solution A != Solution B. \ 550 Coloring solution comparison FAILED.",
558 for(
size_t i = 0; i < solution_a->getColorsSize(); i++)
560 if(solution_a->getColors()[i] != solution_b->getColors()[i])
563 if(!failed) failed = 1;
566 ComparisonHelper::reduceWithMessage(comm,
567 "Coloring solution comparison FAILED.",
573 ComparisonHelper::reduceWithMessage(comm,
574 "Solution sets A and B are from different problem types. \ 575 Solution comparison FAILED.",
582 ComparisonHelper::reduceWithMessage(comm,
583 "Could not cast solution A to valid problem type. \ 584 Solution comparison FAILED.",
592 status <<
"Solution sets A and B are the same. ";
593 status <<
"Solution set comparison PASSED.";
598 cout << status.str() << endl;
603 void ComparisonHelper::CompareOrderingSolutions(
const ComparisonSource * sourceA,
605 const RCP<
const Comm<int> > &comm)
607 int rank = comm->getRank();
608 ostringstream status;
611 if(!sourceA->
problem.getRawPtr()){ failed = 1;}
612 ComparisonHelper::reduceWithMessage(comm,
613 "Solution A is NULL. Solution comparison FAILED.",
617 if(!failed && !sourceB->
problem.getRawPtr()){ failed = 1;}
618 ComparisonHelper::reduceWithMessage(comm,
619 "Solution B is NULL. Solution comparison FAILED.",
652 status <<
"Solution sets A and B are the same. ";
653 status <<
"Solution set comparison PASSED.";
658 cout << status.str() << endl;
664 void ComparisonHelper::CompareMetrics(
const ParameterList &metricsPlist,
665 const RCP<
const Comm<int> > &comm)
668 int rank = comm->getRank();
671 const string prb_name = metricsPlist.get<
string>(
"Problem");
672 const string ref_name = metricsPlist.get<
string>(
"Reference");
675 cout <<
"\nMetric/Timer comparison of: " << prb_name <<
" and ";
676 cout << ref_name <<
" (reference source)\n";
680 RCP<const ComparisonSource> sourcePrb = this->sources[prb_name];
681 RCP<const ComparisonSource> sourceRef = this->sources[ref_name];
684 auto problem = sourcePrb.get()->problem.get();
685 auto reference = sourceRef.get()->problem.get();
688 std::map<const string, const metric_t> prb_metrics = this->metricArrayToMap(
problem->getMetrics());
689 std::map<const string, const metric_t> ref_metrics = this->metricArrayToMap(reference->getMetrics());
692 std::map< const string, const double> prb_timers = this->timerDataToMap(sourcePrb->timers);
693 std::map< const string, const double> ref_timers = this->timerDataToMap(sourceRef->timers);
696 std::queue<ParameterList> metrics = ComparisonHelper::getMetricsToCompare(metricsPlist);
699 int all_tests_pass = 1;
701 while(!metrics.empty())
705 metric_name = metrics.front().name();
707 if(prb_metrics.find(metric_name) != prb_metrics.end() &&
708 ref_metrics.find(metric_name) != ref_metrics.end())
710 if(rank == 0) cout <<
"\ncomparing metric: " << metric_name << endl;
711 if(!ComparisonHelper::metricComparisonTest(comm,
712 prb_metrics[metric_name],
713 ref_metrics[metric_name],
714 metrics.front(), msg))
718 if(rank == 0) cout << msg.str() << endl;
721 else if(prb_timers.find(metric_name) != prb_timers.end() &&
722 ref_timers.find(metric_name) != ref_timers.end())
724 if(rank == 0) cout <<
"\ncomparing timer: " << metric_name << endl;
725 if(!ComparisonHelper::timerComparisonTest(comm,
726 prb_timers.at(metric_name),
727 ref_timers.at(metric_name),
728 metrics.front(), msg))
733 if(rank == 0) cout << msg.str() << endl;
742 if(all_tests_pass == 1) cout <<
"\nAll metric/timer comparisons PASSED." << endl;
743 else cout <<
"\nMetric/timer metric comparisons FAILED." << endl;
747 std::map<const string, const ComparisonHelper::metric_t>
748 ComparisonHelper::metricArrayToMap(
const ArrayRCP<const ComparisonHelper::metric_t> &metrics)
750 typedef std::pair<const string,const metric_t> pair_t;
751 std::map<const string, const metric_t> metric_map;
752 ArrayRCP<const ComparisonHelper::metric_t>::size_type idx;
753 for(idx = 0; idx < metrics.size(); idx++)
755 metric_map.insert(pair_t(metrics[idx].getName(),metrics[idx]));
762 std::map<const string, const double>
763 ComparisonHelper::timerDataToMap(
const map<
const std::string, RCP<Time> > &
timers)
765 typedef std::pair<const string,const double> pair_t;
766 std::map<const string, const double> time_data;
769 time_data.insert(pair_t(i.first, i.second->totalElapsedTime()));
776 ComparisonHelper::metricComparisonTest(
const RCP<
const Comm<int> > &comm,
779 const Teuchos::ParameterList & metricPlist,
785 string test_name = metricPlist.name() +
" test";
791 Teuchos::Ptr<double> global(&value);
793 reduceAll<int, double>(*comm.get(),Teuchos::EReductionType::REDUCE_MAX,local_value,global);
797 Teuchos::Ptr<double> globalRef(&ref_value);
799 reduceAll<int, double>(*comm.get(),Teuchos::EReductionType::REDUCE_MAX,local_ref_value,globalRef);
803 if (metricPlist.isParameter(
"lower"))
805 double min = metricPlist.get<
double>(
"lower")*ref_value;
809 msg << test_name <<
" FAILED: Minimum imbalance per part, " 810 << value <<
", less than specified allowable minimum, " << min <<
".\n";
813 msg << test_name <<
" PASSED: Minimum imbalance per part, " 814 << value <<
", greater than specified allowable minimum, " << min <<
".\n";
818 if(metricPlist.isParameter(
"upper" ) && pass !=
false) {
820 double max = metricPlist.get<
double>(
"upper") * ref_value;
823 msg << test_name <<
" FAILED: Maximum imbalance per part, " 824 << value <<
", greater than specified allowable maximum, " << max <<
".\n";
827 msg << test_name <<
" PASSED: Maximum imbalance per part, " 828 << value <<
", less than specified allowable maximum, " << max <<
".\n";
838 bool ComparisonHelper::timerComparisonTest(
const RCP<
const Comm<int> > &comm,
840 const double ref_time,
841 const Teuchos::ParameterList & metricPlist,
846 Teuchos::Ptr<double> global(&global_time);
848 reduceAll<int, double>(*comm.get(),Teuchos::EReductionType::REDUCE_MAX,time,global);
851 double global_ref_time;
852 Teuchos::Ptr<double> globalRef(&global_ref_time);
854 reduceAll<int, double>(*comm.get(),Teuchos::EReductionType::REDUCE_MAX,ref_time,globalRef);
860 string test_name = metricPlist.name() +
" test";
861 if (metricPlist.isParameter(
"lower"))
863 double min = metricPlist.get<
double>(
"lower")*global_ref_time;
865 if(global_time < min)
867 msg << test_name <<
" FAILED: Minimum time, " 869 "[s], less than specified allowable minimum time, " << min <<
"[s]"<<
".\n";
872 msg << test_name <<
" PASSED: Minimum time, " 874 "[s], greater than specified allowable minimum time, " << min <<
"[s]"<<
".\n";
878 if(metricPlist.isParameter(
"upper" ) && pass !=
false) {
880 double max = metricPlist.get<
double>(
"upper") * global_ref_time;
881 if (global_time > max)
883 msg << test_name <<
" FAILED: Maximum time, " 885 "[s], greater than specified allowable maximum time, " << max <<
"[s]"<<
".\n";
888 msg << test_name <<
" PASSED: Maximum time, " 890 "[s], less than specified allowable maximum time, " << max <<
"[s]"<<
".\n";
898 std::queue<ParameterList>
899 ComparisonHelper::getMetricsToCompare(
const ParameterList &pList)
902 std::queue<ParameterList> metrics;
903 for(
auto it = pList.begin(); it != pList.end(); ++it)
905 if(pList.isSublist(it->first))
907 metrics.push(pList.sublist(it->first));
RCP< basic_problem_t > problem
Zoltan2::Problem< base_t > problem_t
scalar_t getMaxImbalance() const
Get the imbalance of the most imbalanced part. This is what we normally call the imbalance of a parti...
ColoringProblem sets up coloring problems for the user.
Defines the ColoringProblem class.
AdapterForTests::basic_id_t basic_id_t
AdapterForTests::xcrsGraph_adapter xcrsGraph_t
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
AdapterForTests::base_adapter_t base_t
Zoltan2::Problem< base_t > problem_t
ColoringSolution< Adapter > * getSolution()
Get the solution to the problem.
AdapterForTests::xcrsGraph_adapter xcrsGraph_t
AdapterForTests::xcrsMatrix_adapter xcrsMatrix_t
Zoltan2::PartitioningProblem< xcrsMatrix_t > xcrsMatrix_problem_t
Zoltan2::PartitioningProblem< base_t > partioning_problem_t
void Compare(const ParameterList &pList, const RCP< const Comm< int > > &comm)
Provides access for Zoltan2 to Xpetra::CrsGraph data.
common code used by tests
AdapterForTests::xpetra_mv_adapter xpetra_mv_t
void AddSource(const string &name, ComparisonSource *source)
RCP< basic_id_t > adapter
Zoltan2::PartitioningProblem< xcrsGraph_t > xcrsGraph_problem_t
Zoltan2::PartitioningProblem< base_t > partioning_problem_t
scalar_t getAvgImbalance() const
Get the average of the part imbalances.
AdapterForTests::basic_vector_adapter basic_vector_t
This class represents a collection of global Identifiers and their associated weights, if any.
Zoltan2::PartitioningProblem< basic_vector_t > basicVector_problem_t
Zoltan2::PartitioningProblem< xcrsGraph_t > xcrsGraph_problem_t
Zoltan2::PartitioningProblem< basic_id_t > basic_problem_t
size_t getNumberOfSources() const
Problem base class from which other classes (PartitioningProblem, ColoringProblem, OrderingProblem, MatchingProblem, etc.) derive.
BasicVectorAdapter represents a vector (plus optional weights) supplied by the user as pointers to st...
Zoltan2::PartitioningProblem< basic_vector_t > basicVector_problem_t
const Zoltan2::MetricValues< zscalar_t > metric_t
AdapterForTests::basic_vector_adapter basic_vector_t
An adapter for Xpetra::MultiVector.
A class for comparing solutions, metrics, and timing data of Zoltan2 problems.
std::map< const std::string, RCP< Time > > timers
Defines the OrderingProblem class.
AdapterForTests::basic_id_t basic_id_t
PartitioningProblem sets up partitioning problems for the user.
static const std::string pass
BaseAdapter defines methods required by all Adapters.
AdapterForTests::xcrsMatrix_adapter xcrsMatrix_t
A class containing the metrics for one measurable item.
Zoltan2::PartitioningProblem< xpetra_mv_t > xpetra_mv_problem_t
Zoltan2::PartitioningProblem< basic_id_t > basic_problem_t
~ComparisonSource()
Destructor.
A class used to save problem solutions and timers.
AdapterForTests::xpetra_mv_adapter xpetra_mv_t
Defines the PartitioningProblem class.
AdapterForTests::base_adapter_t base_t
void addTimer(const std::string &name)
Zoltan2::PartitioningProblem< xpetra_mv_t > xpetra_mv_problem_t
Zoltan2::PartitioningProblem< xcrsMatrix_t > xcrsMatrix_problem_t
Generate Adapter for testing purposes.