50 #ifndef _ZOLTAN2_PARTITIONINGPROBLEM_HPP_
51 #define _ZOLTAN2_PARTITIONINGPROBLEM_HPP_
62 #ifdef ZOLTAN2_TASKMAPPING_MOVE
74 #ifdef HAVE_ZOLTAN2_OVIS
103 template<
typename Adapter>
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) ;
275 Array<std::string> algorithm_names(19);
276 algorithm_names[0] =
"rcb";
277 algorithm_names[1] =
"multijagged";
278 algorithm_names[2] =
"rib";
279 algorithm_names[3] =
"hsfc";
280 algorithm_names[4] =
"patoh";
281 algorithm_names[5] =
"phg";
282 algorithm_names[6] =
"metis";
283 algorithm_names[7] =
"parmetis";
284 algorithm_names[8] =
"quotient";
285 algorithm_names[9] =
"pulp";
286 algorithm_names[10] =
"parma";
287 algorithm_names[11] =
"scotch";
288 algorithm_names[12] =
"ptscotch";
289 algorithm_names[13] =
"block";
290 algorithm_names[14] =
"cyclic";
291 algorithm_names[15] =
"sarma";
292 algorithm_names[16] =
"random";
293 algorithm_names[17] =
"zoltan";
294 algorithm_names[18] =
"forTestingOnly";
295 RCP<Teuchos::StringValidator> algorithm_Validator = Teuchos::rcp(
296 new Teuchos::StringValidator( algorithm_names ));
297 pl.set(
"algorithm",
"random",
"partitioning algorithm",
298 algorithm_Validator);
301 pl.set(
"keep_partition_tree",
false,
"If true, will keep partition tree",
305 pl.set(
"rectilinear",
false,
"If true, then when a cut is made, all of the "
306 "dots located on the cut are moved to the same side of the cut. The "
307 "resulting regions are then rectilinear. The resulting load balance may "
308 "not be as good as when the group of dots is split by the cut. ",
311 RCP<Teuchos::StringValidator> partitioning_objective_Validator =
312 Teuchos::rcp(
new Teuchos::StringValidator(
313 Teuchos::tuple<std::string>(
"balance_object_count",
314 "balance_object_weight",
"multicriteria_minimize_total_weight",
315 "multicriteria_minimize_maximum_weight",
316 "multicriteria_balance_total_maximum",
"minimize_cut_edge_count",
317 "minimize_cut_edge_weight",
"minimize_neighboring_parts",
318 "minimize_boundary_vertices" )));
319 pl.set(
"partitioning_objective",
"balance_object_weight",
320 "objective of partitioning", partitioning_objective_Validator);
322 pl.set(
"imbalance_tolerance", 1.1,
"imbalance tolerance, ratio of "
326 RCP<Teuchos::EnhancedNumberValidator<int>> num_global_parts_Validator =
327 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(
328 1, Teuchos::EnhancedNumberTraits<int>::max()) );
329 pl.set(
"num_global_parts", 1,
"global number of parts to compute "
330 "(0 means use the number of processes)", num_global_parts_Validator);
333 RCP<Teuchos::EnhancedNumberValidator<int>> num_local_parts_Validator =
334 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(
335 0, Teuchos::EnhancedNumberTraits<int>::max()) );
336 pl.set(
"num_local_parts", 0,
"number of parts to compute for this "
337 "process (num_global_parts == sum of all num_local_parts)",
338 num_local_parts_Validator);
340 RCP<Teuchos::StringValidator> partitioning_approach_Validator =
341 Teuchos::rcp(
new Teuchos::StringValidator(
342 Teuchos::tuple<std::string>(
"partition",
"repartition",
343 "maximize_overlap" )));
344 pl.set(
"partitioning_approach",
"partition",
"Partition from scratch, "
345 "partition incrementally from current partition, of partition from "
346 "scratch but maximize overlap with the current partition",
347 partitioning_approach_Validator);
349 RCP<Teuchos::StringValidator> objects_to_partition_Validator =
350 Teuchos::rcp(
new Teuchos::StringValidator(
351 Teuchos::tuple<std::string>(
"matrix_rows",
"matrix_columns",
352 "matrix_nonzeros",
"mesh_elements",
"mesh_nodes",
"graph_edges",
353 "graph_vertices",
"coordinates",
"identifiers" )));
354 pl.set(
"objects_to_partition",
"graph_vertices",
"Objects to be partitioned",
355 objects_to_partition_Validator);
357 RCP<Teuchos::StringValidator> model_Validator = Teuchos::rcp(
358 new Teuchos::StringValidator(
359 Teuchos::tuple<std::string>(
"hypergraph",
"graph",
360 "geometry",
"ids" )));
361 pl.set(
"model",
"graph",
"This is a low level parameter. Normally the "
362 "library will choose a computational model based on the algorithm or "
363 "objective specified by the user.", model_Validator);
366 pl.set(
"remap_parts",
false,
"remap part numbers to minimize migration "
369 pl.set(
"mapping_type", -1,
"Mapping of solution to the processors. -1 No"
372 RCP<Teuchos::EnhancedNumberValidator<int>> ghost_layers_Validator =
373 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(1, 10, 1, 0) );
374 pl.set(
"ghost_layers", 2,
"number of layers for ghosting used in "
375 "hypergraph ghost method", ghost_layers_Validator);
379 void initializeProblem();
381 void createPartitioningProblem(
bool newData);
383 RCP<PartitioningSolution<Adapter> > solution_;
384 #ifdef ZOLTAN2_TASKMAPPING_MOVE
385 RCP<MachineRepresentation<scalar_t,part_t> > machine_;
396 std::string algName_;
398 int numberOfWeights_;
409 ArrayRCP<ArrayRCP<part_t> > partIds_;
410 ArrayRCP<ArrayRCP<scalar_t> > partSizes_;
411 int numberOfCriteria_;
415 ArrayRCP<int> levelNumberParts_;
428 template <
typename Adapter>
429 void PartitioningProblem<Adapter>::initializeProblem()
433 this->env_->debug(
DETAILED_STATUS,
"PartitioningProblem::initializeProblem");
435 if (getenv(
"DEBUGME")){
437 std::cout << getpid() << std::endl;
440 std::cout << _getpid() << std::endl;
445 #ifdef HAVE_ZOLTAN2_OVIS
446 ovis_enabled(this->comm_->getRank());
451 #ifdef ZOLTAN2_TASKMAPPING_MOVE
452 machine_ = RCP<MachineRepresentation<scalar_t,part_t> >(
453 new MachineRepresentation<scalar_t,part_t>(*(this->comm_)));
459 numberOfWeights_ = this->inputAdapter_->getNumWeightsPerID();
461 numberOfCriteria_ = (numberOfWeights_ > 1) ? numberOfWeights_ : 1;
463 inputType_ = this->inputAdapter_->adapterType();
468 ArrayRCP<part_t> *noIds =
new ArrayRCP<part_t> [numberOfCriteria_];
469 ArrayRCP<scalar_t> *noSizes =
new ArrayRCP<scalar_t> [numberOfCriteria_];
471 partIds_ = arcp(noIds, 0, numberOfCriteria_,
true);
472 partSizes_ = arcp(noSizes, 0, numberOfCriteria_,
true);
475 std::ostringstream msg;
476 msg << this->comm_->getSize() <<
" procs,"
477 << numberOfWeights_ <<
" user-defined weights\n";
481 this->env_->memory(
"After initializeProblem");
484 template <
typename Adapter>
486 int criteria,
int len,
part_t *partIds,
scalar_t *partSizes,
bool makeCopy)
488 this->env_->localInputAssertion(__FILE__, __LINE__,
"invalid length",
491 this->env_->localInputAssertion(__FILE__, __LINE__,
"invalid criteria",
495 partIds_[criteria] = ArrayRCP<part_t>();
496 partSizes_[criteria] = ArrayRCP<scalar_t>();
500 this->env_->localInputAssertion(__FILE__, __LINE__,
"invalid arrays",
507 part_t *z2_partIds = NULL;
509 bool own_memory =
false;
512 z2_partIds =
new part_t [len];
514 this->env_->localMemoryAssertion(__FILE__, __LINE__, len, z2_partSizes);
515 memcpy(z2_partIds, partIds, len *
sizeof(
part_t));
516 memcpy(z2_partSizes, partSizes, len *
sizeof(
scalar_t));
520 z2_partIds = partIds;
521 z2_partSizes = partSizes;
524 partIds_[criteria] = arcp(z2_partIds, 0, len, own_memory);
525 partSizes_[criteria] = arcp(z2_partSizes, 0, len, own_memory);
528 template <
typename Adapter>
537 createPartitioningProblem(updateInputData);
549 if (algName_ == std::string(
"multijagged")) {
552 this->coordinateModel_));
554 else if (algName_ == std::string(
"zoltan")) {
557 this->baseInputAdapter_));
559 else if (algName_ == std::string(
"parma")) {
562 this->baseInputAdapter_));
564 else if (algName_ == std::string(
"scotch")) {
567 this->baseInputAdapter_));
569 else if (algName_ == std::string(
"parmetis")) {
575 else if (algName_ == std::string(
"quotient")) {
578 this->baseInputAdapter_));
581 else if (algName_ == std::string(
"pulp")) {
584 this->baseInputAdapter_));
586 else if (algName_ == std::string(
"block")) {
588 this->comm_, this->identifierModel_));
590 else if (algName_ == std::string(
"phg") ||
591 algName_ == std::string(
"patoh")) {
593 Teuchos::ParameterList &pl = this->env_->getParametersNonConst();
594 Teuchos::ParameterList &zparams = pl.sublist(
"zoltan_parameters",
false);
595 if (numberOfWeights_ > 0) {
597 sprintf(strval,
"%d", numberOfWeights_);
598 zparams.set(
"OBJ_WEIGHT_DIM", strval);
600 zparams.set(
"LB_METHOD", algName_.c_str());
601 zparams.set(
"LB_APPROACH",
"PARTITION");
602 algName_ = std::string(
"zoltan");
606 this->baseInputAdapter_));
608 else if (algName_ == std::string(
"sarma")) {
611 this->baseInputAdapter_));
613 else if (algName_ == std::string(
"forTestingOnly")) {
616 this->baseInputAdapter_));
623 throw std::logic_error(
"partitioning algorithm not supported");
629 this->env_->timerStart(
MACRO_TIMERS,
"create solution");
634 this->envConst_, this->comm_, numberOfWeights_,
635 partIds_.view(0, numberOfCriteria_),
636 partSizes_.view(0, numberOfCriteria_), this->algorithm_);
640 solution_ = rcp(soln);
643 this->env_->memory(
"After creating Solution");
648 this->algorithm_->partition(solution_);
653 const Teuchos::ParameterEntry *pe = this->envConst_->getParameters().getEntryPtr(
"mapping_type");
654 int mapping_type = -1;
656 mapping_type = pe->getValue(&mapping_type);
660 #if ZOLTAN2_TASKMAPPING_MOVE
661 if (mapping_type == 0){
667 this->comm_.getRawPtr(),
668 machine_.getRawPtr(),
669 this->coordinateModel_.getRawPtr(),
670 solution_.getRawPtr(),
671 this->envConst_.getRawPtr()
684 const part_t *oldParts = solution_->getPartListView();
685 size_t nLocal = ia->getNumLocalIds();
686 for (
size_t i = 0; i < nLocal; i++) {
698 else if (mapping_type == 1){
705 template <
typename Adapter>
709 "PartitioningProblem::createPartitioningProblem");
711 using Teuchos::ParameterList;
722 prevModelAvail[i] = modelAvail_[i];
727 modelFlag_t previousIdentifierModelFlags = idFlags_;
728 modelFlag_t previousCoordinateModelFlags = coordFlags_;
733 modelAvail_[i] =
false;
760 Environment &env = *(this->env_);
761 ParameterList &pl = env.getParametersNonConst();
763 std::string defString(
"default");
767 std::string model(defString);
768 const Teuchos::ParameterEntry *pe = pl.getEntryPtr(
"model");
770 model = pe->getValue<std::string>(&model);
774 std::string algorithm(defString);
775 pe = pl.getEntryPtr(
"algorithm");
777 algorithm = pe->getValue<std::string>(&algorithm);
781 bool needConsecutiveGlobalIds =
false;
782 bool removeSelfEdges=
false;
788 if (algorithm != defString)
792 if (algorithm == std::string(
"block") ||
793 algorithm == std::string(
"random") ||
794 algorithm == std::string(
"cyclic") ){
799 algName_ = algorithm;
801 else if (algorithm == std::string(
"zoltan") ||
802 algorithm == std::string(
"parma") ||
803 algorithm == std::string(
"forTestingOnly"))
805 algName_ = algorithm;
807 else if (algorithm == std::string(
"rcb") ||
808 algorithm == std::string(
"rib") ||
809 algorithm == std::string(
"hsfc"))
812 Teuchos::ParameterList &zparams = pl.sublist(
"zoltan_parameters",
false);
813 zparams.set(
"LB_METHOD", algorithm);
814 if (numberOfWeights_ > 0) {
816 sprintf(strval,
"%d", numberOfWeights_);
817 zparams.set(
"OBJ_WEIGHT_DIM", strval);
819 algName_ = std::string(
"zoltan");
821 else if (algorithm == std::string(
"multijagged"))
826 algName_ = algorithm;
828 else if (algorithm == std::string(
"metis") ||
829 algorithm == std::string(
"parmetis"))
834 algName_ = algorithm;
835 removeSelfEdges =
true;
836 needConsecutiveGlobalIds =
true;
838 else if (algorithm == std::string(
"quotient"))
840 algName_ = algorithm;
842 else if (algorithm == std::string(
"scotch") ||
843 algorithm == std::string(
"ptscotch"))
845 algName_ = algorithm;
847 else if (algorithm == std::string(
"pulp"))
849 algName_ = algorithm;
851 else if (algorithm == std::string(
"sarma"))
853 algName_ = algorithm;
855 else if (algorithm == std::string(
"patoh") ||
856 algorithm == std::string(
"phg"))
866 algName_ = algorithm;
871 throw std::logic_error(
"parameter list algorithm is invalid");
874 else if (model != defString)
877 if (model == std::string(
"hypergraph"))
882 algName_ = std::string(
"phg");
884 else if (model == std::string(
"graph"))
889 #ifdef HAVE_ZOLTAN2_SCOTCH
891 if (this->comm_->getSize() > 1)
892 algName_ = std::string(
"ptscotch");
894 algName_ = std::string(
"scotch");
896 #ifdef HAVE_ZOLTAN2_PARMETIS
897 if (this->comm_->getSize() > 1)
898 algName_ = std::string(
"parmetis");
900 algName_ = std::string(
"metis");
901 removeSelfEdges =
true;
902 needConsecutiveGlobalIds =
true;
904 #ifdef HAVE_ZOLTAN2_PULP
909 algName_ = std::string(
"pulp");
911 algName_ = std::string(
"phg");
916 else if (model == std::string(
"geometry"))
921 algName_ = std::string(
"multijagged");
923 else if (model == std::string(
"ids"))
928 algName_ = std::string(
"block");
933 env.localBugAssertion(__FILE__, __LINE__,
948 algName_ = std::string(
"phg");
956 algName_ = std::string(
"phg");
963 algName_ = std::string(
"multijagged");
970 algName_ = std::string(
"block");
974 throw std::logic_error(
"input type is invalid");
980 Array<int> valueList;
981 pe = pl.getEntryPtr(
"topology");
984 valueList = pe->getValue<Array<int> >(&valueList);
986 if (!Zoltan2::noValuesAreInRangeList<int>(valueList)){
987 int *n =
new int [valueList.size() + 1];
988 levelNumberParts_ = arcp(n, 0, valueList.size() + 1,
true);
989 int procsPerNode = 1;
990 for (
int i=0; i < valueList.size(); i++){
991 levelNumberParts_[i+1] = valueList[i];
992 procsPerNode *= valueList[i];
995 levelNumberParts_[0] = env.numProcs_ / procsPerNode;
997 if (env.numProcs_ % procsPerNode > 0)
998 levelNumberParts_[0]++;
1002 levelNumberParts_.clear();
1005 hierarchical_ = levelNumberParts_.size() > 0;
1009 std::string objectOfInterest(defString);
1010 pe = pl.getEntryPtr(
"objects_to_partition");
1012 objectOfInterest = pe->getValue<std::string>(&objectOfInterest);
1024 std::string symParameter(defString);
1025 pe = pl.getEntryPtr(
"symmetrize_graph");
1027 symParameter = pe->getValue<std::string>(&symParameter);
1028 if (symParameter == std::string(
"transpose"))
1030 else if (symParameter == std::string(
"bipartite"))
1034 bool sgParameter =
false;
1035 pe = pl.getEntryPtr(
"subset_graph");
1037 sgParameter = pe->getValue(&sgParameter);
1039 if (sgParameter == 1)
1044 if (removeSelfEdges)
1047 if (needConsecutiveGlobalIds)
1053 if (objectOfInterest == defString ||
1054 objectOfInterest == std::string(
"matrix_rows") )
1056 else if (objectOfInterest == std::string(
"matrix_columns"))
1058 else if (objectOfInterest == std::string(
"matrix_nonzeros"))
1063 if (objectOfInterest == defString ||
1064 objectOfInterest == std::string(
"mesh_nodes") )
1066 else if (objectOfInterest == std::string(
"mesh_elements"))
1093 (graphFlags_ != previousGraphModelFlags) ||
1094 (coordFlags_ != previousCoordinateModelFlags) ||
1095 (idFlags_ != previousIdentifierModelFlags))
1110 this->graphModel_ = rcp(
new GraphModel<base_adapter_t>(
1111 this->baseInputAdapter_, this->envConst_, this->comm_,
1114 this->baseModel_ = rcp_implicit_cast<const Model<base_adapter_t> >(
1126 this->coordinateModel_ = rcp(
new CoordinateModel<base_adapter_t>(
1127 this->baseInputAdapter_, this->envConst_, this->comm_,
1130 this->baseModel_ = rcp_implicit_cast<const Model<base_adapter_t> >(
1131 this->coordinateModel_);
1137 this->identifierModel_ = rcp(
new IdentifierModel<base_adapter_t>(
1138 this->baseInputAdapter_, this->envConst_, this->comm_,
1141 this->baseModel_ = rcp_implicit_cast<const Model<base_adapter_t> >(
1142 this->identifierModel_);
1145 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.
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.
GraphModel defines the interface required for graph models.
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.
map_t::local_ordinal_type lno_t
map_t::global_ordinal_type gno_t
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
Created by mbenlioglu on Aug 31, 2020.
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