12 #ifndef _ZOLTAN2_ALGND_HPP_
13 #define _ZOLTAN2_ALGND_HPP_
45 template <
typename Adapter>
56 const RCP<const Environment> mEnv;
57 const RCP<const Comm<int>> mProblemComm;
59 std::string mPartitionMethod;
61 const RCP<const typename Adapter::base_adapter_t> mBaseInputAdapter;
64 void getBoundLayer(part_t levelIndx,
const std::vector<part_t> &partMap,
65 const part_t *parts,
const std::set<lno_t> &excVerts,
66 lno_t &bigraphNumS, lno_t &bigraphNumT, lno_t &bigraphNumE,
67 std::vector<lno_t> &bigraphCRSRowPtr, std::vector<lno_t> &bigraphCRSCols,
68 std::vector<lno_t> &bigraphVMapU, std::vector<lno_t> &bigraphVMapV,
71 void buildPartTree(part_t level, std::vector<part_t> &levIndx,
72 part_t startV,
const std::vector<part_t> &permPartNums,
73 const std::vector<part_t> &splitRangeBeg,
74 const std::vector<part_t> &splitRangeEnd,
75 const std::vector<part_t> &treeVertParents,
76 std::vector<part_t> &sepLevels, std::vector<std::set<part_t>> &sepParts1,
77 std::vector<std::set<part_t>> &sepParts2, part_t &maxLev,
78 part_t &sepTreeIndx, part_t *sepTreeView,
79 std::vector<std::pair<part_t, part_t>> &treeIndxToSepLev);
82 const part_t *parts,
const std::set<lno_t> &sepVerts,
83 const std::vector<std::vector<std::set<lno_t>>> &sepVertsByLevel,
84 const std::vector<std::pair<part_t, part_t>> &treeIndxToSepLev,
85 lno_t *ipermView, lno_t *sepRangeView);
88 part_t targetPart,
const std::set<lno_t> &idsToExcl, std::set<lno_t> &outIds);
92 AlgND(
const RCP<const Environment> &env_,
93 const RCP<
const Comm<int>> &problemComm_,
94 const RCP<const typename Adapter::base_adapter_t> &baseInputAdapter_,
96 : mEnv(env_), mProblemComm(problemComm_), mPartitionMethod(
"rcb"),
97 mBaseInputAdapter(baseInputAdapter_), graphFlags(graphFlags_)
99 #ifndef INCLUDE_ZOLTAN2_EXPERIMENTAL
103 if (mProblemComm->getSize() != 1)
108 const Teuchos::ParameterList &pl = mEnv->getParameters();
109 const Teuchos::ParameterEntry *pe;
111 pe = pl.getEntryPtr(
"edge_separator_method");
115 mPartitionMethod = pe->getValue<std::string>(&mPartitionMethod);
128 RCP<Teuchos::StringValidator> es_method_Validator =
129 Teuchos::rcp(
new Teuchos::StringValidator(Teuchos::tuple<std::string>(
"rcb",
"phg")));
131 pl.set(
"edge_separator_method",
"rcb",
"ND ordering - Edge separator method", es_method_Validator);
138 template <
typename Adapter>
142 throw std::logic_error(
"AlgND does not support global ordering.");
149 template <
typename Adapter>
162 Teuchos::ParameterList partParams;
164 part_t numParts = mEnv->getParameters().template get<part_t>(
"num_global_parts");
166 partParams.set(
"num_global_parts", numParts);
169 partParams.set(
"keep_partition_tree",
true);
172 Teuchos::ParameterList &zparams = partParams.sublist(
"zoltan_parameters",
false);
173 zparams.set(
"LB_METHOD", mPartitionMethod);
179 const RCP<const Environment> partEnv = rcp(
new Zoltan2::Environment(partParams, this->mEnv->comm_));
184 RCP<AlgZoltan<Adapter>> algZoltan = rcp(
new AlgZoltan<Adapter>(partEnv, mProblemComm, this->mBaseInputAdapter));
186 RCP<PartitioningSolution<Adapter>> partSoln;
190 algZoltan->partition(partSoln);
192 size_t numGlobalParts = partSoln->getTargetGlobalNumberOfParts();
194 const part_t *parts = partSoln->getPartListView();
208 assert(partSoln->isPartitioningTreeBinary() ==
true);
213 part_t numTreeVerts = 0;
214 std::vector<part_t> permPartNums;
216 std::vector<part_t> splitRangeBeg;
217 std::vector<part_t> splitRangeEnd;
218 std::vector<part_t> treeVertParents;
220 partSoln->getPartitionTree(numTreeVerts, permPartNums, splitRangeBeg,
221 splitRangeEnd, treeVertParents);
235 std::vector<part_t> levInds;
237 std::vector<part_t> sepLevels;
238 std::vector<std::set<part_t>> sepParts1;
239 std::vector<std::set<part_t>> sepParts2;
241 std::vector<std::pair<part_t, part_t>> treeIndxToSepLev(treeVertParents.size());
246 part_t *sepTreeView = solution_->getSeparatorTreeView();
248 part_t sepTreeIndx = treeVertParents.size() - 1;
250 sepTreeView[sepTreeIndx] = -1;
252 buildPartTree(0, levInds, numTreeVerts, permPartNums, splitRangeBeg, splitRangeEnd, treeVertParents,
253 sepLevels, sepParts1, sepParts2, maxLevel, sepTreeIndx, sepTreeView, treeIndxToSepLev);
255 solution_->setHaveSeparatorTree(
true);
270 part_t numSeparators = sepLevels.size();
279 part_t numLevels = maxLevel + 1;
281 std::vector<std::vector<part_t>> partLevelMap(numLevels, std::vector<part_t>(numGlobalParts));
283 std::vector<part_t> sepsInLev(numLevels, 0);
285 const auto graphModel = rcp(
new GraphModel<Adapter>(mBaseInputAdapter, mEnv, mProblemComm, graphFlags));
287 for (part_t i = 0; i < numSeparators; i++)
289 part_t level = sepLevels[i];
291 for (
typename std::set<part_t>::const_iterator iter = sepParts1[i].begin();
292 iter != sepParts1[i].end(); ++iter)
294 partLevelMap[level][*iter] = 2 * sepsInLev[level];
297 for (
typename std::set<part_t>::const_iterator iter = sepParts2[i].begin();
298 iter != sepParts2[i].end(); ++iter)
300 partLevelMap[level][*iter] = 2 * sepsInLev[level] + 1;
310 std::set<lno_t> sepVerts;
311 std::vector<std::vector<std::set<lno_t>>> sepVertsByLevel(numLevels);
318 for (part_t level = 0; level < numLevels; level++)
320 sepVertsByLevel[level].resize(sepsInLev[level]);
322 for (part_t levIndx = 0; levIndx < sepsInLev[level]; levIndx++)
328 lno_t bigraphNumU = 0, bigraphNumV = 0;
329 lno_t bigraphNumE = 0;
330 std::vector<lno_t> bigraphVMapU;
331 std::vector<lno_t> bigraphVMapV;
333 std::vector<lno_t> bigraphCRSRowPtr;
334 std::vector<lno_t> bigraphCRSCols;
336 getBoundLayer(levIndx, partLevelMap[level], parts, sepVerts,
337 bigraphNumU, bigraphNumV, bigraphNumE,
338 bigraphCRSRowPtr, bigraphCRSCols,
339 bigraphVMapU, bigraphVMapV, graphModel);
371 assert(bigraphNumV > 0);
373 Matcher<lno_t> bpMatch(bigraphCRSRowPtr.data(), bigraphCRSCols.data(), bigraphNumU, bigraphNumV, bigraphNumE);
376 const std::vector<lno_t> &vertUMatches = bpMatch.getVertexUMatches();
377 const std::vector<lno_t> &vertVMatches = bpMatch.getVertexVMatches();
383 std::vector<lno_t> VC;
385 bpMatch.getVCfromMatching(bigraphCRSRowPtr, bigraphCRSCols, vertUMatches, vertVMatches,
386 bigraphVMapU, bigraphVMapV, VC);
388 for (
size_t i = 0; i < VC.size(); i++)
390 sepVerts.insert(VC[i]);
392 sepVertsByLevel[level][levIndx].insert(VC[i]);
405 lno_t *ipermView = solution_->getPermutationView(inverse);
406 lno_t *sepRangeView = solution_->getSeparatorRangeView();
408 fillSolutionIperm(graphModel, parts, sepVerts, sepVertsByLevel, treeIndxToSepLev, ipermView, sepRangeView);
410 solution_->setHaveInverse(
true);
411 solution_->setHaveSeparatorRange(
true);
417 std::cout <<
"Separators: " << std::endl;
419 part_t nLevels = sepVertsByLevel.size();
420 for (part_t level = 0; level < nLevels; level++)
423 part_t nSepsOnLev = sepVertsByLevel[level].size();
425 for (part_t levIndx = 0; levIndx < nSepsOnLev; levIndx++)
427 std::cout <<
" Separator " << level <<
" " << levIndx <<
": ";
429 typename std::set<lno_t>::const_iterator iterS;
430 for (iterS = sepVertsByLevel[level][levIndx].begin(); iterS != sepVertsByLevel[level][levIndx].end(); ++iterS)
432 std::cout << *iterS <<
" ";
434 std::cout << std::endl;
468 template <
typename Adapter>
471 const std::set<lno_t> &excVerts,
473 std::vector<lno_t> &bigraphCRSRowPtr, std::vector<lno_t> &bigraphCRSCols,
474 std::vector<lno_t> &bigraphVMapS, std::vector<lno_t> &bigraphVMapT,
477 typedef typename Adapter::offset_t offset_t;
480 lno_t numVerts = graphModel->getLocalNumVertices();
484 ArrayView<const gno_t> eIDs;
485 ArrayView<const offset_t> vOffsets;
486 ArrayView<input_t> wgts;
497 graphModel->getEdgeList(eIDs, vOffsets, wgts);
502 std::map<lno_t, std::set<lno_t>> bigraphEs;
503 std::set<lno_t> vSetS;
504 std::set<lno_t> vSetT;
508 for (
lno_t v1 = 0; v1 < numVerts; v1++)
511 part_t vpart1 = partMap[parts[v1]];
513 bool correctBL = (vpart1 >= 2 * levelIndx && vpart1 < 2 * (levelIndx + 1));
523 if (excVerts.find(v1) != excVerts.end())
530 for (offset_t j = vOffsets[v1]; j < vOffsets[v1 + 1]; j++)
535 part_t vpart2 = partMap[parts[v2]];
537 correctBL = (vpart2 >= 2 * levelIndx && vpart2 < 2 * (levelIndx + 1));
547 if (excVerts.find(v2) != excVerts.end())
552 if (vpart1 != vpart2)
560 if (bigraphEs.find(v1) == bigraphEs.end())
562 bigraphEs[v1] = std::set<lno_t>();
564 bigraphEs[v1].insert(v2);
579 bigraphNumS = vSetS.
size();
580 bigraphNumT = vSetT.size();
586 bigraphVMapS.resize(bigraphNumS);
588 std::map<lno_t, lno_t> glob2LocTMap;
591 for (
typename std::set<lno_t>::const_iterator iter = vSetS.begin(); iter != vSetS.end(); ++iter)
593 bigraphVMapS[indx] = *iter;
597 bigraphVMapT.resize(bigraphNumT);
599 for (
typename std::set<lno_t>::const_iterator iter = vSetT.begin(); iter != vSetT.end(); ++iter)
601 bigraphVMapT[indx] = *iter;
602 glob2LocTMap[*iter] = indx;
610 bigraphCRSRowPtr.resize(bigraphNumS + 1);
611 bigraphCRSCols.resize(bigraphNumE);
617 bigraphCRSRowPtr[0] = 0;
621 typename std::map<lno_t, std::set<lno_t>>::const_iterator iterM;
622 for (iterM = bigraphEs.begin(); iterM != bigraphEs.end(); ++iterM)
624 bigraphCRSRowPtr[rownum + 1] = bigraphCRSRowPtr[rownum] + (*iterM).second.size();
626 for (
typename std::set<lno_t>::const_iterator iter = (*iterM).second.begin(); iter != (*iterM).second.end(); ++iter)
628 bigraphCRSCols[nzIndx] = glob2LocTMap[(*iter)];
641 template <
typename Adapter>
642 void AlgND<Adapter>::
643 buildPartTree(
part_t level, std::vector<part_t> &levIndx,
645 const std::vector<part_t> &permPartNums,
646 const std::vector<part_t> &splitRangeBeg,
647 const std::vector<part_t> &splitRangeEnd,
648 const std::vector<part_t> &treeVertParents,
649 std::vector<part_t> &sepLevels,
650 std::vector<std::set<part_t>> &sepParts1, std::vector<std::set<part_t>> &sepParts2,
652 part_t *sepTreeView, std::vector<std::pair<part_t, part_t>> &treeIndxToSepLev)
656 part_t tmpMaxLev = maxLev;
661 typename std::vector<part_t>::const_iterator iter;
662 std::vector<part_t> inds;
664 for (iter = treeVertParents.begin(); iter != treeVertParents.end(); ++iter)
678 assert(inds.size() == 2 || inds.size() == 0);
681 if (inds.size() == 2)
684 if ((
part_t)levIndx.size() < level + 1)
686 levIndx.push_back(0);
695 treeIndxToSepLev[gIndx].first = level;
696 treeIndxToSepLev[gIndx].second = levIndx[level];
701 sepLevels.push_back(level);
703 sepParts1.push_back(std::set<part_t>());
704 typename std::vector<std::set<part_t>>::iterator setIter = sepParts1.end();
707 for (
part_t k = splitRangeBeg[v0]; k < splitRangeEnd[v0]; k++)
709 (*setIter).insert(permPartNums[k]);
712 sepParts2.push_back(std::set<part_t>());
713 setIter = sepParts2.end();
716 for (
part_t k = splitRangeBeg[v1]; k < splitRangeEnd[v1]; k++)
718 (*setIter).insert(permPartNums[k]);
721 part_t parentNode = gIndx;
723 sepTreeView[gIndx] = parentNode;
726 buildPartTree(level + 1, levIndx, v0,
727 permPartNums, splitRangeBeg, splitRangeEnd, treeVertParents,
728 sepLevels, sepParts1, sepParts2,
730 gIndx, sepTreeView, treeIndxToSepLev);
731 if (tmpMaxLev > maxLev)
737 sepTreeView[gIndx] = parentNode;
739 buildPartTree(level + 1, levIndx, v1,
740 permPartNums, splitRangeBeg, splitRangeEnd, treeVertParents,
741 sepLevels, sepParts1, sepParts2,
743 gIndx, sepTreeView, treeIndxToSepLev);
744 if (tmpMaxLev > maxLev)
752 treeIndxToSepLev[gIndx].first = -1;
753 treeIndxToSepLev[gIndx].second = permPartNums[splitRangeBeg[startV]];
764 template <
typename Adapter>
765 void AlgND<Adapter>::
766 fillSolutionIperm(
const RCP<
const GraphModel<Adapter>> &graphModel,
767 const part_t *parts,
const std::set<lno_t> &sepVerts,
768 const std::vector<std::vector<std::set<lno_t>>> &sepVertsByLevel,
769 const std::vector<std::pair<part_t, part_t>> &treeIndxToSepLev,
773 lno_t sepRangeIndx = 0;
774 sepRangeView[sepRangeIndx] = 0;
776 for (
size_t i = 0; i < treeIndxToSepLev.size(); i++)
778 part_t lev = treeIndxToSepLev[i].first;
784 std::set<lno_t> idSet;
785 getIdsOfPart(graphModel, parts, treeIndxToSepLev[i].second, sepVerts, idSet);
787 for (
typename std::set<lno_t>::const_iterator setIter = idSet.begin(); setIter != idSet.end();
790 ipermView[permIndx] = *setIter;
793 sepRangeView[sepRangeIndx + 1] = sepRangeView[sepRangeIndx] + idSet.size();
802 const std::set<lno_t> &idSet = sepVertsByLevel[lev][treeIndxToSepLev[i].second];
804 for (
typename std::set<lno_t>::const_iterator setIter = idSet.begin();
805 setIter != idSet.end(); ++setIter)
807 ipermView[permIndx] = *setIter;
810 sepRangeView[sepRangeIndx + 1] = sepRangeView[sepRangeIndx] + idSet.size();
820 template <
typename Adapter>
821 void AlgND<Adapter>::
822 getIdsOfPart(
const RCP<
const GraphModel<Adapter>> &graphModel,
const part_t *parts,
823 part_t targetPart,
const std::set<lno_t> &idsToExcl, std::set<lno_t> &outIds)
825 size_t numVerts = graphModel->getLocalNumVertices();
827 for (
size_t i = 0; i < numVerts; i++)
829 if (parts[i] == targetPart && idsToExcl.find(i) == idsToExcl.end())
#define Z2_THROW_SERIAL(mystr)
Throw an error when code is run on more than one processor.
LO match()
Computes the maximum cardinality matching.
lno_t size() const
Return the length of the strided array.
interface to the Zoltan package
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
AlgND(const RCP< const Environment > &env_, const RCP< const Comm< int >> &problemComm_, const RCP< const typename Adapter::base_adapter_t > &baseInputAdapter_, const modelFlag_t &graphFlags_)
map_t::global_ordinal_type gno_t
Defines the PartitioningSolution class.
An implementation of the Matcher interface that operates on Epetra matrices and Graphs.
sub-steps, each method's entry and exit
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
SparseMatrixAdapter_t::part_t part_t
Defines the IdentifierModel interface.
A PartitioningSolution is a solution to a partitioning problem.
The StridedData class manages lists of weights or coordinates.
Algorithm defines the base class for all algorithms.
map_t::local_ordinal_type lno_t
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
#define Z2_THROW_EXPERIMENTAL(mystr)
Throw an error when experimental code is requested but not compiled.
GraphModel defines the interface required for graph models.
int globalOrder(const RCP< GlobalOrderingSolution< gno_t >> &solution_)
int localOrder(const RCP< LocalOrderingSolution< lno_t >> &solution_)