14#ifndef _ZOLTAN2_PARTITIONINGPROBLEM_HPP_
15#define _ZOLTAN2_PARTITIONINGPROBLEM_HPP_
26#ifdef ZOLTAN2_TASKMAPPING_MOVE
38#ifdef HAVE_ZOLTAN2_OVIS
67template<
typename Adapter>
73 typedef typename Adapter::gno_t
gno_t;
74 typedef typename Adapter::lno_t
lno_t;
75 typedef typename Adapter::part_t
part_t;
76 typedef typename Adapter::user_t
user_t;
81 const RCP<
const Teuchos::Comm<int> > &comm):
92#ifdef HAVE_ZOLTAN2_MPI
97 rcp<const Comm<int> >(new
Teuchos::MpiComm<int>(
98 Teuchos::opaqueWrapper(mpicomm))))
128 void solve(
bool updateInputData=
true);
217 scalar_t *partSizes,
bool makeCopy=
true) ;
240 Array<std::string> algorithm_names(19);
241 algorithm_names[0] =
"rcb";
242 algorithm_names[1] =
"multijagged";
243 algorithm_names[2] =
"rib";
244 algorithm_names[3] =
"hsfc";
245 algorithm_names[4] =
"patoh";
246 algorithm_names[5] =
"phg";
247 algorithm_names[6] =
"metis";
248 algorithm_names[7] =
"parmetis";
249 algorithm_names[8] =
"quotient";
250 algorithm_names[9] =
"pulp";
251 algorithm_names[10] =
"parma";
252 algorithm_names[11] =
"scotch";
253 algorithm_names[12] =
"ptscotch";
254 algorithm_names[13] =
"block";
255 algorithm_names[14] =
"cyclic";
256 algorithm_names[15] =
"sarma";
257 algorithm_names[16] =
"random";
258 algorithm_names[17] =
"zoltan";
259 algorithm_names[18] =
"forTestingOnly";
260 RCP<Teuchos::StringValidator> algorithm_Validator = Teuchos::rcp(
261 new Teuchos::StringValidator( algorithm_names ));
262 pl.set(
"algorithm",
"random",
"partitioning algorithm",
263 algorithm_Validator);
266 pl.set(
"keep_partition_tree",
false,
"If true, will keep partition tree",
270 pl.set(
"rectilinear",
false,
"If true, then when a cut is made, all of the "
271 "dots located on the cut are moved to the same side of the cut. The "
272 "resulting regions are then rectilinear. The resulting load balance may "
273 "not be as good as when the group of dots is split by the cut. ",
276 RCP<Teuchos::StringValidator> partitioning_objective_Validator =
277 Teuchos::rcp(
new Teuchos::StringValidator(
278 Teuchos::tuple<std::string>(
"balance_object_count",
279 "balance_object_weight",
"multicriteria_minimize_total_weight",
280 "multicriteria_minimize_maximum_weight",
281 "multicriteria_balance_total_maximum",
"minimize_cut_edge_count",
282 "minimize_cut_edge_weight",
"minimize_neighboring_parts",
283 "minimize_boundary_vertices" )));
284 pl.set(
"partitioning_objective",
"balance_object_weight",
285 "objective of partitioning", partitioning_objective_Validator);
287 pl.set(
"imbalance_tolerance", 1.1,
"imbalance tolerance, ratio of "
291 RCP<Teuchos::EnhancedNumberValidator<int>> num_global_parts_Validator =
292 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(
293 1, Teuchos::EnhancedNumberTraits<int>::max()) );
294 pl.set(
"num_global_parts", 1,
"global number of parts to compute "
295 "(0 means use the number of processes)", num_global_parts_Validator);
298 RCP<Teuchos::EnhancedNumberValidator<int>> num_local_parts_Validator =
299 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(
300 0, Teuchos::EnhancedNumberTraits<int>::max()) );
301 pl.set(
"num_local_parts", 0,
"number of parts to compute for this "
302 "process (num_global_parts == sum of all num_local_parts)",
303 num_local_parts_Validator);
305 RCP<Teuchos::StringValidator> partitioning_approach_Validator =
306 Teuchos::rcp(
new Teuchos::StringValidator(
307 Teuchos::tuple<std::string>(
"partition",
"repartition",
308 "maximize_overlap" )));
309 pl.set(
"partitioning_approach",
"partition",
"Partition from scratch, "
310 "partition incrementally from current partition, of partition from "
311 "scratch but maximize overlap with the current partition",
312 partitioning_approach_Validator);
314 RCP<Teuchos::StringValidator> objects_to_partition_Validator =
315 Teuchos::rcp(
new Teuchos::StringValidator(
316 Teuchos::tuple<std::string>(
"matrix_rows",
"matrix_columns",
317 "matrix_nonzeros",
"mesh_elements",
"mesh_nodes",
"graph_edges",
318 "graph_vertices",
"coordinates",
"identifiers" )));
319 pl.set(
"objects_to_partition",
"graph_vertices",
"Objects to be partitioned",
320 objects_to_partition_Validator);
322 RCP<Teuchos::StringValidator> model_Validator = Teuchos::rcp(
323 new Teuchos::StringValidator(
324 Teuchos::tuple<std::string>(
"hypergraph",
"graph",
325 "geometry",
"ids" )));
326 pl.set(
"model",
"graph",
"This is a low level parameter. Normally the "
327 "library will choose a computational model based on the algorithm or "
328 "objective specified by the user.", model_Validator);
331 pl.set(
"remap_parts",
false,
"remap part numbers to minimize migration "
334 pl.set(
"mapping_type", -1,
"Mapping of solution to the processors. -1 No"
337 RCP<Teuchos::EnhancedNumberValidator<int>> ghost_layers_Validator =
338 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(1, 10, 1, 0) );
339 pl.set(
"ghost_layers", 2,
"number of layers for ghosting used in "
340 "hypergraph ghost method", ghost_layers_Validator);
345 virtual void processAlgorithmName(
const std::string& algorithm,
const std::string& defString,
const std::string& model,
346 Environment &env,
bool& removeSelfEdges,
bool &isGraphType,
bool& needConsecutiveGlobalIds);
352#ifdef ZOLTAN2_TASKMAPPING_MOVE
353 RCP<MachineRepresentation<scalar_t,part_t> > machine_;
393template <
typename Adapter>
398 this->env_->debug(
DETAILED_STATUS,
"PartitioningProblem::initializeProblem");
400 if (getenv(
"DEBUGME")){
402 std::cout << getpid() << std::endl;
405 std::cout << _getpid() << std::endl;
410#ifdef HAVE_ZOLTAN2_OVIS
411 ovis_enabled(this->comm_->getRank());
416#ifdef ZOLTAN2_TASKMAPPING_MOVE
417 machine_ = RCP<MachineRepresentation<scalar_t,part_t> >(
424 numberOfWeights_ = this->inputAdapter_->getNumWeightsPerID();
426 numberOfCriteria_ = (numberOfWeights_ > 1) ? numberOfWeights_ : 1;
428 inputType_ = this->inputAdapter_->adapterType();
433 ArrayRCP<part_t> *noIds =
new ArrayRCP<part_t> [numberOfCriteria_];
434 ArrayRCP<scalar_t> *noSizes =
new ArrayRCP<scalar_t> [numberOfCriteria_];
436 partIds_ = arcp(noIds, 0, numberOfCriteria_,
true);
437 partSizes_ = arcp(noSizes, 0, numberOfCriteria_,
true);
440 std::ostringstream msg;
441 msg << this->comm_->getSize() <<
" procs,"
442 << numberOfWeights_ <<
" user-defined weights\n";
446 this->env_->memory(
"After initializeProblem");
449template <
typename Adapter>
451 int criteria,
int len,
part_t *partIds,
scalar_t *partSizes,
bool makeCopy)
453 this->env_->localInputAssertion(__FILE__, __LINE__,
"invalid length",
456 this->env_->localInputAssertion(__FILE__, __LINE__,
"invalid criteria",
460 partIds_[criteria] = ArrayRCP<part_t>();
461 partSizes_[criteria] = ArrayRCP<scalar_t>();
465 this->env_->localInputAssertion(__FILE__, __LINE__,
"invalid arrays",
472 part_t *z2_partIds = NULL;
474 bool own_memory =
false;
477 z2_partIds =
new part_t [len];
479 this->env_->localMemoryAssertion(__FILE__, __LINE__, len, z2_partSizes);
480 memcpy(z2_partIds, partIds, len *
sizeof(
part_t));
481 memcpy(z2_partSizes, partSizes, len *
sizeof(
scalar_t));
485 z2_partIds = partIds;
486 z2_partSizes = partSizes;
489 partIds_[criteria] = arcp(z2_partIds, 0, len, own_memory);
490 partSizes_[criteria] = arcp(z2_partSizes, 0, len, own_memory);
493 template <
typename Adapter>
497 if (algName_ == std::string(
"multijagged")) {
500 this->baseInputAdapter_));
502 else if (algName_ == std::string(
"zoltan")) {
505 this->baseInputAdapter_));
507 else if (algName_ == std::string(
"parma")) {
510 this->baseInputAdapter_));
512 else if (algName_ == std::string(
"scotch")) {
515 this->baseInputAdapter_));
517 else if (algName_ == std::string(
"parmetis")) {
521 this->baseInputAdapter_,
524 else if (algName_ == std::string(
"quotient")) {
527 this->baseInputAdapter_,
531 else if (algName_ == std::string(
"pulp")) {
534 this->baseInputAdapter_));
536 else if (algName_ == std::string(
"block")) {
538 this->comm_, this->baseInputAdapter_));
540 else if (algName_ == std::string(
"phg") ||
541 algName_ == std::string(
"patoh")) {
543 Teuchos::ParameterList &pl = this->env_->getParametersNonConst();
544 Teuchos::ParameterList &zparams = pl.sublist(
"zoltan_parameters",
false);
545 if (numberOfWeights_ > 0) {
547 sprintf(strval,
"%d", numberOfWeights_);
548 zparams.set(
"OBJ_WEIGHT_DIM", strval);
550 zparams.set(
"LB_METHOD", algName_.c_str());
551 zparams.set(
"LB_APPROACH",
"PARTITION");
552 algName_ = std::string(
"zoltan");
556 this->baseInputAdapter_));
558 else if (algName_ == std::string(
"sarma")) {
561 this->baseInputAdapter_));
563 else if (algName_ == std::string(
"forTestingOnly")) {
566 this->baseInputAdapter_));
573 throw std::logic_error(
"partitioning algorithm not supported");
577template <
typename Adapter>
586 createPartitioningProblem(updateInputData);
598 this->createAlgorithm();
602 this->env_->timerStart(
MACRO_TIMERS,
"create solution");
607 this->envConst_, this->comm_, numberOfWeights_,
608 partIds_.view(0, numberOfCriteria_),
609 partSizes_.view(0, numberOfCriteria_), this->algorithm_);
613 solution_ = rcp(soln);
616 this->env_->memory(
"After creating Solution");
621 this->algorithm_->partition(solution_);
626 const Teuchos::ParameterEntry *pe = this->envConst_->getParameters().getEntryPtr(
"mapping_type");
627 int mapping_type = -1;
629 mapping_type = pe->getValue(&mapping_type);
633#if ZOLTAN2_TASKMAPPING_MOVE
634 if (mapping_type == 0){
638 Zoltan2::CoordinateTaskMapper <Adapter, part_t> *ctm=
640 this->comm_.getRawPtr(),
641 machine_.getRawPtr(),
642 this->baseInputAdapter_.getRawPtr(),
643 solution_.getRawPtr(),
644 this->envConst_.getRawPtr()
657 const part_t *oldParts = solution_->getPartListView();
658 size_t nLocal = ia->getNumLocalIds();
659 for (
size_t i = 0; i < nLocal; i++) {
671 else if (mapping_type == 1){
678template <
typename Adapter>
680 const std::string &algorithm,
const std::string &defString,
681 const std::string &model,
Environment &env,
bool &removeSelfEdges,
682 bool &isGraphType,
bool &needConsecutiveGlobalIds) {
685 if (algorithm != defString) {
686 if (algorithm == std::string(
"block") ||
687 algorithm == std::string(
"random") ||
688 algorithm == std::string(
"cyclic") ||
689 algorithm == std::string(
"zoltan") ||
690 algorithm == std::string(
"parma") ||
691 algorithm == std::string(
"forTestingOnly") ||
692 algorithm == std::string(
"quotient") ||
693 algorithm == std::string(
"scotch") ||
694 algorithm == std::string(
"ptscotch") ||
695 algorithm == std::string(
"pulp") || algorithm == std::string(
"sarma") ||
696 algorithm == std::string(
"patoh") || algorithm == std::string(
"phg") ||
697 algorithm == std::string(
"multijagged")) {
698 algName_ = algorithm;
699 }
else if (algorithm == std::string(
"rcb") ||
700 algorithm == std::string(
"rib") ||
701 algorithm == std::string(
"hsfc")) {
703 Teuchos::ParameterList &zparams = pl.sublist(
"zoltan_parameters",
false);
704 zparams.set(
"LB_METHOD", algorithm);
705 if (numberOfWeights_ > 0) {
707 sprintf(strval,
"%d", numberOfWeights_);
708 zparams.set(
"OBJ_WEIGHT_DIM", strval);
710 algName_ = std::string(
"zoltan");
711 }
else if (algorithm == std::string(
"metis") ||
712 algorithm == std::string(
"parmetis")) {
713 algName_ = algorithm;
714 removeSelfEdges =
true;
715 needConsecutiveGlobalIds =
true;
719 throw std::logic_error(
"parameter list algorithm is invalid");
721 }
else if (model != defString) {
723 if (model == std::string(
"hypergraph")) {
724 algName_ = std::string(
"phg");
725 }
else if (model == std::string(
"graph")) {
726#ifdef HAVE_ZOLTAN2_SCOTCH
727 if (this->comm_->getSize() > 1)
728 algName_ = std::string(
"ptscotch");
730 algName_ = std::string(
"scotch");
732#ifdef HAVE_ZOLTAN2_PARMETIS
733 if (this->comm_->getSize() > 1)
734 algName_ = std::string(
"parmetis");
736 algName_ = std::string(
"metis");
737 removeSelfEdges =
true;
738 needConsecutiveGlobalIds =
true;
741#ifdef HAVE_ZOLTAN2_PULP
746 algName_ = std::string(
"pulp");
748 algName_ = std::string(
"phg");
752 }
else if (model == std::string(
"geometry")) {
753 algName_ = std::string(
"multijagged");
754 }
else if (model == std::string(
"ids")) {
755 algName_ = std::string(
"block");
759 "parameter list model type is invalid", 1,
768 algName_ = std::string(
"phg");
771 algName_ = std::string(
"phg");
773 algName_ = std::string(
"multijagged");
775 algName_ = std::string(
"block");
778 throw std::logic_error(
"input type is invalid");
783template <
typename Adapter>
787 "PartitioningProblem::createPartitioningProblem");
789 using Teuchos::ParameterList;
818 std::string defString(
"default");
822 std::string model(defString);
823 const Teuchos::ParameterEntry *pe = pl.getEntryPtr(
"model");
825 model = pe->getValue<std::string>(&model);
829 std::string algorithm(defString);
830 pe = pl.getEntryPtr(
"algorithm");
832 algorithm = pe->getValue<std::string>(&algorithm);
836 bool needConsecutiveGlobalIds =
false;
837 bool removeSelfEdges=
false;
838 bool isGraphModel =
false;
844 this->processAlgorithmName(algorithm, defString, model, env, removeSelfEdges,
845 isGraphModel, needConsecutiveGlobalIds);
849 Array<int> valueList;
850 pe = pl.getEntryPtr(
"topology");
853 valueList = pe->getValue<Array<int> >(&valueList);
855 if (!Zoltan2::noValuesAreInRangeList<int>(valueList)){
856 int *n =
new int [valueList.size() + 1];
857 levelNumberParts_ = arcp(n, 0, valueList.size() + 1,
true);
858 int procsPerNode = 1;
859 for (
int i=0; i < valueList.size(); i++){
860 levelNumberParts_[i+1] = valueList[i];
861 procsPerNode *= valueList[i];
864 levelNumberParts_[0] = env.
numProcs_ / procsPerNode;
867 levelNumberParts_[0]++;
871 levelNumberParts_.clear();
874 hierarchical_ = levelNumberParts_.size() > 0;
878 std::string objectOfInterest(defString);
879 pe = pl.getEntryPtr(
"objects_to_partition");
881 objectOfInterest = pe->getValue<std::string>(&objectOfInterest);
888 if (isGraphModel ==
true)
893 std::string symParameter(defString);
894 pe = pl.getEntryPtr(
"symmetrize_graph");
896 symParameter = pe->getValue<std::string>(&symParameter);
897 if (symParameter == std::string(
"transpose"))
899 else if (symParameter == std::string(
"bipartite"))
903 bool sgParameter =
false;
904 pe = pl.getEntryPtr(
"subset_graph");
906 sgParameter = pe->getValue(&sgParameter);
908 if (sgParameter == 1)
916 if (needConsecutiveGlobalIds)
922 if (objectOfInterest == defString ||
923 objectOfInterest == std::string(
"matrix_rows") )
925 else if (objectOfInterest == std::string(
"matrix_columns"))
927 else if (objectOfInterest == std::string(
"matrix_nonzeros"))
932 if (objectOfInterest == defString ||
933 objectOfInterest == std::string(
"mesh_nodes") )
935 else if (objectOfInterest == std::string(
"mesh_elements"))
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
The user parameters, debug, timing and memory profiling output objects, and error checking methods.
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.
int numProcs_
number of processes (relative to comm_)
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyIntValidator()
Exists to make setting up validators less cluttered.
void localBugAssertion(const char *file, int lineNum, const char *msg, bool ok, AssertionLevel level) const
Test for valid library behavior on local process only.
Teuchos::ParameterList & getParametersNonConst()
Returns a reference to a non-const copy of the parameters.
GraphModel defines the interface required for graph models.
MachineRepresentation Class Base class for representing machine coordinates, networks,...
PartitioningProblem sets up partitioning problems for the user.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this Problem.
ArrayRCP< ArrayRCP< part_t > > partIds_
virtual void createAlgorithm()
virtual void processAlgorithmName(const std::string &algorithm, const std::string &defString, const std::string &model, Environment &env, bool &removeSelfEdges, bool &isGraphType, bool &needConsecutiveGlobalIds)
Adapter::scalar_t scalar_t
BaseAdapterType inputType_
ArrayRCP< int > levelNumberParts_
const PartitioningSolution< Adapter > & getSolution()
Get the solution to the 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.
ArrayRCP< ArrayRCP< scalar_t > > partSizes_
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
RCP< PartitioningSolution< Adapter > > solution_
~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.
void createPartitioningProblem(bool newData)
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.
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