42 #include <Epetra_ConfigDefs.h>
48 #include <Epetra_CrsGraph.h>
49 #include <Epetra_GIDTypeVector.h>
50 #include <Epetra_MapColoring.h>
51 #include <Epetra_Map.h>
52 #include <Epetra_Comm.h>
53 #include <Epetra_Util.h>
54 #include <Epetra_Import.h>
55 #include <Epetra_Export.h>
57 #include <Epetra_Time.h>
69 template<
typename int_type>
71 CrsGraph_MapColoring::
85 if( verbosity_ > 1 ) std::cout <<
"RowMap:\n" << RowMap;
86 if( verbosity_ > 1 ) std::cout <<
"ColMap:\n" << ColMap;
98 double wTime1 = timer.WallTime();
102 if( distributedGraph )
106 for(
int i = 0; i < nRows; ++i )
108 orig.ExtractMyRowView( i, NumIndices, Indices );
113 for(
int j = 0; j < NumIndices; ++j )
114 if( Indices[j] >= nRows )
120 if( verbosity_ > 1 ) std::cout <<
"Base Graph:\n" << *base << std::endl;
122 double wTime2 = timer.WallTime();
124 std::cout <<
"EpetraExt::MapColoring [INSERT BOUNDARIES] Time: " << wTime2-wTime1 << std::endl;
130 if( verbosity_ > 1 ) std::cout <<
"Adjacency 1 Graph!\n" << Adj1;
132 wTime1 = timer.WallTime();
134 std::cout <<
"EpetraExt::MapColoring [TRANSPOSE GRAPH] Time: " << wTime1-wTime2 << std::endl;
137 if( verbosity_ > 0 ) std::cout << std::endl <<
"Delta: " << Delta << std::endl;
146 for(
int i = 0; i < nCols; ++i )
148 Adj1.ExtractMyRowView( i, NumAdj1Indices, Adj1Indices );
151 for(
int j = 0; j < NumAdj1Indices; ++j )
154 for(
int k = 0; k < NumIndices; ++k )
155 if( Indices[k] < nCols ) Cols.insert( Indices[k] );
157 int nCols2 = Cols.size();
158 std::vector<int> ColVec( nCols2 );
159 set<int>::iterator iterIS = Cols.begin();
160 set<int>::iterator iendIS = Cols.end();
161 for(
int j = 0 ; iterIS != iendIS; ++iterIS, ++j ) ColVec[j] = *iterIS;
166 if( verbosity_ > 1 ) std::cout <<
"Adjacency 2 Graph!\n" << *Adj2;
168 wTime2 = timer.WallTime();
170 std::cout <<
"EpetraExt::MapColoring [GEN DIST-2 GRAPH] Time: " << wTime2-wTime1 << std::endl;
173 wTime2 = timer.WallTime();
177 std::vector<int> rowOrder( nCols );
178 if( reordering_ == 0 || reordering_ == 1 )
180 std::multimap<int,int> adjMap;
181 typedef std::multimap<int,int>::value_type adjMapValueType;
182 for(
int i = 0; i < nCols; ++i )
183 adjMap.insert( adjMapValueType( Adj2->
NumMyIndices(i), i ) );
184 std::multimap<int,int>::iterator
iter = adjMap.begin();
185 std::multimap<int,int>::iterator
end = adjMap.end();
186 if( reordering_ == 0 )
188 for(
int i = 1; iter !=
end; ++
iter, ++i )
189 rowOrder[ nCols - i ] = (*iter).second;
193 for(
int i = 0; iter !=
end; ++
iter, ++i )
194 rowOrder[ i ] = (*iter).second;
197 else if( reordering_ == 2 )
199 for(
int i = 0; i < nCols; ++i )
202 std::random_shuffle( rowOrder.begin(), rowOrder.end() );
206 wTime1 = timer.WallTime();
208 std::cout <<
"EpetraExt::MapColoring [REORDERING] Time: " << wTime1-wTime2 << std::endl;
213 for(
int col = 0; col < nCols; ++col )
219 for(
int i = 0; i < NumIndices; ++i )
221 color = (*ColorMap)[ Indices[i] ];
222 if( color > 0 ) usedColors.insert( color );
227 if( !usedColors.count( testcolor ) ) color = testcolor;
231 (*ColorMap)[ rowOrder[col] ] = color;
234 wTime2 = timer.WallTime();
236 std::cout <<
"EpetraExt::MapColoring [GREEDY COLORING] Time: " << wTime2-wTime1 << std::endl;
238 std::cout <<
"Num GREEDY Colors: " << ColorMap->
NumColors() << std::endl;
240 else if( algo_ ==
LUBY )
244 std::vector<int> Keys(nCols);
245 std::vector<int> State(nCols,-1);
247 for(
int col = 0; col < nCols; ++col )
250 int NumRemaining = nCols;
251 int CurrentColor = 1;
253 while( NumRemaining > 0 )
256 while( NumRemaining > 0 )
261 for(
int i = 0; i < nCols; ++i )
263 int col = rowOrder[i];
267 int MyKey = Keys[col];
268 for(
int j = 0; j < NumIndices; ++j )
269 if( col != Indices[j] && State[ Indices[j] ] < 0 )
271 if( MyKey > Keys[ Indices[j] ] ) State[ Indices[j] ] = 0;
272 else State[ col ] = 0;
278 for(
int col = 0; col < nCols; ++col )
281 State[col] = CurrentColor;
285 for(
int col = 0; col < nCols; ++col )
286 if( State[col] == 0 )
290 for(
int i = 0; i < NumIndices; ++i )
291 if( col != Indices[i] && State[ Indices[i] ] == CurrentColor )
305 for(
int col = 0; col < nCols; ++col )
306 if( State[col] == 0 )
314 std::cout <<
"Finished Color: " << CurrentColor << std::endl;
315 std::cout <<
"NumRemaining: " << NumRemaining << std::endl;
322 for(
int col = 0; col < nCols; ++col )
323 (*ColorMap)[col] = State[col]-1;
325 wTime2 = timer.WallTime();
327 std::cout <<
"EpetraExt::MapColoring [LUBI COLORING] Time: " << wTime2-wTime1 << std::endl;
329 std::cout <<
"Num LUBI Colors: " << ColorMap->
NumColors() << std::endl;
335 if( distributedGraph )
delete base;
336 if( !distance1_ )
delete Adj2;
344 if( verbosity_ > 1 ) std::cout <<
"OverlapGraph:\n" << OverlapGraph;
355 for(
int i = 0; i < nRows; ++i )
360 for(
int j = 0; j < NumAdj1Indices; ++j )
362 int GID = OverlapGraph.LRID( OverlapGraph.GCID64( Adj1Indices[j] ) );
363 OverlapGraph.ExtractMyRowView( GID, NumIndices, Indices );
364 for(
int k = 0; k < NumIndices; ++k ) Cols.insert( Indices[k] );
366 int nCols2 = Cols.size();
367 std::vector<int> ColVec( nCols2 );
368 set<int>::iterator iterIS = Cols.begin();
369 set<int>::iterator iendIS = Cols.end();
370 for(
int j = 0 ; iterIS != iendIS; ++iterIS, ++j ) ColVec[j] = *iterIS;
383 RowMap.Comm().Barrier();
384 if( verbosity_ > 1 ) std::cout <<
"Adjacency 2 Graph!\n" << *Adj2;
388 std::vector<int_type> boundaryGIDs;
389 std::vector<int_type> interiorGIDs;
390 for(
int row = 0; row < nRows; ++row )
393 bool testFlag =
false;
394 for(
int i = 0; i < NumIndices; ++i )
395 if( Indices[i] >= nRows ) testFlag =
true;
396 if( testFlag ) boundaryGIDs.push_back( (int_type) Adj2->GRID64(row) );
397 else interiorGIDs.push_back( (int_type) Adj2->GRID64(row) );
400 int LocalBoundarySize = boundaryGIDs.size();
402 Epetra_Map BoundaryMap( -1, boundaryGIDs.size(),
403 LocalBoundarySize ? &boundaryGIDs[0]: 0,
405 if( verbosity_ > 1 ) std::cout <<
"BoundaryMap:\n" << BoundaryMap;
407 int_type BoundarySize = (int_type) BoundaryMap.NumGlobalElements64();
412 Epetra_Map BoundaryIndexMap( BoundarySize, LocalBoundarySize, 0, RowMap.Comm() );
413 if( verbosity_ > 1) std::cout <<
"BoundaryIndexMap:\n" << BoundaryIndexMap;
416 if( verbosity_ > 1) std::cout <<
"BoundaryGIDs:\n" << bGIDs;
418 int_type NumLocalBs = 0;
419 if( !RowMap.Comm().MyPID() ) NumLocalBs = BoundarySize;
421 Epetra_Map LocalBoundaryIndexMap( BoundarySize, NumLocalBs, 0, RowMap.Comm() );
422 if( verbosity_ > 1) std::cout <<
"LocalBoundaryIndexMap:\n" << LocalBoundaryIndexMap;
425 Epetra_Import lbImport( LocalBoundaryIndexMap, BoundaryIndexMap );
426 lbGIDs.Import( bGIDs, lbImport,
Insert );
427 if( verbosity_ > 1) std::cout <<
"LocalBoundaryGIDs:\n" << lbGIDs;
429 Epetra_Map LocalBoundaryMap( BoundarySize, NumLocalBs, lbGIDs.Values(), 0, RowMap.Comm() );
430 if( verbosity_ > 1) std::cout <<
"LocalBoundaryMap:\n" << LocalBoundaryMap;
434 LocalBoundaryGraph.
Import( *Adj2, LocalBoundaryImport,
Insert );
436 if( verbosity_ > 1 ) std::cout <<
"LocalBoundaryGraph:\n " << LocalBoundaryGraph;
440 if( verbosity_ > 1 ) std::cout <<
"LocalBoundaryColoring:\n " << LocalBoundaryColoring;
442 Epetra_Export BoundaryExport( LocalBoundaryMap, BoundaryMap );
443 BoundaryColoring.Export( LocalBoundaryColoring, BoundaryExport,
Insert );
456 std::vector<int_type> OverlapBoundaryGIDs( boundaryGIDs );
458 OverlapBoundaryGIDs.push_back( (int_type) Adj2->
ColMap().GID64(i) );
460 int_type OverlapBoundarySize = OverlapBoundaryGIDs.size();
461 Epetra_Map BoundaryColMap( (int_type) -1, OverlapBoundarySize,
462 OverlapBoundarySize ? &OverlapBoundaryGIDs[0] : 0,
467 BoundaryGraph.Import( *Adj2, BoundaryImport,
Insert );
468 BoundaryGraph.FillComplete();
469 if( verbosity_ > 1) std::cout <<
"BoundaryGraph:\n" << BoundaryGraph;
471 Epetra_Import ReverseOverlapBoundaryImport( BoundaryMap, BoundaryColMap );
472 Epetra_Import OverlapBoundaryImport( BoundaryColMap, BoundaryMap );
475 int GlobalColored = 0;
482 Util.
SetSeed( 47954118 * (MyPID+1) );
483 for(
int i=0; i < LocalBoundarySize; ++i )
486 if( val < 0 ) val *= -1;
487 BoundaryValues[i] = val;
492 OverlapBoundaryValues.Import( BoundaryValues, OverlapBoundaryImport,
Insert );
494 while( GlobalColored < BoundarySize )
499 std::vector<int> LevelIndices;
500 for(
int i = 0; i < LocalBoundarySize; ++i )
502 if( !OverlapBoundaryColoring[i] )
505 int MyVal = OverlapBoundaryValues[i];
506 BoundaryGraph.ExtractMyRowView( i, theNumIndices, theIndices );
507 bool ColorFlag =
true;
509 while( Loc<theNumIndices && theIndices[Loc]<LocalBoundarySize ) ++Loc;
510 for(
int j = Loc; j < theNumIndices; ++j )
511 if( (OverlapBoundaryValues[theIndices[j]]>MyVal)
512 && !OverlapBoundaryColoring[theIndices[j]] )
517 if( ColorFlag ) LevelIndices.push_back(i);
523 std::cout << MyPID <<
" Level Indices: ";
524 int Lsize = (int) LevelIndices.size();
525 for(
int i = 0; i < Lsize; ++i ) std::cout << LevelIndices[i] <<
" ";
526 std::cout << std::endl;
530 set<int> levelColors;
531 int Lsize = (int) LevelIndices.size();
532 for(
int i = 0; i < Lsize; ++i )
534 BoundaryGraph.ExtractMyRowView( LevelIndices[i], theNumIndices, theIndices );
538 for(
int j = 0; j < theNumIndices; ++j )
540 color = OverlapBoundaryColoring[ theIndices[j] ];
541 if( color > 0 ) usedColors.insert( color );
546 if( !usedColors.count( testcolor ) ) color = testcolor;
550 OverlapBoundaryColoring[ LevelIndices[i] ] = color;
551 levelColors.insert( color );
554 if( verbosity_ > 2 ) std::cout << MyPID <<
" Level: " << Level <<
" Count: " << LevelIndices.size() <<
" NumColors: " << levelColors.size() << std::endl;
556 if( verbosity_ > 2 ) std::cout <<
"Current Level Boundary Coloring:\n" << OverlapBoundaryColoring;
559 BoundaryColoring.Import( OverlapBoundaryColoring, ReverseOverlapBoundaryImport,
Insert );
560 OverlapBoundaryColoring.Import( BoundaryColoring, OverlapBoundaryImport,
Insert );
561 Colored += LevelIndices.size();
564 RowMap.Comm().SumAll( &Colored, &GlobalColored, 1 );
565 if( verbosity_ > 2 ) std::cout <<
"Num Globally Colored: " << GlobalColored <<
" from Num Global Boundary Nodes: " << BoundarySize << std::endl;
569 if( verbosity_ > 1 ) std::cout <<
"BoundaryColoring:\n " << BoundaryColoring;
574 for(
int i = 0; i < LocalBoundarySize; ++i )
576 int_type GID = (int_type) BoundaryMap.GID64(i);
577 RowColorMap(GID) = BoundaryColoring(GID);
582 Adj2ColColorMap.Import( RowColorMap, Adj2Import,
Insert );
584 if( verbosity_ > 1 ) std::cout <<
"RowColoringMap:\n " << RowColorMap;
585 if( verbosity_ > 1 ) std::cout <<
"Adj2ColColorMap:\n " << Adj2ColColorMap;
587 std::vector<int> rowOrder( nRows );
588 if( reordering_ == 0 || reordering_ == 1 )
590 std::multimap<int,int> adjMap;
591 typedef std::multimap<int,int>::value_type adjMapValueType;
592 for(
int i = 0; i < nRows; ++i )
593 adjMap.insert( adjMapValueType( Adj2->
NumMyIndices(i), i ) );
594 std::multimap<int,int>::iterator
iter = adjMap.begin();
595 std::multimap<int,int>::iterator
end = adjMap.end();
596 if( reordering_ == 0 )
598 for(
int i = 1; iter !=
end; ++
iter, ++i )
599 rowOrder[nRows-i] = (*iter).second;
603 for(
int i = 0; iter !=
end; ++
iter, ++i )
604 rowOrder[i] = (*iter).second;
607 else if( reordering_ == 2 )
609 for(
int i = 0; i < nRows; ++i )
612 random_shuffle( rowOrder.begin(), rowOrder.end() );
617 set<int> InteriorColors;
618 for(
int row = 0; row < nRows; ++row )
620 if( !RowColorMap[ rowOrder[row] ] )
626 for(
int i = 0; i < NumIndices; ++i )
628 color = Adj2ColColorMap[ Indices[i] ];
629 if( color > 0 ) usedColors.insert( color );
634 if( !usedColors.count( testcolor ) ) color = testcolor;
638 Adj2ColColorMap[ rowOrder[row] ] = color;
639 InteriorColors.insert( color );
642 if( verbosity_ > 1 ) std::cout << MyPID <<
" Num Interior Colors: " << InteriorColors.size() << std::endl;
643 if( verbosity_ > 1 ) std::cout <<
"RowColorMap after Greedy:\n " << RowColorMap;
647 ColorMap->Import( Adj2ColColorMap, ColImport,
Insert );
649 if( !distance1_ )
delete Adj2;
652 if( verbosity_ > 0 ) std::cout << MyPID <<
" ColorMap Color Count: " << ColorMap->
NumColors() << std::endl;
653 if( verbosity_ > 1 ) std::cout <<
"ColorMap!\n" << *ColorMap;
664 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
665 if(orig.RowMap().GlobalIndicesInt()) {
666 return Toperator<int>(orig);
670 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
671 if(orig.RowMap().GlobalIndicesLongLong()) {
672 return Toperator<long long>(orig);
676 throw "CrsGraph_MapColoring::operator(): ERROR, GlobalIndices type unknown.";
bool DistributedGlobal() const
int InsertMyIndices(int LocalRow, int NumIndices, int *Indices)
Transform to generate the explicit transpose of a Epetra_CrsGraph.
const Epetra_BlockMap & ColMap() const
Given an input Epetra_CrsGraph, a "overlapped" Epetra_CrsGraph is generated including rows associated...
virtual int MyPID() const =0
CrsGraph_MapColoring::NewTypeRef operator()(CrsGraph_MapColoring::OriginalTypeRef orig)
Generates the Epetra_MapColoring object from an input Epetra_CrsGraph.
int NumMyElements() const
int SetSeed(unsigned int Seed_in)
const Epetra_BlockMap & RowMap() const
const Epetra_Comm & Comm() const
int ExtractMyRowView(int LocalRow, int &NumIndices, int *&Indices) const
int NumMyIndices(int Row) const
int MaxNumIndices() const
Map Coloring of independent columns in a Graph.
int Import(const Epetra_SrcDistObject &A, const Epetra_Import &Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor=0)