14 #ifndef _ZOLTAN2_PARTITIONINGPROBLEM_HPP_
15 #define _ZOLTAN2_PARTITIONINGPROBLEM_HPP_
26 #ifdef ZOLTAN2_TASKMAPPING_MOVE
38 #ifdef HAVE_ZOLTAN2_OVIS
67 template<
typename Adapter>
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_;
393 template <
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");
449 template <
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");
577 template <
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){
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){
678 template <
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");
783 template <
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"))
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
BaseAdapterType inputType_
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
ArrayRCP< ArrayRCP< part_t > > partIds_
fast typical checks for valid arguments
ArrayRCP< ArrayRCP< scalar_t > > partSizes_
#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.
ArrayRCP< int > levelNumberParts_
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
map_t::global_ordinal_type gno_t
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.
int numProcs_
number of processes (relative to comm_)
SparseMatrixAdapter_t::part_t part_t
void createPartitioningProblem(bool newData)
use matrix rows as graph vertices
Teuchos::ParameterList & getParametersNonConst()
Returns a reference to a non-const copy of the parameters.
algorithm requires no self edges
Defines the IdentifierModel interface.
virtual void createAlgorithm()
A PartitioningSolution is a solution to a partitioning problem.
use nonzeros as graph vertices
Defines the EvaluatePartition class.
virtual void processAlgorithmName(const std::string &algorithm, const std::string &defString, const std::string &model, Environment &env, bool &removeSelfEdges, bool &isGraphType, bool &needConsecutiveGlobalIds)
BaseAdapterType
An enum to identify general types of adapters.
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.
Defines the Problem base class.
map_t::local_ordinal_type lno_t
RCP< PartitioningSolution< Adapter > > solution_
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
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.
MachineRepresentation Class Base class for representing machine coordinates, networks, etc.
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.
Defines the GraphModel interface.
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.
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