50 #ifndef _ZOLTAN2_PARTITIONINGPROBLEM_HPP_
51 #define _ZOLTAN2_PARTITIONINGPROBLEM_HPP_
62 #ifdef ZOLTAN2_TASKMAPPING_MOVE
74 #ifdef HAVE_ZOLTAN2_OVIS
103 template<
typename Adapter>
109 typedef typename Adapter::gno_t
gno_t;
110 typedef typename Adapter::lno_t
lno_t;
117 const RCP<
const Teuchos::Comm<int> > &comm):
121 graphFlags_(), idFlags_(), coordFlags_(),
122 algName_(), numberOfWeights_(), partIds_(), partSizes_(),
123 numberOfCriteria_(), levelNumberParts_(), hierarchical_(false)
129 #ifdef HAVE_ZOLTAN2_MPI
134 rcp<const Comm<int> >(new Teuchos::MpiComm<int>(
135 Teuchos::opaqueWrapper(mpicomm))))
165 void solve(
bool updateInputData=
true);
172 return *(solution_.getRawPtr());
254 scalar_t *partSizes,
bool makeCopy=
true) ;
274 Array<std::string> algorithm_names(17);
275 algorithm_names[0] =
"rcb";
276 algorithm_names[1] =
"multijagged";
277 algorithm_names[2] =
"rib";
278 algorithm_names[3] =
"hsfc";
279 algorithm_names[4] =
"patoh";
280 algorithm_names[5] =
"phg";
281 algorithm_names[6] =
"metis";
282 algorithm_names[7] =
"parmetis";
283 algorithm_names[8] =
"pulp";
284 algorithm_names[9] =
"parma";
285 algorithm_names[10] =
"scotch";
286 algorithm_names[11] =
"ptscotch";
287 algorithm_names[12] =
"block";
288 algorithm_names[13] =
"cyclic";
289 algorithm_names[14] =
"random";
290 algorithm_names[15] =
"zoltan";
291 algorithm_names[16] =
"forTestingOnly";
292 RCP<Teuchos::StringValidator> algorithm_Validator = Teuchos::rcp(
293 new Teuchos::StringValidator( algorithm_names ));
294 pl.set(
"algorithm",
"random",
"partitioning algorithm",
295 algorithm_Validator);
298 pl.set(
"keep_partition_tree",
false,
"If true, will keep partition tree",
302 pl.set(
"rectilinear",
false,
"If true, then when a cut is made, all of the "
303 "dots located on the cut are moved to the same side of the cut. The "
304 "resulting regions are then rectilinear. The resulting load balance may "
305 "not be as good as when the group of dots is split by the cut. ",
308 RCP<Teuchos::StringValidator> partitioning_objective_Validator =
309 Teuchos::rcp(
new Teuchos::StringValidator(
310 Teuchos::tuple<std::string>(
"balance_object_count",
311 "balance_object_weight",
"multicriteria_minimize_total_weight",
312 "multicriteria_minimize_maximum_weight",
313 "multicriteria_balance_total_maximum",
"minimize_cut_edge_count",
314 "minimize_cut_edge_weight",
"minimize_neighboring_parts",
315 "minimize_boundary_vertices" )));
316 pl.set(
"partitioning_objective",
"balance_object_weight",
317 "objective of partitioning", partitioning_objective_Validator);
319 pl.set(
"imbalance_tolerance", 1.1,
"imbalance tolerance, ratio of "
323 RCP<Teuchos::EnhancedNumberValidator<int>> num_global_parts_Validator =
324 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(
325 1, Teuchos::EnhancedNumberTraits<int>::max()) );
326 pl.set(
"num_global_parts", 1,
"global number of parts to compute "
327 "(0 means use the number of processes)", num_global_parts_Validator);
330 RCP<Teuchos::EnhancedNumberValidator<int>> num_local_parts_Validator =
331 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(
332 0, Teuchos::EnhancedNumberTraits<int>::max()) );
333 pl.set(
"num_local_parts", 0,
"number of parts to compute for this "
334 "process (num_global_parts == sum of all num_local_parts)",
335 num_local_parts_Validator);
337 RCP<Teuchos::StringValidator> partitioning_approach_Validator =
338 Teuchos::rcp(
new Teuchos::StringValidator(
339 Teuchos::tuple<std::string>(
"partition",
"repartition",
340 "maximize_overlap" )));
341 pl.set(
"partitioning_approach",
"partition",
"Partition from scratch, "
342 "partition incrementally from current partition, of partition from "
343 "scratch but maximize overlap with the current partition",
344 partitioning_approach_Validator);
346 RCP<Teuchos::StringValidator> objects_to_partition_Validator =
347 Teuchos::rcp(
new Teuchos::StringValidator(
348 Teuchos::tuple<std::string>(
"matrix_rows",
"matrix_columns",
349 "matrix_nonzeros",
"mesh_elements",
"mesh_nodes",
"graph_edges",
350 "graph_vertices",
"coordinates",
"identifiers" )));
351 pl.set(
"objects_to_partition",
"graph_vertices",
"Objects to be partitioned",
352 objects_to_partition_Validator);
354 RCP<Teuchos::StringValidator> model_Validator = Teuchos::rcp(
355 new Teuchos::StringValidator(
356 Teuchos::tuple<std::string>(
"hypergraph",
"graph",
357 "geometry",
"ids" )));
358 pl.set(
"model",
"graph",
"This is a low level parameter. Normally the "
359 "library will choose a computational model based on the algorithm or "
360 "objective specified by the user.", model_Validator);
363 pl.set(
"remap_parts",
false,
"remap part numbers to minimize migration "
366 pl.set(
"mapping_type", -1,
"Mapping of solution to the processors. -1 No"
369 RCP<Teuchos::EnhancedNumberValidator<int>> ghost_layers_Validator =
370 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(1, 10, 1, 0) );
371 pl.set(
"ghost_layers", 2,
"number of layers for ghosting used in "
372 "hypergraph ghost method", ghost_layers_Validator);
376 void initializeProblem();
378 void createPartitioningProblem(
bool newData);
380 RCP<PartitioningSolution<Adapter> > solution_;
381 #ifdef ZOLTAN2_TASKMAPPING_MOVE
382 RCP<MachineRepresentation<scalar_t,part_t> > machine_;
393 std::string algName_;
395 int numberOfWeights_;
406 ArrayRCP<ArrayRCP<part_t> > partIds_;
407 ArrayRCP<ArrayRCP<scalar_t> > partSizes_;
408 int numberOfCriteria_;
412 ArrayRCP<int> levelNumberParts_;
425 template <
typename Adapter>
426 void PartitioningProblem<Adapter>::initializeProblem()
430 this->env_->debug(
DETAILED_STATUS,
"PartitioningProblem::initializeProblem");
432 if (getenv(
"DEBUGME")){
434 std::cout << getpid() << std::endl;
437 std::cout << _getpid() << std::endl;
442 #ifdef HAVE_ZOLTAN2_OVIS
443 ovis_enabled(this->comm_->getRank());
448 #ifdef ZOLTAN2_TASKMAPPING_MOVE
449 machine_ = RCP<MachineRepresentation<scalar_t,part_t> >(
450 new MachineRepresentation<scalar_t,part_t>(*(this->comm_)));
456 numberOfWeights_ = this->inputAdapter_->getNumWeightsPerID();
458 numberOfCriteria_ = (numberOfWeights_ > 1) ? numberOfWeights_ : 1;
460 inputType_ = this->inputAdapter_->adapterType();
465 ArrayRCP<part_t> *noIds =
new ArrayRCP<part_t> [numberOfCriteria_];
466 ArrayRCP<scalar_t> *noSizes =
new ArrayRCP<scalar_t> [numberOfCriteria_];
468 partIds_ = arcp(noIds, 0, numberOfCriteria_,
true);
469 partSizes_ = arcp(noSizes, 0, numberOfCriteria_,
true);
472 std::ostringstream msg;
473 msg << this->comm_->getSize() <<
" procs,"
474 << numberOfWeights_ <<
" user-defined weights\n";
478 this->env_->memory(
"After initializeProblem");
481 template <
typename Adapter>
483 int criteria,
int len,
part_t *partIds,
scalar_t *partSizes,
bool makeCopy)
485 this->env_->localInputAssertion(__FILE__, __LINE__,
"invalid length",
488 this->env_->localInputAssertion(__FILE__, __LINE__,
"invalid criteria",
492 partIds_[criteria] = ArrayRCP<part_t>();
493 partSizes_[criteria] = ArrayRCP<scalar_t>();
497 this->env_->localInputAssertion(__FILE__, __LINE__,
"invalid arrays",
504 part_t *z2_partIds = NULL;
506 bool own_memory =
false;
509 z2_partIds =
new part_t [len];
511 this->env_->localMemoryAssertion(__FILE__, __LINE__, len, z2_partSizes);
512 memcpy(z2_partIds, partIds, len *
sizeof(
part_t));
513 memcpy(z2_partSizes, partSizes, len *
sizeof(
scalar_t));
517 z2_partIds = partIds;
518 z2_partSizes = partSizes;
521 partIds_[criteria] = arcp(z2_partIds, 0, len, own_memory);
522 partSizes_[criteria] = arcp(z2_partSizes, 0, len, own_memory);
525 template <
typename Adapter>
534 createPartitioningProblem(updateInputData);
546 if (algName_ == std::string(
"multijagged")) {
549 this->coordinateModel_));
551 else if (algName_ == std::string(
"zoltan")) {
554 this->baseInputAdapter_));
556 else if (algName_ == std::string(
"parma")) {
559 this->baseInputAdapter_));
561 else if (algName_ == std::string(
"scotch")) {
564 this->baseInputAdapter_));
566 else if (algName_ == std::string(
"parmetis")) {
571 else if (algName_ == std::string(
"pulp")) {
574 this->baseInputAdapter_));
576 else if (algName_ == std::string(
"block")) {
578 this->comm_, this->identifierModel_));
580 else if (algName_ == std::string(
"phg") ||
581 algName_ == std::string(
"patoh")) {
583 Teuchos::ParameterList &pl = this->env_->getParametersNonConst();
584 Teuchos::ParameterList &zparams = pl.sublist(
"zoltan_parameters",
false);
585 if (numberOfWeights_ > 0) {
587 sprintf(strval,
"%d", numberOfWeights_);
588 zparams.set(
"OBJ_WEIGHT_DIM", strval);
590 zparams.set(
"LB_METHOD", algName_.c_str());
591 zparams.set(
"LB_APPROACH",
"PARTITION");
592 algName_ = std::string(
"zoltan");
596 this->baseInputAdapter_));
598 else if (algName_ == std::string(
"forTestingOnly")) {
601 this->baseInputAdapter_));
608 throw std::logic_error(
"partitioning algorithm not supported");
614 this->env_->timerStart(
MACRO_TIMERS,
"create solution");
619 this->envConst_, this->comm_, numberOfWeights_,
620 partIds_.view(0, numberOfCriteria_),
621 partSizes_.view(0, numberOfCriteria_), this->algorithm_);
625 solution_ = rcp(soln);
628 this->env_->memory(
"After creating Solution");
633 this->algorithm_->partition(solution_);
638 const Teuchos::ParameterEntry *pe = this->envConst_->getParameters().getEntryPtr(
"mapping_type");
639 int mapping_type = -1;
641 mapping_type = pe->getValue(&mapping_type);
645 #if ZOLTAN2_TASKMAPPING_MOVE
646 if (mapping_type == 0){
652 this->comm_.getRawPtr(),
653 machine_.getRawPtr(),
654 this->coordinateModel_.getRawPtr(),
655 solution_.getRawPtr(),
656 this->envConst_.getRawPtr()
669 const part_t *oldParts = solution_->getPartListView();
670 size_t nLocal = ia->getNumLocalIds();
671 for (
size_t i = 0; i < nLocal; i++) {
683 else if (mapping_type == 1){
690 template <
typename Adapter>
694 "PartitioningProblem::createPartitioningProblem");
696 using Teuchos::ParameterList;
707 prevModelAvail[i] = modelAvail_[i];
712 modelFlag_t previousIdentifierModelFlags = idFlags_;
713 modelFlag_t previousCoordinateModelFlags = coordFlags_;
718 modelAvail_[i] =
false;
745 Environment &env = *(this->env_);
746 ParameterList &pl = env.getParametersNonConst();
748 std::string defString(
"default");
752 std::string model(defString);
753 const Teuchos::ParameterEntry *pe = pl.getEntryPtr(
"model");
755 model = pe->getValue<std::string>(&model);
759 std::string algorithm(defString);
760 pe = pl.getEntryPtr(
"algorithm");
762 algorithm = pe->getValue<std::string>(&algorithm);
766 bool needConsecutiveGlobalIds =
false;
767 bool removeSelfEdges=
false;
773 if (algorithm != defString)
777 if (algorithm == std::string(
"block") ||
778 algorithm == std::string(
"random") ||
779 algorithm == std::string(
"cyclic") ){
784 algName_ = algorithm;
786 else if (algorithm == std::string(
"zoltan") ||
787 algorithm == std::string(
"parma") ||
788 algorithm == std::string(
"forTestingOnly"))
790 algName_ = algorithm;
792 else if (algorithm == std::string(
"rcb") ||
793 algorithm == std::string(
"rib") ||
794 algorithm == std::string(
"hsfc"))
797 Teuchos::ParameterList &zparams = pl.sublist(
"zoltan_parameters",
false);
798 zparams.set(
"LB_METHOD", algorithm);
799 if (numberOfWeights_ > 0) {
801 sprintf(strval,
"%d", numberOfWeights_);
802 zparams.set(
"OBJ_WEIGHT_DIM", strval);
804 algName_ = std::string(
"zoltan");
806 else if (algorithm == std::string(
"multijagged"))
811 algName_ = algorithm;
813 else if (algorithm == std::string(
"metis") ||
814 algorithm == std::string(
"parmetis"))
819 algName_ = algorithm;
820 removeSelfEdges =
true;
821 needConsecutiveGlobalIds =
true;
823 else if (algorithm == std::string(
"scotch") ||
824 algorithm == std::string(
"ptscotch"))
826 algName_ = algorithm;
828 else if (algorithm == std::string(
"pulp"))
830 algName_ = algorithm;
832 else if (algorithm == std::string(
"patoh") ||
833 algorithm == std::string(
"phg"))
843 algName_ = algorithm;
848 throw std::logic_error(
"parameter list algorithm is invalid");
851 else if (model != defString)
854 if (model == std::string(
"hypergraph"))
859 algName_ = std::string(
"phg");
861 else if (model == std::string(
"graph"))
866 #ifdef HAVE_ZOLTAN2_SCOTCH
868 if (this->comm_->getSize() > 1)
869 algName_ = std::string(
"ptscotch");
871 algName_ = std::string(
"scotch");
873 #ifdef HAVE_ZOLTAN2_PARMETIS
874 if (this->comm_->getSize() > 1)
875 algName_ = std::string(
"parmetis");
877 algName_ = std::string(
"metis");
878 removeSelfEdges =
true;
879 needConsecutiveGlobalIds =
true;
881 #ifdef HAVE_ZOLTAN2_PULP
886 algName_ = std::string(
"pulp");
888 algName_ = std::string(
"phg");
893 else if (model == std::string(
"geometry"))
898 algName_ = std::string(
"multijagged");
900 else if (model == std::string(
"ids"))
905 algName_ = std::string(
"block");
910 env.localBugAssertion(__FILE__, __LINE__,
925 algName_ = std::string(
"phg");
933 algName_ = std::string(
"phg");
940 algName_ = std::string(
"multijagged");
947 algName_ = std::string(
"block");
951 throw std::logic_error(
"input type is invalid");
957 Array<int> valueList;
958 pe = pl.getEntryPtr(
"topology");
961 valueList = pe->getValue<Array<int> >(&valueList);
963 if (!Zoltan2::noValuesAreInRangeList<int>(valueList)){
964 int *n =
new int [valueList.size() + 1];
965 levelNumberParts_ = arcp(n, 0, valueList.size() + 1,
true);
966 int procsPerNode = 1;
967 for (
int i=0; i < valueList.size(); i++){
968 levelNumberParts_[i+1] = valueList[i];
969 procsPerNode *= valueList[i];
972 levelNumberParts_[0] = env.numProcs_ / procsPerNode;
974 if (env.numProcs_ % procsPerNode > 0)
975 levelNumberParts_[0]++;
979 levelNumberParts_.clear();
982 hierarchical_ = levelNumberParts_.size() > 0;
986 std::string objectOfInterest(defString);
987 pe = pl.getEntryPtr(
"objects_to_partition");
989 objectOfInterest = pe->getValue<std::string>(&objectOfInterest);
1001 std::string symParameter(defString);
1002 pe = pl.getEntryPtr(
"symmetrize_graph");
1004 symParameter = pe->getValue<std::string>(&symParameter);
1005 if (symParameter == std::string(
"transpose"))
1007 else if (symParameter == std::string(
"bipartite"))
1011 bool sgParameter =
false;
1012 pe = pl.getEntryPtr(
"subset_graph");
1014 sgParameter = pe->getValue(&sgParameter);
1016 if (sgParameter == 1)
1021 if (removeSelfEdges)
1024 if (needConsecutiveGlobalIds)
1030 if (objectOfInterest == defString ||
1031 objectOfInterest == std::string(
"matrix_rows") )
1033 else if (objectOfInterest == std::string(
"matrix_columns"))
1035 else if (objectOfInterest == std::string(
"matrix_nonzeros"))
1040 if (objectOfInterest == defString ||
1041 objectOfInterest == std::string(
"mesh_nodes") )
1043 else if (objectOfInterest == std::string(
"mesh_elements"))
1070 (graphFlags_ != previousGraphModelFlags) ||
1071 (coordFlags_ != previousCoordinateModelFlags) ||
1072 (idFlags_ != previousIdentifierModelFlags))
1084 if(modelAvail_[GraphModelType]==
true)
1087 this->graphModel_ = rcp(
new GraphModel<base_adapter_t>(
1088 this->baseInputAdapter_, this->envConst_, this->comm_,
1091 this->baseModel_ = rcp_implicit_cast<
const Model<base_adapter_t> >(
1094 if(modelAvail_[HypergraphModelType]==
true)
1100 if(modelAvail_[CoordinateModelType]==
true)
1103 this->coordinateModel_ = rcp(
new CoordinateModel<base_adapter_t>(
1104 this->baseInputAdapter_, this->envConst_, this->comm_,
1107 this->baseModel_ = rcp_implicit_cast<
const Model<base_adapter_t> >(
1108 this->coordinateModel_);
1111 if(modelAvail_[IdentifierModelType]==
true)
1114 this->identifierModel_ = rcp(
new IdentifierModel<base_adapter_t>(
1115 this->baseInputAdapter_, this->envConst_, this->comm_,
1118 this->baseModel_ = rcp_implicit_cast<
const Model<base_adapter_t> >(
1119 this->identifierModel_);
1122 this->env_->memory(
"After creating Model");
use columns as graph vertices
Serial greedy first-fit graph coloring (local graph only)
~PartitioningProblem()
Destructor.
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
Time an algorithm (or other entity) as a whole.
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.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
static RCP< Teuchos::BoolParameterEntryValidator > getBoolValidator()
Exists to make setting up validators less cluttered.
algorithm requires consecutive ids
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
PartitioningProblem(Adapter *A, ParameterList *p)
Constructor where communicator is the Teuchos default.
model must symmetrize input
model must symmetrize input
PartitioningProblem(Adapter *A, ParameterList *p, const RCP< const Teuchos::Comm< int > > &comm)
Constructor where Teuchos communicator is specified.
Defines the PartitioningSolution class.
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyDoubleValidator()
Exists to make setting up validators less cluttered.
part_t getAssignedProcForTask(part_t taskId)
getAssignedProcForTask function, returns the assigned processor id for the given task ...
sub-steps, each method's entry and exit
static void getValidParameters(ParameterList &pl)
Set up validators specific to this Problem.
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.
SparseMatrixAdapter_t::part_t part_t
use matrix rows as graph vertices
algorithm requires no self edges
Defines the IdentifierModel interface.
A PartitioningSolution is a solution to a partitioning problem.
use nonzeros as graph vertices
Defines the EvaluatePartition class.
BaseAdapterType
An enum to identify general types of adapters.
identifier data, just a list of IDs
Problem base class from which other classes (PartitioningProblem, ColoringProblem, OrderingProblem, MatchingProblem, etc.) derive.
Defines the Problem base class.
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyIntValidator()
Exists to make setting up validators less cluttered.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
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
Defines the GraphModel interface.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
static void getValidParameters(ParameterList &)
Set up validators specific to this algorithm.
void solve(bool updateInputData=true)
Direct the problem to create a solution.
Multi Jagged coordinate partitioning algorithm.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t