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))
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> >(
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_);
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");
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
Serial greedy first-fit graph coloring (local graph only)
Defines the EvaluatePartition class.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
Defines the GraphModel interface.
Defines the IdentifierModel interface.
Define IntegerRangeList validator.
Defines the PartitioningSolution class.
Defines the Problem base class.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
static void getValidParameters(ParameterList &)
Set up validators specific to this algorithm.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
part_t getAssignedProcForTask(part_t taskId)
getAssignedProcForTask function, returns the assigned processor id for the given task
static RCP< Teuchos::BoolParameterEntryValidator > getBoolValidator()
Exists to make setting up validators less cluttered.
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyDoubleValidator()
Exists to make setting up validators less cluttered.
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyIntValidator()
Exists to make setting up validators less cluttered.
PartitioningProblem sets up partitioning problems for the user.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this Problem.
const PartitioningSolution< Adapter > & getSolution()
Get the solution to the problem.
Adapter::scalar_t scalar_t
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.
PartitioningProblem(Adapter *A, ParameterList *p, const RCP< const Teuchos::Comm< int > > &comm)
Constructor where Teuchos communicator is specified.
void solve(bool updateInputData=true)
Direct the problem to create a solution.
Adapter::base_adapter_t base_adapter_t
~PartitioningProblem()
Destructor.
PartitioningProblem(Adapter *A, ParameterList *p)
Constructor where communicator is the Teuchos default.
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.
A PartitioningSolution is a solution to a partitioning problem.
Problem base class from which other classes (PartitioningProblem, ColoringProblem,...
Multi Jagged coordinate partitioning algorithm.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
@ MACRO_TIMERS
Time an algorithm (or other entity) as a whole.
@ DETAILED_STATUS
sub-steps, each method's entry and exit
@ BASIC_ASSERTION
fast typical checks for valid arguments
BaseAdapterType
An enum to identify general types of adapters.
@ VectorAdapterType
vector data
@ InvalidAdapterType
unused value
@ GraphAdapterType
graph data
@ MatrixAdapterType
matrix data
@ MeshAdapterType
mesh data
@ IdentifierAdapterType
identifier data, just a list of IDs
@ VERTICES_ARE_MATRIX_ROWS
use matrix rows as graph vertices
@ VERTICES_ARE_MESH_ELEMENTS
use mesh elements as vertices
@ BUILD_SUBSET_GRAPH
ignore invalid neighbors
@ GENERATE_CONSECUTIVE_IDS
algorithm requires consecutive ids
@ SYMMETRIZE_INPUT_TRANSPOSE
model must symmetrize input
@ SYMMETRIZE_INPUT_BIPARTITE
model must symmetrize input
@ REMOVE_SELF_EDGES
algorithm requires no self edges
@ VERTICES_ARE_MESH_NODES
use mesh nodes as vertices
@ VERTICES_ARE_MATRIX_COLUMNS
use columns as graph vertices
@ VERTICES_ARE_MATRIX_NONZEROS
use nonzeros as graph vertices
SparseMatrixAdapter_t::part_t part_t