50 #ifndef _ZOLTAN2_PARTITIONINGPROBLEM_HPP_ 51 #define _ZOLTAN2_PARTITIONINGPROBLEM_HPP_ 71 #ifdef HAVE_ZOLTAN2_OVIS 100 template<
typename Adapter>
106 typedef typename Adapter::gno_t
gno_t;
107 typedef typename Adapter::lno_t
lno_t;
112 #ifdef HAVE_ZOLTAN2_MPI 113 typedef Teuchos::OpaqueWrapper<MPI_Comm> mpiWrapper_t;
117 Problem<Adapter>(A,p,comm), solution_(),
118 problemComm_(), problemCommConst_(),
120 graphFlags_(), idFlags_(), coordFlags_(), algName_(),
121 numberOfWeights_(), partIds_(), partSizes_(),
122 numberOfCriteria_(), levelNumberParts_(), hierarchical_(false),
123 metricsRequested_(false), graphMetricsRequested_(false), metrics_(),
133 Problem<Adapter>(A,p), solution_(),
134 problemComm_(), problemCommConst_(),
136 graphFlags_(), idFlags_(), coordFlags_(), algName_(),
138 partIds_(), partSizes_(), numberOfCriteria_(),
139 levelNumberParts_(), hierarchical_(false),
140 metricsRequested_(false), graphMetricsRequested_(false), metrics_(),
149 RCP<
const Teuchos::Comm<int> > &comm):
150 Problem<Adapter>(A,p,comm), solution_(),
151 problemComm_(), problemCommConst_(),
153 graphFlags_(), idFlags_(), coordFlags_(), algName_(),
155 partIds_(), partSizes_(), numberOfCriteria_(),
156 levelNumberParts_(), hierarchical_(false),
157 metricsRequested_(false), graphMetricsRequested_(false), metrics_(),
185 void solve(
bool updateInputData=
true );
192 return *(solution_.getRawPtr());
205 if (!metrics_.is_null())
206 metrics_->getWeightImbalance(imb, idx);
216 if (metrics_.is_null()){
217 ArrayRCP<const MetricValues<scalar_t> > emptyMetrics;
221 return metrics_->getMetrics();
229 if (graphMetrics_.is_null()){
230 ArrayRCP<const GraphMetricValues<scalar_t> > emptyMetrics;
234 return graphMetrics_->getGraphMetrics();
243 if (metrics_.is_null())
244 os <<
"No metrics available." << std::endl;
246 metrics_->printMetrics(os);
328 scalar_t *partSizes,
bool makeCopy=
true) ;
349 void initializeProblem();
351 void createPartitioningProblem(
bool newData);
353 RCP<PartitioningSolution<Adapter> > solution_;
355 RCP<MachineRepresentation <typename Adapter::base_adapter_t::scalar_t> > machine_;
357 RCP<Comm<int> > problemComm_;
358 RCP<const Comm<int> > problemCommConst_;
368 std::string algName_;
370 int numberOfWeights_;
381 ArrayRCP<ArrayRCP<part_t> > partIds_;
382 ArrayRCP<ArrayRCP<scalar_t> > partSizes_;
383 int numberOfCriteria_;
387 ArrayRCP<int> levelNumberParts_;
392 bool metricsRequested_;
393 bool graphMetricsRequested_;
394 RCP<const PartitioningSolutionQuality<Adapter> > metrics_;
395 RCP<const GraphPartitioningSolutionQuality<Adapter> > graphMetrics_;
407 template <
typename Adapter>
414 if (getenv(
"DEBUGME")){
416 std::cout << getpid() << std::endl;
419 std::cout << _getpid() << std::endl;
424 #ifdef HAVE_ZOLTAN2_OVIS 425 ovis_enabled(this->
comm_->getRank());
430 problemComm_ = this->
comm_->duplicate();
431 problemCommConst_ = rcp_const_cast<
const Comm<int> > (problemComm_);
438 numberOfWeights_ = this->
inputAdapter_->getNumWeightsPerID();
440 numberOfCriteria_ = (numberOfWeights_ > 1) ? numberOfWeights_ : 1;
447 ArrayRCP<part_t> *noIds =
new ArrayRCP<part_t> [numberOfCriteria_];
448 ArrayRCP<scalar_t> *noSizes =
new ArrayRCP<scalar_t> [numberOfCriteria_];
450 partIds_ = arcp(noIds, 0, numberOfCriteria_,
true);
451 partSizes_ = arcp(noSizes, 0, numberOfCriteria_,
true);
454 std::ostringstream msg;
455 msg << problemComm_->getSize() <<
" procs," 456 << numberOfWeights_ <<
" user-defined weights\n";
460 this->
env_->memory(
"After initializeProblem");
463 template <
typename Adapter>
465 int criteria,
int len,
part_t *partIds,
scalar_t *partSizes,
bool makeCopy)
467 this->
env_->localInputAssertion(__FILE__, __LINE__,
"invalid length",
470 this->
env_->localInputAssertion(__FILE__, __LINE__,
"invalid criteria",
474 partIds_[criteria] = ArrayRCP<part_t>();
475 partSizes_[criteria] = ArrayRCP<scalar_t>();
479 this->
env_->localInputAssertion(__FILE__, __LINE__,
"invalid arrays",
486 part_t *z2_partIds = NULL;
488 bool own_memory =
false;
491 z2_partIds =
new part_t [len];
493 this->
env_->localMemoryAssertion(__FILE__, __LINE__, len, z2_partSizes);
494 memcpy(z2_partIds, partIds, len *
sizeof(
part_t));
495 memcpy(z2_partSizes, partSizes, len *
sizeof(
scalar_t));
499 z2_partIds = partIds;
500 z2_partSizes = partSizes;
503 partIds_[criteria] = arcp(z2_partIds, 0, len, own_memory);
504 partSizes_[criteria] = arcp(z2_partSizes, 0, len, own_memory);
507 template <
typename Adapter>
516 createPartitioningProblem(updateInputData);
528 if (algName_ == std::string(
"multijagged")) {
533 else if (algName_ == std::string(
"zoltan")) {
538 else if (algName_ == std::string(
"parma")) {
543 else if (algName_ == std::string(
"scotch")) {
548 else if (algName_ == std::string(
"parmetis")) {
553 else if (algName_ == std::string(
"block")) {
557 else if (algName_ == std::string(
"forTestingOnly")) {
567 throw std::logic_error(
"partitioning algorithm not supported");
578 this->
envConst_, problemCommConst_, numberOfWeights_,
579 partIds_.view(0, numberOfCriteria_),
580 partSizes_.view(0, numberOfCriteria_), this->
algorithm_);
584 solution_ = rcp(soln);
587 this->
env_->memory(
"After creating Solution");
597 const Teuchos::ParameterEntry *pe = this->
envConst_->getParameters().getEntryPtr(
"mapping_type");
598 int mapping_type = -1;
600 mapping_type = pe->getValue(&mapping_type);
604 if (mapping_type == 0){
610 problemComm_.getRawPtr(),
611 machine_.getRawPtr(),
613 solution_.getRawPtr(),
621 else if (mapping_type == 1){
625 if (metricsRequested_){
629 psq_t *quality = NULL;
630 RCP<const ps_t> solutionConst = rcp_const_cast<
const ps_t>(solution_);
633 quality =
new psq_t(this->
envConst_, problemCommConst_,
636 Z2_FORWARD_EXCEPTIONS
638 metrics_ = rcp(quality);
641 if (graphMetricsRequested_ && (algName_ == std::string(
"scotch") ||
642 algName_ == std::string(
"parmetis"))){
646 gpsq_t *quality = NULL;
647 RCP<const ps_t> solutionConst = rcp_const_cast<
const ps_t>(solution_);
650 quality =
new gpsq_t(this->
envConst_, problemCommConst_,
654 Z2_FORWARD_EXCEPTIONS
656 graphMetrics_ = rcp(quality);
662 template <
typename Adapter>
666 "PartitioningProblem::createPartitioningProblem");
668 using Teuchos::ParameterList;
679 prevModelAvail[i] = modelAvail_[i];
684 modelFlag_t previousIdentifierModelFlags = idFlags_;
685 modelFlag_t previousCoordinateModelFlags = coordFlags_;
690 modelAvail_[i] =
false;
720 std::string defString(
"default");
725 const Teuchos::ParameterEntry *pe = pl.getEntryPtr(
"compute_metrics");
727 yesNo = pe->getValue<
int>(&yesNo);
728 metricsRequested_ =
true;
733 std::string model(defString);
734 pe = pl.getEntryPtr(
"model");
736 model = pe->getValue<std::string>(&model);
740 std::string algorithm(defString);
741 pe = pl.getEntryPtr(
"algorithm");
743 algorithm = pe->getValue<std::string>(&algorithm);
747 bool needConsecutiveGlobalIds =
false;
748 bool removeSelfEdges=
false;
754 if (algorithm != defString)
758 if (algorithm == std::string(
"block") ||
759 algorithm == std::string(
"random") ||
760 algorithm == std::string(
"cyclic") ){
765 algName_ = algorithm;
767 else if (algorithm == std::string(
"zoltan") ||
768 algorithm == std::string(
"parma") ||
769 algorithm == std::string(
"forTestingOnly"))
771 algName_ = algorithm;
773 else if (algorithm == std::string(
"rcb") ||
774 algorithm == std::string(
"rib") ||
775 algorithm == std::string(
"hsfc"))
778 Teuchos::ParameterList &zparams = pl.sublist(
"zoltan_parameters",
false);
779 zparams.set(
"LB_METHOD", algorithm);
780 if (numberOfWeights_ > 0) {
782 sprintf(strval,
"%d", numberOfWeights_);
783 zparams.set(
"OBJ_WEIGHT_DIM", strval);
785 algName_ = std::string(
"zoltan");
787 else if (algorithm == std::string(
"multijagged"))
792 algName_ = algorithm;
794 else if (algorithm == std::string(
"metis") ||
795 algorithm == std::string(
"parmetis") ||
796 algorithm == std::string(
"scotch") ||
797 algorithm == std::string(
"ptscotch"))
803 algName_ = algorithm;
804 removeSelfEdges =
true;
805 needConsecutiveGlobalIds =
true;
807 else if (algorithm == std::string(
"patoh") ||
808 algorithm == std::string(
"phg"))
818 algName_ = algorithm;
820 #ifdef INCLUDE_ZOLTAN2_EXPERIMENTAL_WOLF 821 else if (algorithm == std::string(
"nd"))
825 algName_ = algorithm;
831 throw std::logic_error(
"parameter list algorithm is invalid");
834 else if (model != defString)
837 if (model == std::string(
"hypergraph"))
842 if (problemComm_->getSize() > 1)
843 algName_ = std::string(
"phg");
845 algName_ = std::string(
"patoh");
847 else if (model == std::string(
"graph"))
852 #ifdef HAVE_ZOLTAN2_SCOTCH 853 if (problemComm_->getSize() > 1)
854 algName_ = std::string(
"ptscotch");
856 algName_ = std::string(
"scotch");
857 removeSelfEdges =
true;
858 needConsecutiveGlobalIds =
true;
860 #ifdef HAVE_ZOLTAN2_PARMETIS 861 if (problemComm_->getSize() > 1)
862 algName_ = std::string(
"parmetis");
864 algName_ = std::string(
"metis");
865 removeSelfEdges =
true;
866 needConsecutiveGlobalIds =
true;
868 if (problemComm_->getSize() > 1)
869 algName_ = std::string(
"phg");
871 algName_ = std::string(
"patoh");
875 else if (model == std::string(
"geometry"))
880 algName_ = std::string(
"multijagged");
882 else if (model == std::string(
"ids"))
887 algName_ = std::string(
"block");
907 if (problemComm_->getSize() > 1)
908 algName_ = std::string(
"phg");
910 algName_ = std::string(
"patoh");
918 if (problemComm_->getSize() > 1)
919 algName_ = std::string(
"phg");
921 algName_ = std::string(
"patoh");
928 algName_ = std::string(
"multijagged");
935 algName_ = std::string(
"block");
939 throw std::logic_error(
"input type is invalid");
945 Array<int> valueList;
946 pe = pl.getEntryPtr(
"topology");
949 valueList = pe->getValue<Array<int> >(&valueList);
951 if (!Zoltan2::noValuesAreInRangeList<int>(valueList)){
952 int *n =
new int [valueList.size() + 1];
953 levelNumberParts_ = arcp(n, 0, valueList.size() + 1,
true);
954 int procsPerNode = 1;
955 for (
int i=0; i < valueList.size(); i++){
956 levelNumberParts_[i+1] = valueList[i];
957 procsPerNode *= valueList[i];
960 levelNumberParts_[0] = env.
numProcs_ / procsPerNode;
963 levelNumberParts_[0]++;
967 levelNumberParts_.clear();
970 hierarchical_ = levelNumberParts_.size() > 0;
974 std::string objectOfInterest(defString);
975 pe = pl.getEntryPtr(
"objects_to_partition");
977 objectOfInterest = pe->getValue<std::string>(&objectOfInterest);
989 std::string symParameter(defString);
990 pe = pl.getEntryPtr(
"symmetrize_graph");
992 symParameter = pe->getValue<std::string>(&symParameter);
993 if (symParameter == std::string(
"transpose"))
995 else if (symParameter == std::string(
"bipartite"))
1000 pe = pl.getEntryPtr(
"subset_graph");
1002 sgParameter = pe->getValue<
int>(&sgParameter);
1004 if (sgParameter == 1)
1009 if (removeSelfEdges)
1012 if (needConsecutiveGlobalIds)
1018 if (objectOfInterest == defString ||
1019 objectOfInterest == std::string(
"matrix_rows") )
1021 else if (objectOfInterest == std::string(
"matrix_columns"))
1023 else if (objectOfInterest == std::string(
"matrix_nonzeros"))
1028 if (objectOfInterest == defString ||
1029 objectOfInterest == std::string(
"mesh_nodes") )
1031 else if (objectOfInterest == std::string(
"mesh_elements"))
1058 (graphFlags_ != previousGraphModelFlags) ||
1059 (coordFlags_ != previousCoordinateModelFlags) ||
1060 (idFlags_ != previousIdentifierModelFlags))
1072 if(modelAvail_[GraphModelType]==
true)
1083 if(modelAvail_[HypergraphModelType]==
true)
1085 std::cout <<
"Hypergraph model not implemented yet..." << std::endl;
1088 if(modelAvail_[CoordinateModelType]==
true)
1099 if(modelAvail_[IdentifierModelType]==
true)
1110 this->
env_->memory(
"After creating Model");
use columns as graph vertices
RCP< GraphModel< base_adapter_t > > graphModel_
~PartitioningProblem()
Destructor.
ArrayRCP< const MetricValues< scalar_t > > getMetrics() const
Get the array of metrics Metrics were only computed if user requested metrics with a parameter...
const scalar_t getWeightImbalance(int idx=0) const
Returns the imbalance of the solution.
Time an algorithm (or other entity) as a whole.
RCP< const base_adapter_t > baseInputAdapter_
Adapter::scalar_t scalar_t
void setPartSizes(int len, part_t *partIds, scalar_t *partSizes, bool makeCopy=true)
Set or reset relative sizes for the parts that Zoltan2 will create.
use mesh nodes as vertices
fast typical checks for valid arguments
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
algorithm requires consecutive ids
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
PartitioningProblem(Adapter *A, ParameterList *p, RCP< const Teuchos::Comm< int > > &comm)
Constructor where Teuchos communicator is specified.
PartitioningProblem(Adapter *A, ParameterList *p)
Constructor where communicator is the Teuchos default.
model must symmetrize input
model must symmetrize input
RCP< Algorithm< Adapter > > algorithm_
RCP< const Comm< int > > comm_
void resetParameters(ParameterList *params)
Reset the list of parameters.
Defines the PartitioningSolution class.
sub-steps, each method's entry and exit
const RCP< const Environment > & getEnvironment() const
Get the current Environment. Useful for testing.
void resetParameters(ParameterList *params)
Reset the list of parameters.
RCP< IdentifierModel< base_adapter_t > > identifierModel_
void setPartSizesForCriteria(int criteria, int len, part_t *partIds, scalar_t *partSizes, bool makeCopy=true)
Set or reset the relative sizes (per weight) for the parts that Zoltan2 will create.
int numProcs_
number of processes (relative to comm_)
use matrix rows as graph vertices
This class provides geometric coordinates with optional weights to the Zoltan2 algorithm.
Teuchos::ParameterList & getParametersNonConst()
Returns a reference to a non-const copy of the parameters.
algorithm requires no self edges
A class that computes and returns quality metrics.
Defines the IdentifierModel interface.
A PartitioningSolution is a solution to a partitioning problem.
use nonzeros as graph vertices
Defines the PartitioningSolutionQuality class.
BaseAdapterType
An enum to identify general types of adapters.
void printMetrics(std::ostream &os) const
Print the array of metrics.
identifier data, just a list of IDs
void localBugAssertion(const char *file, int lineNum, const char *msg, bool ok, AssertionLevel level) const
Test for valid library behavior on local process only.
Problem base class from which other classes (PartitioningProblem, ColoringProblem, OrderingProblem, MatchingProblem, etc.) derive.
RCP< const Adapter > inputAdapter_
Defines the Problem base class.
RCP< CoordinateModel< base_adapter_t > > coordinateModel_
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
MachineRepresentation Class Finds the coordinate of the processor. Used to find the processor coordin...
ArrayRCP< const GraphMetricValues< scalar_t > > getGraphMetrics() const
Get the array of graphMetrics Graph metrics were only computed if user requested graph metrics with a...
Adapter::base_adapter_t base_adapter_t
Define IntegerRangeList validator.
const PartitioningSolution< Adapter > & getSolution()
Get the solution to the problem.
PartitioningProblem sets up partitioning problems for the user.
use mesh elements as vertices
GraphModel defines the interface required for graph models.
The base class for all model classes.
IdentifierModel defines the interface for all identifier models.
Defines the GraphModel interface.
RCP< const Model< base_adapter_t > > baseModel_
void solve(bool updateInputData=true)
Direct the problem to create a solution.
RCP< const Environment > envConst_
Multi Jagged coordinate partitioning algorithm.