94 #ifndef ZOLTAN2_EVALUATEPARTITION_HPP 95 #define ZOLTAN2_EVALUATEPARTITION_HPP 109 template <
typename Adapter>
115 typedef typename Adapter::lno_t lno_t;
116 typedef typename Adapter::part_t part_t;
117 typedef typename Adapter::scalar_t scalar_t;
121 part_t numGlobalParts_;
122 part_t targetGlobalParts_;
126 typedef ArrayRCP<RCP<base_metric_type> > base_metric_array_type;
128 base_metric_array_type metricsBase_;
130 void sharedConstructor(
const Adapter *ia,
132 const RCP<
const Comm<int> > &problemComm,
153 numGlobalParts_(0), targetGlobalParts_(0), numNonEmpty_(0), metricsBase_()
155 RCP<const Comm<int> > problemComm = DefaultComm<int>::getComm();
156 sharedConstructor(ia, p, problemComm, soln, graphModel);
172 const RCP<
const Comm<int> > &problemComm,
176 numGlobalParts_(0), targetGlobalParts_(0), numNonEmpty_(0), metricsBase_()
178 sharedConstructor(ia, p, problemComm, soln, graphModel);
181 #ifdef HAVE_ZOLTAN2_MPI 198 numGlobalParts_(0), targetGlobalParts_(0), numNonEmpty_(0), metricsBase_()
200 RCP<Teuchos::OpaqueWrapper<MPI_Comm> > wrapper =
201 Teuchos::opaqueWrapper(comm);
202 RCP<const Comm<int> > problemComm =
203 rcp<const Comm<int> >(
new Teuchos::MpiComm<int>(wrapper));
204 sharedConstructor(ia, p, problemComm, soln, graphModel);
217 std::set<std::string> temporarySet;
218 std::vector<std::string> returnVector;
227 for(
int n = 0; n < metricsBase_.size(); ++n ) {
228 std::string checkName = metricsBase_[n]->getMetricType();
229 if (temporarySet.find(checkName) == temporarySet.end()) {
230 temporarySet.insert(checkName);
231 returnVector.push_back(checkName);
244 int sizeOfArrayView = 0;
245 for(
typename base_metric_array_type::size_type n = 0;
246 n < metricsBase_.size(); ++n) {
247 if( metricsBase_[n]->getMetricType() == metricType ) {
248 if (beginIndex == -1) {
254 if (sizeOfArrayView == 0) {
255 return ArrayView<RCP<base_metric_type> >();
257 return metricsBase_.view(beginIndex, sizeOfArrayView);
263 ArrayView<RCP<base_metric_type> > metrics =
265 if( metrics.size() <= 0 ) {
266 throw std::logic_error(
"getObjectCountImbalance() was called " 267 "but no metrics data was generated for " +
270 return metrics[0]->getMetricValue(
"maximum imbalance");
280 ArrayView<RCP<base_metric_type> > metrics =
283 if( metrics.size() <= 0 ) {
284 throw std::logic_error(
"getNormedImbalance() was called " 285 "but no metrics data was generated for " +
288 if( metrics.size() <= 1 ) {
289 throw std::logic_error(
"getNormedImbalance() was called " 290 "but the normed data does not exist." );
292 return metrics[1]->getMetricValue(
"maximum imbalance");
313 ArrayView<RCP<base_metric_type> > metrics =
316 int weight0IndexStartsAtThisArrayIndex = ( metrics.size() > 2 ) ? 2 : 1;
317 int numberOfWeights = metrics.size() - weight0IndexStartsAtThisArrayIndex;
318 int indexInArray = weight0IndexStartsAtThisArrayIndex + weightIndex;
319 if( metrics.size() <= indexInArray ) {
320 throw std::logic_error(
"getWeightImbalance was called with weight index "+
321 std::to_string(weightIndex) +
322 " but the maximum weight available for " +
324 " is weight " + std::to_string(numberOfWeights-1) +
327 return metrics[indexInArray]->getMetricValue(
"maximum imbalance");
333 ArrayView<RCP<base_metric_type> > graphMetrics =
335 if( graphMetrics.size() < 1 ) {
336 throw std::logic_error(
"getMaxEdgeCut() was called " 337 "but no metrics data was generated for " +
340 return graphMetrics[0]->getMetricValue(
"global maximum");
346 ArrayView<RCP<base_metric_type> > graphMetrics =
348 int indexInArray = weightIndex + 1;
349 if( graphMetrics.size() <= 1 ) {
350 throw std::logic_error(
"getMaxWeightEdgeCut was called with " 351 "weight index " + std::to_string(weightIndex) +
352 " but no weights were available for " +
355 else if( graphMetrics.size() <= indexInArray ) {
359 throw std::logic_error(
"getMaxWeightEdgeCut was called with " 360 "weight index " + std::to_string(weightIndex) +
361 " but the maximum weight available for " +
364 std::to_string(graphMetrics.size() - 2) +
"." );
366 return graphMetrics[indexInArray]->getMetricValue(
"global maximum");
372 ArrayView<RCP<base_metric_type> > graphMetrics =
374 if( graphMetrics.size() < 1 ) {
375 throw std::logic_error(
"getTotalEdgeCut() was called but no metrics " 376 "data was generated for " +
379 return graphMetrics[0]->getMetricValue(
"global sum");
385 ArrayView<RCP<base_metric_type> > graphMetrics =
387 int indexInArray = weightIndex + 1;
388 if( graphMetrics.size() <= 1 ) {
392 throw std::logic_error(
"getTotalWeightEdgeCut was called with " 393 "weight index " + std::to_string(weightIndex) +
394 " but no weights were available for " +
397 else if( graphMetrics.size() <= indexInArray ) {
398 throw std::logic_error(
"getTotalWeightEdgeCut was called with " 399 "weight index " + std::to_string(weightIndex) +
400 " but the maximum weight available for " +
403 std::to_string(graphMetrics.size() - 2) +
"." );
405 return graphMetrics[indexInArray]->getMetricValue(
"global sum");
410 void printMetrics(std::ostream &os,
bool bIncludeUnusedTypes =
true)
const {
411 std::vector<std::string> types =
412 (bIncludeUnusedTypes ?
415 for(
auto metricType : types ) {
426 if (metrics.size() != 0) {
431 Zoltan2::printGraphMetrics<scalar_t, part_t>(os, targetGlobalParts_,
432 numGlobalParts_, metrics);
435 Zoltan2::printImbalanceMetrics<scalar_t, part_t>(os, targetGlobalParts_,
437 numNonEmpty_, metrics);
444 template <
typename Adapter>
445 void EvaluatePartition<Adapter>::sharedConstructor(
448 const RCP<
const Comm<int> > &comm,
449 const PartitioningSolution<Adapter> *soln,
450 const RCP<
const GraphModel<typename Adapter::base_adapter_t> > &graphModel
453 RCP<const Comm<int> > problemComm;
454 if (comm == Teuchos::null) {
455 problemComm = DefaultComm<int>::getComm();
460 RCP<Environment> env;
463 env = rcp(
new Environment(*p, problemComm));
467 env->debug(
DETAILED_STATUS, std::string(
"Entering EvaluatePartition"));
471 size_t numLocalObjects = ia->getLocalNumIDs();
472 ArrayRCP<const part_t> parts;
476 parts = arcp(soln->getPartListView(), 0, numLocalObjects,
false);
477 env->localInputAssertion(__FILE__, __LINE__,
"parts not set",
482 const part_t *tmp = NULL;
483 ia->getPartsView(tmp);
485 parts = arcp(tmp, 0, numLocalObjects,
false);
488 part_t *procs =
new part_t[numLocalObjects];
489 for (
size_t i=0;i<numLocalObjects;i++) procs[i]=problemComm->getRank();
490 parts = arcp(procs, 0, numLocalObjects,
true);
493 ArrayView<const part_t> partArray = parts(0, numLocalObjects);
500 const Teuchos::ParameterEntry *pe = p->getEntryPtr(
"partitioning_objective");
502 std::string strChoice = pe->getValue<std::string>(&strChoice);
503 if (strChoice == std::string(
"multicriteria_minimize_total_weight"))
505 else if (strChoice == std::string(
"multicriteria_minimize_maximum_weight"))
509 const RCP<const base_adapter_t> bia =
510 rcp(dynamic_cast<const base_adapter_t *>(ia),
false);
513 imbalanceMetrics<Adapter>(env, problemComm, mcnorm, ia, soln, partArray,
515 numGlobalParts_, numNonEmpty_, metricsBase_);
520 targetGlobalParts_ = soln->getTargetGlobalNumberOfParts();
522 targetGlobalParts_ = problemComm->getSize();
531 env->timerStart(
MACRO_TIMERS,
"Computing graph metrics");
536 std::bitset<NUM_MODEL_FLAGS> modelFlags;
540 RCP<const GraphModel<base_adapter_t> > graph;
541 if (graphModel == Teuchos::null)
542 graph = rcp(
new GraphModel<base_adapter_t>(bia, env, problemComm,
548 ArrayRCP<scalar_t> globalSums;
550 globalWeightedCutsByPart<Adapter>(env,
551 problemComm, graph, partArray,
552 numGlobalParts_, metricsBase_,
557 env->timerStop(
MACRO_TIMERS,
"Computing graph metrics");
560 std::string(
"Exiting EvaluatePartition"));
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
Time an algorithm (or other entity) as a whole.
fast typical checks for valid arguments
void printMetrics(std::ostream &os, bool bIncludeUnusedTypes=true) const
Print all the metrics based on the metric object type.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
#define IMBALANCE_METRICS_TYPE_NAME
scalar_t getNormedImbalance() const
Return the object normed weight imbalance. Normed imbalance is only valid if there is at least 2 elem...
Defines the PartitioningSolution class.
scalar_t getObjectCountImbalance() const
Return the object count imbalance.
scalar_t getTotalEdgeCut() const
getTotalEdgeCut
sub-steps, each method's entry and exit
scalar_t getMaxWeightEdgeCut(int weightIndex) const
getMaxWeightEdgeCuts weighted for the specified index
scalar_t getTotalWeightEdgeCut(int weightIndex) const
getTotalWeightEdgeCut weighted for the specified index
A PartitioningSolution is a solution to a partitioning problem.
BaseAdapterType
An enum to identify general types of adapters.
EvaluatePartition(const Adapter *ia, ParameterList *p, const RCP< const Comm< int > > &problemComm, const PartitioningSolution< Adapter > *soln, const RCP< const GraphModel< typename Adapter::base_adapter_t > > &graphModel=Teuchos::null)
Constructor where Teuchos communicator is specified.
The StridedData class manages lists of weights or coordinates.
std::vector< std::string > getMetricTypes() const
GraphModel defines the interface required for graph models.
multiCriteriaNorm
Enumerator used in code for multicriteria norm choice.
EvaluatePartition(const Adapter *ia, ParameterList *p, const PartitioningSolution< Adapter > *soln, const RCP< const GraphModel< typename Adapter::base_adapter_t > > &graphModel=Teuchos::null)
Constructor where communicator is Teuchos default.
ArrayView< RCP< base_metric_type > > getAllMetricsOfType(std::string metricType) const
Return the metric list for types matching the given metric type.
A class that computes and returns quality metrics.
void printMetrics(std::ostream &os, std::string metricType) const
Print all metrics of type metricType based on the metric object type.
scalar_t getWeightImbalance(int weightIndex) const
Return the imbalance for the requested weight.
scalar_t getMaxEdgeCut() const
Return the max cut for the requested weight.
#define GRAPH_METRICS_TYPE_NAME
base_metric_array_type getAllMetrics() const
Return the full metric list which will be mixed types.