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>
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> >(
456 numberOfWeights_ = this->
inputAdapter_->getNumWeightsPerID();
458 numberOfCriteria_ = (numberOfWeights_ > 1) ? numberOfWeights_ : 1;
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")) {
551 else if (algName_ == std::string(
"zoltan")) {
556 else if (algName_ == std::string(
"parma")) {
561 else if (algName_ == std::string(
"scotch")) {
566 else if (algName_ == std::string(
"parmetis")) {
571 else if (algName_ == std::string(
"pulp")) {
576 else if (algName_ == std::string(
"block")) {
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");
598 else if (algName_ == std::string(
"forTestingOnly")) {
608 throw std::logic_error(
"partitioning algorithm not supported");
620 partIds_.view(0, numberOfCriteria_),
621 partSizes_.view(0, numberOfCriteria_), this->
algorithm_);
625 solution_ = rcp(soln);
628 this->
env_->memory(
"After creating 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(),
655 solution_.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;
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;
845 #ifdef INCLUDE_ZOLTAN2_EXPERIMENTAL_WOLF 846 else if (algorithm == std::string(
"nd"))
850 algName_ = algorithm;
856 throw std::logic_error(
"parameter list algorithm is invalid");
859 else if (model != defString)
862 if (model == std::string(
"hypergraph"))
867 if (this->
comm_->getSize() > 1)
868 algName_ = std::string(
"phg");
870 algName_ = std::string(
"patoh");
872 else if (model == std::string(
"graph"))
877 #ifdef HAVE_ZOLTAN2_SCOTCH 879 if (this->
comm_->getSize() > 1)
880 algName_ = std::string(
"ptscotch");
882 algName_ = std::string(
"scotch");
884 #ifdef HAVE_ZOLTAN2_PARMETIS 885 if (this->
comm_->getSize() > 1)
886 algName_ = std::string(
"parmetis");
888 algName_ = std::string(
"metis");
889 removeSelfEdges =
true;
890 needConsecutiveGlobalIds =
true;
892 #ifdef HAVE_ZOLTAN2_PULP 897 algName_ = std::string(
"pulp");
899 if (this->
comm_->getSize() > 1)
900 algName_ = std::string(
"phg");
902 algName_ = std::string(
"patoh");
907 else if (model == std::string(
"geometry"))
912 algName_ = std::string(
"multijagged");
914 else if (model == std::string(
"ids"))
919 algName_ = std::string(
"block");
939 if (this->
comm_->getSize() > 1)
940 algName_ = std::string(
"phg");
942 algName_ = std::string(
"patoh");
950 if (this->
comm_->getSize() > 1)
951 algName_ = std::string(
"phg");
953 algName_ = std::string(
"patoh");
960 algName_ = std::string(
"multijagged");
967 algName_ = std::string(
"block");
971 throw std::logic_error(
"input type is invalid");
977 Array<int> valueList;
978 pe = pl.getEntryPtr(
"topology");
981 valueList = pe->getValue<Array<int> >(&valueList);
983 if (!Zoltan2::noValuesAreInRangeList<int>(valueList)){
984 int *n =
new int [valueList.size() + 1];
985 levelNumberParts_ = arcp(n, 0, valueList.size() + 1,
true);
986 int procsPerNode = 1;
987 for (
int i=0; i < valueList.size(); i++){
988 levelNumberParts_[i+1] = valueList[i];
989 procsPerNode *= valueList[i];
992 levelNumberParts_[0] = env.
numProcs_ / procsPerNode;
995 levelNumberParts_[0]++;
999 levelNumberParts_.clear();
1002 hierarchical_ = levelNumberParts_.size() > 0;
1006 std::string objectOfInterest(defString);
1007 pe = pl.getEntryPtr(
"objects_to_partition");
1009 objectOfInterest = pe->getValue<std::string>(&objectOfInterest);
1021 std::string symParameter(defString);
1022 pe = pl.getEntryPtr(
"symmetrize_graph");
1024 symParameter = pe->getValue<std::string>(&symParameter);
1025 if (symParameter == std::string(
"transpose"))
1027 else if (symParameter == std::string(
"bipartite"))
1031 bool sgParameter =
false;
1032 pe = pl.getEntryPtr(
"subset_graph");
1034 sgParameter = pe->getValue(&sgParameter);
1036 if (sgParameter == 1)
1041 if (removeSelfEdges)
1044 if (needConsecutiveGlobalIds)
1050 if (objectOfInterest == defString ||
1051 objectOfInterest == std::string(
"matrix_rows") )
1053 else if (objectOfInterest == std::string(
"matrix_columns"))
1055 else if (objectOfInterest == std::string(
"matrix_nonzeros"))
1060 if (objectOfInterest == defString ||
1061 objectOfInterest == std::string(
"mesh_nodes") )
1063 else if (objectOfInterest == std::string(
"mesh_elements"))
1090 (graphFlags_ != previousGraphModelFlags) ||
1091 (coordFlags_ != previousCoordinateModelFlags) ||
1092 (idFlags_ != previousIdentifierModelFlags))
1104 if(modelAvail_[GraphModelType]==
true)
1114 if(modelAvail_[HypergraphModelType]==
true)
1120 if(modelAvail_[CoordinateModelType]==
true)
1131 if(modelAvail_[IdentifierModelType]==
true)
1142 this->
env_->memory(
"After creating Model");
use columns as graph vertices
Serial greedy first-fit graph coloring (local graph only)
RCP< GraphModel< base_adapter_t > > graphModel_
~PartitioningProblem()
Destructor.
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
Time an algorithm (or other entity) as a whole.
RCP< const base_adapter_t > baseInputAdapter_
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
RCP< Algorithm< Adapter > > algorithm_
PartitioningProblem(Adapter *A, ParameterList *p, const RCP< const Teuchos::Comm< int > > &comm)
Constructor where Teuchos communicator is specified.
RCP< const Comm< int > > comm_
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.
RCP< IdentifierModel< base_adapter_t > > identifierModel_
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
use matrix rows as graph vertices
This class provides geometric coordinates with optional weights to the Zoltan2 algorithm.
Teuchos::ParameterList & getParametersNonConst()
Returns a reference to a non-const copy of the parameters.
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.
void localBugAssertion(const char *file, int lineNum, const char *msg, bool ok, AssertionLevel level) const
Test for valid library behavior on local process only.
BaseAdapterType
An enum to identify general types of adapters.
identifier data, just a list of IDs
RCP< const Comm< int > > getComm()
Return the communicator used by the problem.
Problem base class from which other classes (PartitioningProblem, ColoringProblem, OrderingProblem, MatchingProblem, etc.) derive.
RCP< const Adapter > inputAdapter_
Defines the Problem base class.
RCP< CoordinateModel< base_adapter_t > > coordinateModel_
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.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
PartitioningProblem sets up partitioning problems for the user.
use mesh elements as vertices
GraphModel defines the interface required for graph models.
The base class for all model classes.
IdentifierModel defines the interface for all identifier models.
Defines the GraphModel interface.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
RCP< const Model< base_adapter_t > > baseModel_
void solve(bool updateInputData=true)
Direct the problem to create a solution.
RCP< const Environment > envConst_
Multi Jagged coordinate partitioning algorithm.
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.