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())
#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
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.
int globalOrder(const RCP< GlobalOrderingSolution< gno_t > > &solution_)
Ordering method.
SparseMatrixAdapter_t::part_t part_t
This class provides geometric coordinates with optional weights to the Zoltan2 algorithm.
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.
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.
AlgND(const RCP< const Environment > &env_, const RCP< const Comm< int > > &problemComm_, const RCP< GraphModel< typename Adapter::base_adapter_t > > &gModel_, const RCP< CoordinateModel< typename Adapter::base_adapter_t > > &cModel_, const RCP< const typename Adapter::base_adapter_t > baseInputAdapter_)
int localOrder(const RCP< LocalOrderingSolution< lno_t > > &solution_)
Ordering method.