48 #ifndef _ZOLTAN2_ALGND_HPP_
49 #define _ZOLTAN2_ALGND_HPP_
83 template <
typename Adapter>
92 typedef typename Adapter::lno_t lno_t;
93 typedef typename Adapter::gno_t gno_t;
96 const RCP<const Environment> mEnv;
97 const RCP<const Comm<int> > mProblemComm;
99 std::string mPartitionMethod;
101 const RCP<GraphModel<typename Adapter::base_adapter_t> > mGraphModel;
102 const RCP<CoordinateModel<typename Adapter::base_adapter_t> > mIds;
104 const RCP<const typename Adapter::base_adapter_t> mBaseInputAdapter;
106 void getBoundLayer(part_t levelIndx,
const std::vector<part_t> &partMap,
107 const part_t * parts,
108 const std::set<lno_t> &excVerts,
109 lno_t &bigraphNumS, lno_t &bigraphNumT, lno_t &bigraphNumE,
110 std::vector<lno_t> &bigraphCRSRowPtr, std::vector<lno_t> &bigraphCRSCols,
111 std::vector<lno_t> &bigraphVMapU, std::vector<lno_t> &bigraphVMapV);
113 void buildPartTree(part_t level, std::vector<part_t> &levIndx,
115 const std::vector<part_t> &permPartNums,
116 const std::vector<part_t> &splitRangeBeg,
117 const std::vector<part_t> &splitRangeEnd,
118 const std::vector<part_t> &treeVertParents,
119 std::vector<part_t> &sepLevels,
120 std::vector<std::set<part_t> > &sepParts1, std::vector<std::set<part_t> > &sepParts2,
123 part_t *sepTreeView, std::vector<std::pair<part_t,part_t> > &treeIndxToSepLev);
125 void fillSolutionIperm(
const part_t *parts,
const std::set<lno_t> &sepVerts,
126 const std::vector<std::vector< std::set<lno_t> > > & sepVertsByLevel,
127 const std::vector<std::pair<part_t,part_t> > &treeIndxToSepLev,
128 lno_t * ipermView, lno_t *sepRangeView);
130 void getIdsOfPart(
const part_t *parts, part_t targetPart,
const std::set<lno_t> &idsToExcl,
131 std::set<lno_t> &outIds);
136 AlgND(
const RCP<const Environment> &env_,
137 const RCP<
const Comm<int> > &problemComm_,
140 const RCP<const typename Adapter::base_adapter_t> baseInputAdapter_
142 :mEnv(env_), mProblemComm(problemComm_), mPartitionMethod(
"rcb"),
143 mGraphModel(gModel_),
144 mIds(cModel_), mBaseInputAdapter(baseInputAdapter_)
146 #ifndef INCLUDE_ZOLTAN2_EXPERIMENTAL
150 if(mProblemComm->getSize()!=1)
156 const Teuchos::ParameterList &pl = mEnv->getParameters();
157 const Teuchos::ParameterEntry *pe;
160 pe = pl.getEntryPtr(
"edge_separator_method");
164 mPartitionMethod = pe->getValue<std::string>(&mPartitionMethod);
178 RCP<Teuchos::StringValidator> es_method_Validator =
179 Teuchos::rcp(
new Teuchos::StringValidator(Teuchos::tuple<std::string>(
"rcb",
"phg")));
181 pl.set(
"edge_separator_method",
"rcb",
"ND ordering - Edge separator method", es_method_Validator);
189 template <
typename Adapter>
193 throw std::logic_error(
"AlgND does not support global ordering.");
201 template <
typename Adapter>
204 typedef typename Adapter::lno_t lno_t;
216 Teuchos::ParameterList partParams;
218 part_t numParts = mEnv->getParameters().template get<part_t>(
"num_global_parts");
220 partParams.set(
"num_global_parts", numParts);
223 partParams.set(
"keep_partition_tree",
true);
227 Teuchos::ParameterList &zparams = partParams.sublist(
"zoltan_parameters",
false);
228 zparams.set(
"LB_METHOD", mPartitionMethod);
234 const RCP<const Environment> partEnv = rcp(
new Zoltan2::Environment(partParams,this->mEnv->comm_));
239 RCP<AlgZoltan<Adapter> > algZoltan = rcp(
new AlgZoltan<Adapter>(partEnv, mProblemComm, this->mBaseInputAdapter));
241 RCP<PartitioningSolution<Adapter> > partSoln;
246 algZoltan->partition(partSoln);
248 size_t numGlobalParts = partSoln->getTargetGlobalNumberOfParts();
250 const part_t *parts = partSoln->getPartListView();
264 assert(partSoln->isPartitioningTreeBinary()==
true);
269 part_t numTreeVerts = 0;
270 std::vector<part_t> permPartNums;
272 std::vector<part_t> splitRangeBeg;
273 std::vector<part_t> splitRangeEnd;
274 std::vector<part_t> treeVertParents;
276 partSoln->getPartitionTree(numTreeVerts,permPartNums,splitRangeBeg,
277 splitRangeEnd,treeVertParents);
291 std::vector<part_t> levInds;
293 std::vector<part_t> sepLevels;
294 std::vector<std::set<part_t> > sepParts1;
295 std::vector<std::set<part_t> > sepParts2;
297 std::vector<std::pair<part_t,part_t> > treeIndxToSepLev(treeVertParents.size());
302 part_t *sepTreeView = solution_->getSeparatorTreeView();
304 part_t sepTreeIndx= treeVertParents.size()-1;
306 sepTreeView[sepTreeIndx]=-1;
308 buildPartTree(0, levInds, numTreeVerts, permPartNums, splitRangeBeg, splitRangeEnd, treeVertParents,
309 sepLevels, sepParts1, sepParts2, maxLevel, sepTreeIndx,sepTreeView,treeIndxToSepLev);
311 solution_->setHaveSeparatorTree(
true);
327 part_t numSeparators = sepLevels.size();
336 part_t numLevels = maxLevel+1;
338 std::vector<std::vector<part_t> > partLevelMap(numLevels,std::vector<part_t>(numGlobalParts));
340 std::vector<part_t> sepsInLev(numLevels,0);
342 for(part_t i=0;i<numSeparators;i++)
344 part_t level = sepLevels[i];
346 for(
typename std::set<part_t>::const_iterator iter = sepParts1[i].begin();
347 iter!=sepParts1[i].end();++iter)
349 partLevelMap[level][*iter] = 2*sepsInLev[level];
353 for(
typename std::set<part_t>::const_iterator iter = sepParts2[i].begin();
354 iter!=sepParts2[i].end();++iter)
356 partLevelMap[level][*iter] = 2*sepsInLev[level]+1;
366 std::set<lno_t> sepVerts;
367 std::vector<std::vector< std::set<lno_t> > > sepVertsByLevel(numLevels);
374 for(part_t level=0;level<numLevels;level++)
376 sepVertsByLevel[level].resize(sepsInLev[level]);
378 for(part_t levIndx=0;levIndx<sepsInLev[level];levIndx++)
384 lno_t bigraphNumU=0, bigraphNumV=0;
386 std::vector<lno_t> bigraphVMapU;
387 std::vector<lno_t> bigraphVMapV;
389 std::vector<lno_t> bigraphCRSRowPtr;
390 std::vector<lno_t> bigraphCRSCols;
393 getBoundLayer(levIndx, partLevelMap[level], parts, sepVerts,
394 bigraphNumU,bigraphNumV,bigraphNumE,
395 bigraphCRSRowPtr, bigraphCRSCols,
396 bigraphVMapU,bigraphVMapV);
430 assert(bigraphNumV>0);
432 Matcher<lno_t> bpMatch(bigraphCRSRowPtr.data(), bigraphCRSCols.data(), bigraphNumU, bigraphNumV, bigraphNumE);
435 const std::vector<lno_t> &vertUMatches = bpMatch.getVertexUMatches();
436 const std::vector<lno_t> &vertVMatches = bpMatch.getVertexVMatches();
442 std::vector<lno_t> VC;
444 bpMatch.getVCfromMatching(bigraphCRSRowPtr,bigraphCRSCols,vertUMatches,vertVMatches,
445 bigraphVMapU,bigraphVMapV,VC);
447 for(
size_t i=0;i<VC.size();i++)
449 sepVerts.insert(VC[i]);
451 sepVertsByLevel[level][levIndx].insert(VC[i]);
464 lno_t *ipermView = solution_->getPermutationView(inverse);
465 lno_t *sepRangeView = solution_->getSeparatorRangeView();
467 fillSolutionIperm(parts, sepVerts,sepVertsByLevel,treeIndxToSepLev,ipermView, sepRangeView);
469 solution_->setHaveInverse(
true);
470 solution_->setHaveSeparatorRange(
true);
476 std::cout <<
"Separators: " << std::endl;
478 part_t nLevels = sepVertsByLevel.size();
479 for(part_t level=0;level<nLevels;level++)
482 part_t nSepsOnLev = sepVertsByLevel[level].size();
484 for(part_t levIndx=0;levIndx<nSepsOnLev;levIndx++)
486 std::cout <<
" Separator " << level <<
" " << levIndx <<
": ";
488 typename std::set<lno_t>::const_iterator iterS;
489 for (iterS=sepVertsByLevel[level][levIndx].begin();iterS!=sepVertsByLevel[level][levIndx].end();++iterS)
491 std::cout << *iterS <<
" ";
493 std::cout << std::endl;
529 template <
typename Adapter>
532 const std::set<lno_t> &excVerts,
533 lno_t &bigraphNumS, lno_t &bigraphNumT, lno_t &bigraphNumE,
534 std::vector<lno_t> &bigraphCRSRowPtr, std::vector<lno_t> &bigraphCRSCols,
535 std::vector<lno_t> &bigraphVMapS, std::vector<lno_t> &bigraphVMapT)
537 typedef typename Adapter::lno_t lno_t;
538 typedef typename Adapter::offset_t offset_t;
539 typedef typename Adapter::scalar_t scalar_t;
542 lno_t numVerts = mGraphModel->getLocalNumVertices();
546 ArrayView< const gno_t > eIDs;
547 ArrayView< const offset_t > vOffsets;
548 ArrayView< input_t > wgts;
560 mGraphModel->getEdgeList(eIDs, vOffsets, wgts);
566 std::map<lno_t,std::set<lno_t> > bigraphEs;
567 std::set<lno_t> vSetS;
568 std::set<lno_t> vSetT;
572 for(lno_t v1=0;v1<numVerts;v1++)
575 part_t vpart1 = partMap[parts[v1]];
577 bool correctBL = (vpart1 >= 2*levelIndx && vpart1 < 2*(levelIndx+1) );
587 if(excVerts.find(v1)!=excVerts.end())
594 for(offset_t j=vOffsets[v1];j<vOffsets[v1+1];j++)
599 part_t vpart2 = partMap[parts[v2]];
601 correctBL = (vpart2 >= 2*levelIndx && vpart2 < 2*(levelIndx+1) );
611 if(excVerts.find(v2)!=excVerts.end())
616 if ( vpart1 != vpart2 )
624 if(bigraphEs.find(v1)==bigraphEs.end())
626 bigraphEs[v1] = std::set<lno_t>();
628 bigraphEs[v1].insert(v2);
645 bigraphNumS = vSetS.size();
646 bigraphNumT = vSetT.size();
652 bigraphVMapS.resize(bigraphNumS);
654 std::map<lno_t,lno_t> glob2LocTMap;
657 for(
typename std::set<lno_t>::const_iterator iter=vSetS.begin(); iter!=vSetS.end(); ++iter)
659 bigraphVMapS[indx] = *iter;
664 bigraphVMapT.resize(bigraphNumT);
666 for(
typename std::set<lno_t>::const_iterator iter=vSetT.begin();iter!=vSetT.end();++iter)
668 bigraphVMapT[indx] = *iter;
669 glob2LocTMap[*iter]=indx;
678 bigraphCRSRowPtr.resize(bigraphNumS+1);
679 bigraphCRSCols.resize(bigraphNumE);
685 bigraphCRSRowPtr[0]=0;
689 typename std::map<lno_t,std::set<lno_t> >::const_iterator iterM;
690 for (iterM=bigraphEs.begin();iterM!=bigraphEs.end();++iterM)
692 bigraphCRSRowPtr[rownum+1] = bigraphCRSRowPtr[rownum] + (*iterM).second.size();
694 for(
typename std::set<lno_t>::const_iterator iter=(*iterM).second.begin(); iter!=(*iterM).second.end(); ++iter)
696 bigraphCRSCols[nzIndx] = glob2LocTMap[(*iter)];
710 template <
typename Adapter>
711 void AlgND<Adapter>::
712 buildPartTree(
part_t level, std::vector<part_t> &levIndx,
714 const std::vector<part_t> &permPartNums,
715 const std::vector<part_t> &splitRangeBeg,
716 const std::vector<part_t> &splitRangeEnd,
717 const std::vector<part_t> &treeVertParents,
718 std::vector<part_t> &sepLevels,
719 std::vector<std::set<part_t> > &sepParts1, std::vector<std::set<part_t> > &sepParts2,
721 part_t *sepTreeView,std::vector<std::pair<part_t,part_t> > &treeIndxToSepLev)
730 typename std::vector<part_t>::const_iterator iter;
731 std::vector<part_t> inds;
733 for(iter=treeVertParents.begin(); iter!=treeVertParents.end(); ++iter)
747 assert(inds.size()==2 || inds.size()==0);
754 if((
part_t)levIndx.size() < level+1)
756 levIndx.push_back(0);
765 treeIndxToSepLev[gIndx].first = level;
766 treeIndxToSepLev[gIndx].second = levIndx[level];
771 sepLevels.push_back(level);
773 sepParts1.push_back(std::set<part_t>());
774 typename std::vector<std::set<part_t> >::iterator setIter = sepParts1.end();
777 for(
part_t k=splitRangeBeg[v0]; k<splitRangeEnd[v0]; k++)
779 (*setIter).insert(permPartNums[k]);
783 sepParts2.push_back(std::set<part_t>());
784 setIter = sepParts2.end();
787 for(
part_t k=splitRangeBeg[v1]; k<splitRangeEnd[v1]; k++)
789 (*setIter).insert(permPartNums[k]);
792 part_t parentNode = gIndx;
794 sepTreeView[gIndx] = parentNode;
797 buildPartTree(level+1, levIndx,v0,
798 permPartNums, splitRangeBeg, splitRangeEnd, treeVertParents,
799 sepLevels, sepParts1, sepParts2,
801 gIndx,sepTreeView,treeIndxToSepLev);
809 sepTreeView[gIndx] = parentNode;
811 buildPartTree(level+1, levIndx, v1,
812 permPartNums, splitRangeBeg, splitRangeEnd, treeVertParents,
813 sepLevels, sepParts1, sepParts2,
815 gIndx, sepTreeView,treeIndxToSepLev);
826 treeIndxToSepLev[gIndx].first = -1;
827 treeIndxToSepLev[gIndx].second = permPartNums[splitRangeBeg[startV]];
840 template <
typename Adapter>
841 void AlgND<Adapter>::
842 fillSolutionIperm(
const part_t *parts,
const std::set<lno_t> &sepVerts,
843 const std::vector<std::vector< std::set<lno_t> > > & sepVertsByLevel,
844 const std::vector<std::pair<part_t,part_t> > &treeIndxToSepLev,
845 lno_t * ipermView, lno_t *sepRangeView)
848 lno_t sepRangeIndx=0;
849 sepRangeView[sepRangeIndx] = 0;
851 for(
size_t i=0; i<treeIndxToSepLev.size();i++)
853 part_t lev = treeIndxToSepLev[i].first;
859 std::set<lno_t> idSet;
860 getIdsOfPart(parts,treeIndxToSepLev[i].second,sepVerts,idSet);
862 for(
typename std::set<lno_t>::const_iterator setIter=idSet.begin(); setIter != idSet.end();
865 ipermView[permIndx]=*setIter;
868 sepRangeView[sepRangeIndx+1]=sepRangeView[sepRangeIndx]+idSet.size();
878 const std::set<lno_t> &idSet = sepVertsByLevel[lev][treeIndxToSepLev[i].second];
880 for(
typename std::set<lno_t>::const_iterator setIter=idSet.begin();
881 setIter != idSet.end(); ++setIter)
883 ipermView[permIndx]=*setIter;
886 sepRangeView[sepRangeIndx+1]=sepRangeView[sepRangeIndx]+idSet.size();
899 template <
typename Adapter>
900 void AlgND<Adapter>::
901 getIdsOfPart(
const part_t *parts,
part_t targetPart,
const std::set<lno_t> &idsToExcl,
902 std::set<lno_t> &outIds)
904 size_t numVerts = mGraphModel->getLocalNumVertices();
906 for(
size_t i=0; i<numVerts; i++)
908 if(parts[i]==targetPart && idsToExcl.find(i)==idsToExcl.end())