43 #ifdef HAVE_EXPERIMENTAL
44 #ifdef HAVE_GRAPH_REORDERINGS
52 #include <Epetra_Util.h>
53 #include <Epetra_CrsGraph.h>
54 #include <Epetra_Map.h>
55 #include <Epetra_Import.h>
64 if( RCMColMap_ != RCMMap_ )
delete RCMColMap_;
65 if( RCMMap_ )
delete RCMMap_;
77 CrsGraph_Transpose transposeTransform;
82 int NumNodes = orig.NumMyRows();
85 int RowSize, RowSizeTrans;
86 std::vector< std::vector<int> > AdjList( NumNodes );
87 int MinDegree = NumNodes;
89 for(
int i = 0; i < NumNodes; ++i )
91 orig.ExtractMyRowView( i, RowSize, LocalRow );
95 for(
int j = 0; j < RowSize; ++j )
96 if( LocalRow[j] < NumNodes ) adjSet.insert( LocalRow[j] );
97 for(
int j = 0; j < RowSizeTrans; ++j )
98 if( LocalRowTrans[j] < NumNodes ) adjSet.insert( LocalRowTrans[j] );
100 std::set<int>::iterator iterS = adjSet.begin();
101 std::set<int>::iterator endS = adjSet.end();
102 AdjList[i].resize( adjSet.size() );
103 for(
int j = 0; iterS != endS; ++iterS, ++j ) AdjList[i][j] = *iterS;
105 if( AdjList[i].size() < MinDegree )
107 MinDegree = AdjList[i].size();
119 int bestWidth = NumNodes;
122 for(
int i = 0; i < NumNodes; ++i )
124 BFT * TestBFT =
new BFT( AdjList, i, NumNodes, TooWide );
125 if( TestBFT->Depth() > bestDepth ||
126 ( TestBFT->Depth() == bestDepth && TestBFT->Width() < bestWidth ) )
129 bestDepth = TestBFT->Depth();
130 bestWidth = TestBFT->Width();
139 BestBFT =
new BFT( AdjList, MinDegreeNode, NumNodes, TooWide );
141 int MinWidth = BestBFT->Width();
142 int BestWidth = MinWidth;
143 int Diameter = BestBFT->Depth();
144 std::vector<int> Leaves;
145 BestBFT->NonNeighborLeaves( Leaves, AdjList, testLeafWidth_ );
150 bool Finished =
false;
155 NarrowerFound =
false;
157 for(
int i = 0; i < Leaves.size(); ++i )
160 BFT * TestBFT =
new BFT( AdjList, Leaves[i], MinWidth, TooWide );
166 if( TestBFT->Width() < MinWidth ) MinWidth = TestBFT->Width();
168 if( TestBFT->Depth() > Diameter )
171 Diameter = TestBFT->Depth();
172 BestWidth = TestBFT->Width();
175 NarrowerFound =
false;
177 else if( (TestBFT->Depth()==Diameter) && (TestBFT->Width()<BestWidth) )
180 BestWidth = TestBFT->Width();
182 NarrowerFound =
true;
189 BestBFT->NonNeighborLeaves( Leaves, AdjList, testLeafWidth_ );
190 else if( NarrowerFound )
192 else Finished =
true;
202 std::vector<int> RCM;
203 BestBFT->ReverseVector( RCM );
204 for(
int i = 0; i < NumNodes; ++i )
205 RCM[i] = orig.RowMap().GID( RCM[i] );
208 RCMMap_ =
new Epetra_Map( orig.RowMap().NumGlobalElements(),
211 orig.RowMap().IndexBase(),
212 orig.RowMap().Comm() );
217 std::vector<int> colIndices = RCM;
223 colIndices.push_back( origColMap.
GID(i) );
226 RCMColMap_ =
new Epetra_Map( orig.ColMap().NumGlobalElements(),
229 orig.ColMap().IndexBase(),
230 orig.ColMap().Comm() );
233 RCMColMap_ = RCMMap_;
238 RCMGraph->Import( orig, Importer, Insert );
239 RCMGraph->FillComplete();
253 CrsGraph_SymmRCM::BFT::
254 BFT(
const std::vector< std::vector<int> > & adjlist,
260 nodes_(adjlist.size()),
263 std::set<int> touchedNodes;
266 levelSets_.push_back( std::vector<int>(1) );
267 levelSets_[0][0] = root;
271 touchedNodes.insert( root );
273 while( touchedNodes.size() < nodes_ )
276 levelSets_.push_back( std::vector<int>() );
279 for(
int i = 0; i < levelSets_[depth_-2].size(); ++i )
281 int currNode = levelSets_[depth_-2][i];
282 int adjSize = adjlist[currNode].size();
283 for(
int j = 0; j < adjSize; ++j )
286 int currAdj = adjlist[currNode][j];
287 if( !touchedNodes.count( currAdj ) )
289 levelSets_[depth_-1].push_back( currAdj );
290 touchedNodes.insert( currAdj );
295 int currWidth = levelSets_[depth_-1].size();
299 if( currWidth > width_ ) width_ = currWidth;
302 if( width_ > max_width )
310 std::vector<int> degrees( currWidth );
311 for(
int i = 0; i < currWidth; ++i )
312 degrees[i] = adjlist[ levelSets_[depth_-1][i] ].size();
313 int ** indices =
new int*[1];
314 indices[0] = &(levelSets_[depth_-1][0]);
321 int minDegree = nodes_;
323 for(
int i = 0; i < nodes_; ++i )
325 if( !touchedNodes.count( i ) && adjlist[i].size() < minDegree )
327 minDegree = adjlist[i].size();
335 touchedNodes.insert( minDegreeNode );
336 levelSets_[depth_-1].push_back( minDegreeNode );
377 CrsGraph_SymmRCM::BFT::
378 NonNeighborLeaves( std::vector<int> & leaves,
379 const std::vector< std::vector<int> > & adjlist,
382 assert( (depth_>0) && (failed_==
false) );
385 int leafWidth = levelSets_[depth_-1].size();
386 std::set<int> adjSeen;
387 for(
int i = 0; i < leafWidth; ++i )
389 int currLeaf = levelSets_[depth_-1][i];
390 if( !adjSeen.count( currLeaf ) )
392 leaves.push_back( currLeaf );
393 for(
int j = 0; j < adjlist[currLeaf].size(); ++j )
394 adjSeen.insert( adjlist[currLeaf][j] );
396 if( leaves.size() == count ) i = leafWidth;
401 CrsGraph_SymmRCM::BFT::
402 ReverseVector( std::vector<int> & ordered )
404 assert( (depth_>0) && (failed_==
false) );
406 ordered.resize( nodes_ );
408 for(
int i = 0; i < depth_; ++i )
410 int currLevel = depth_ - (i+1);
411 int currWidth = levelSets_[currLevel].size();
412 for(
int j = 0; j < currWidth; ++j )
413 ordered[loc++] = levelSets_[currLevel][currWidth-j-1];
418 #endif //HAVE_GRAPH_REORDERINGS
419 #endif //HAVE_EXPERIMENTAL
bool DistributedGlobal() const
NewTypeRef operator()(OriginalTypeRef orig)
Transformation Operator.
int NumMyElements() const
~CrsGraph_SymmRCM()
Destructor.
int ExtractMyRowView(int LocalRow, int &NumIndices, int *&Indices) const
static void EPETRA_LIB_DLL_EXPORT Sort(bool SortAscending, int NumKeys, T *Keys, int NumDoubleCompanions, double **DoubleCompanions, int NumIntCompanions, int **IntCompanions, int NumLongLongCompanions, long long **LongLongCompanions)