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>
70 template<
typename int_type>
72 CrsGraph_MapColoring::
86 if( verbosity_ > 1 ) std::cout <<
"RowMap:\n" << RowMap;
87 if( verbosity_ > 1 ) std::cout <<
"ColMap:\n" << ColMap;
99 double wTime1 = timer.WallTime();
103 if( distributedGraph )
107 for(
int i = 0; i < nRows; ++i )
109 orig.ExtractMyRowView( i, NumIndices, Indices );
114 for(
int j = 0; j < NumIndices; ++j )
115 if( Indices[j] >= nRows )
121 if( verbosity_ > 1 ) std::cout <<
"Base Graph:\n" << *base << std::endl;
123 double wTime2 = timer.WallTime();
125 std::cout <<
"EpetraExt::MapColoring [INSERT BOUNDARIES] Time: " << wTime2-wTime1 << std::endl;
131 if( verbosity_ > 1 ) std::cout <<
"Adjacency 1 Graph!\n" << Adj1;
133 wTime1 = timer.WallTime();
135 std::cout <<
"EpetraExt::MapColoring [TRANSPOSE GRAPH] Time: " << wTime1-wTime2 << std::endl;
138 if( verbosity_ > 0 ) std::cout << std::endl <<
"Delta: " << Delta << std::endl;
147 for(
int i = 0; i < nCols; ++i )
149 Adj1.ExtractMyRowView( i, NumAdj1Indices, Adj1Indices );
152 for(
int j = 0; j < NumAdj1Indices; ++j )
155 for(
int k = 0; k < NumIndices; ++k )
156 if( Indices[k] < nCols ) Cols.insert( Indices[k] );
158 int nCols2 = Cols.size();
159 std::vector<int> ColVec( nCols2 );
160 set<int>::iterator iterIS = Cols.begin();
161 set<int>::iterator iendIS = Cols.end();
162 for(
int j = 0 ; iterIS != iendIS; ++iterIS, ++j ) ColVec[j] = *iterIS;
167 if( verbosity_ > 1 ) std::cout <<
"Adjacency 2 Graph!\n" << *Adj2;
169 wTime2 = timer.WallTime();
171 std::cout <<
"EpetraExt::MapColoring [GEN DIST-2 GRAPH] Time: " << wTime2-wTime1 << std::endl;
174 wTime2 = timer.WallTime();
178 std::vector<int> rowOrder( nCols );
179 if( reordering_ == 0 || reordering_ == 1 )
181 std::multimap<int,int> adjMap;
182 typedef std::multimap<int,int>::value_type adjMapValueType;
183 for(
int i = 0; i < nCols; ++i )
184 adjMap.insert( adjMapValueType( Adj2->
NumMyIndices(i), i ) );
185 std::multimap<int,int>::iterator
iter = adjMap.begin();
186 std::multimap<int,int>::iterator
end = adjMap.end();
187 if( reordering_ == 0 )
189 for(
int i = 1; iter !=
end; ++
iter, ++i )
190 rowOrder[ nCols - i ] = (*iter).second;
194 for(
int i = 0; iter !=
end; ++
iter, ++i )
195 rowOrder[ i ] = (*iter).second;
198 else if( reordering_ == 2 )
200 for(
int i = 0; i < nCols; ++i )
203 std::random_device rd;
204 std::mt19937 g(rd());
205 std::shuffle( rowOrder.begin(), rowOrder.end(), g );
209 wTime1 = timer.WallTime();
211 std::cout <<
"EpetraExt::MapColoring [REORDERING] Time: " << wTime1-wTime2 << std::endl;
216 for(
int col = 0; col < nCols; ++col )
222 for(
int i = 0; i < NumIndices; ++i )
224 color = (*ColorMap)[ Indices[i] ];
225 if( color > 0 ) usedColors.insert( color );
230 if( !usedColors.count( testcolor ) ) color = testcolor;
234 (*ColorMap)[ rowOrder[col] ] = color;
237 wTime2 = timer.WallTime();
239 std::cout <<
"EpetraExt::MapColoring [GREEDY COLORING] Time: " << wTime2-wTime1 << std::endl;
241 std::cout <<
"Num GREEDY Colors: " << ColorMap->
NumColors() << std::endl;
243 else if( algo_ ==
LUBY )
247 std::vector<int> Keys(nCols);
248 std::vector<int> State(nCols,-1);
250 for(
int col = 0; col < nCols; ++col )
253 int NumRemaining = nCols;
254 int CurrentColor = 1;
256 while( NumRemaining > 0 )
259 while( NumRemaining > 0 )
264 for(
int i = 0; i < nCols; ++i )
266 int col = rowOrder[i];
270 int MyKey = Keys[col];
271 for(
int j = 0; j < NumIndices; ++j )
272 if( col != Indices[j] && State[ Indices[j] ] < 0 )
274 if( MyKey > Keys[ Indices[j] ] ) State[ Indices[j] ] = 0;
275 else State[ col ] = 0;
281 for(
int col = 0; col < nCols; ++col )
284 State[col] = CurrentColor;
288 for(
int col = 0; col < nCols; ++col )
289 if( State[col] == 0 )
293 for(
int i = 0; i < NumIndices; ++i )
294 if( col != Indices[i] && State[ Indices[i] ] == CurrentColor )
308 for(
int col = 0; col < nCols; ++col )
309 if( State[col] == 0 )
317 std::cout <<
"Finished Color: " << CurrentColor << std::endl;
318 std::cout <<
"NumRemaining: " << NumRemaining << std::endl;
325 for(
int col = 0; col < nCols; ++col )
326 (*ColorMap)[col] = State[col]-1;
328 wTime2 = timer.WallTime();
330 std::cout <<
"EpetraExt::MapColoring [LUBI COLORING] Time: " << wTime2-wTime1 << std::endl;
332 std::cout <<
"Num LUBI Colors: " << ColorMap->
NumColors() << std::endl;
338 if( distributedGraph )
delete base;
339 if( !distance1_ )
delete Adj2;
347 if( verbosity_ > 1 ) std::cout <<
"OverlapGraph:\n" << OverlapGraph;
358 for(
int i = 0; i < nRows; ++i )
363 for(
int j = 0; j < NumAdj1Indices; ++j )
365 int GID = OverlapGraph.LRID( OverlapGraph.GCID64( Adj1Indices[j] ) );
366 OverlapGraph.ExtractMyRowView( GID, NumIndices, Indices );
367 for(
int k = 0; k < NumIndices; ++k ) Cols.insert( Indices[k] );
369 int nCols2 = Cols.size();
370 std::vector<int> ColVec( nCols2 );
371 set<int>::iterator iterIS = Cols.begin();
372 set<int>::iterator iendIS = Cols.end();
373 for(
int j = 0 ; iterIS != iendIS; ++iterIS, ++j ) ColVec[j] = *iterIS;
386 RowMap.Comm().Barrier();
387 if( verbosity_ > 1 ) std::cout <<
"Adjacency 2 Graph!\n" << *Adj2;
391 std::vector<int_type> boundaryGIDs;
392 std::vector<int_type> interiorGIDs;
393 for(
int row = 0; row < nRows; ++row )
396 bool testFlag =
false;
397 for(
int i = 0; i < NumIndices; ++i )
398 if( Indices[i] >= nRows ) testFlag =
true;
399 if( testFlag ) boundaryGIDs.push_back( (int_type) Adj2->GRID64(row) );
400 else interiorGIDs.push_back( (int_type) Adj2->GRID64(row) );
403 int LocalBoundarySize = boundaryGIDs.size();
405 Epetra_Map BoundaryMap( -1, boundaryGIDs.size(),
406 LocalBoundarySize ? &boundaryGIDs[0]: 0,
408 if( verbosity_ > 1 ) std::cout <<
"BoundaryMap:\n" << BoundaryMap;
410 int_type BoundarySize = (int_type) BoundaryMap.NumGlobalElements64();
415 Epetra_Map BoundaryIndexMap( BoundarySize, LocalBoundarySize, 0, RowMap.Comm() );
416 if( verbosity_ > 1) std::cout <<
"BoundaryIndexMap:\n" << BoundaryIndexMap;
419 if( verbosity_ > 1) std::cout <<
"BoundaryGIDs:\n" << bGIDs;
421 int_type NumLocalBs = 0;
422 if( !RowMap.Comm().MyPID() ) NumLocalBs = BoundarySize;
424 Epetra_Map LocalBoundaryIndexMap( BoundarySize, NumLocalBs, 0, RowMap.Comm() );
425 if( verbosity_ > 1) std::cout <<
"LocalBoundaryIndexMap:\n" << LocalBoundaryIndexMap;
428 Epetra_Import lbImport( LocalBoundaryIndexMap, BoundaryIndexMap );
429 lbGIDs.Import( bGIDs, lbImport,
Insert );
430 if( verbosity_ > 1) std::cout <<
"LocalBoundaryGIDs:\n" << lbGIDs;
432 Epetra_Map LocalBoundaryMap( BoundarySize, NumLocalBs, lbGIDs.Values(), 0, RowMap.Comm() );
433 if( verbosity_ > 1) std::cout <<
"LocalBoundaryMap:\n" << LocalBoundaryMap;
437 LocalBoundaryGraph.
Import( *Adj2, LocalBoundaryImport,
Insert );
439 if( verbosity_ > 1 ) std::cout <<
"LocalBoundaryGraph:\n " << LocalBoundaryGraph;
443 if( verbosity_ > 1 ) std::cout <<
"LocalBoundaryColoring:\n " << LocalBoundaryColoring;
445 Epetra_Export BoundaryExport( LocalBoundaryMap, BoundaryMap );
446 BoundaryColoring.Export( LocalBoundaryColoring, BoundaryExport,
Insert );
459 std::vector<int_type> OverlapBoundaryGIDs( boundaryGIDs );
461 OverlapBoundaryGIDs.push_back( (int_type) Adj2->
ColMap().GID64(i) );
463 int_type OverlapBoundarySize = OverlapBoundaryGIDs.size();
464 Epetra_Map BoundaryColMap( (int_type) -1, OverlapBoundarySize,
465 OverlapBoundarySize ? &OverlapBoundaryGIDs[0] : 0,
470 BoundaryGraph.Import( *Adj2, BoundaryImport,
Insert );
471 BoundaryGraph.FillComplete();
472 if( verbosity_ > 1) std::cout <<
"BoundaryGraph:\n" << BoundaryGraph;
474 Epetra_Import ReverseOverlapBoundaryImport( BoundaryMap, BoundaryColMap );
475 Epetra_Import OverlapBoundaryImport( BoundaryColMap, BoundaryMap );
478 int GlobalColored = 0;
485 Util.
SetSeed( 47954118 * (MyPID+1) );
486 for(
int i=0; i < LocalBoundarySize; ++i )
489 if( val < 0 ) val *= -1;
490 BoundaryValues[i] = val;
495 OverlapBoundaryValues.Import( BoundaryValues, OverlapBoundaryImport,
Insert );
497 while( GlobalColored < BoundarySize )
502 std::vector<int> LevelIndices;
503 for(
int i = 0; i < LocalBoundarySize; ++i )
505 if( !OverlapBoundaryColoring[i] )
508 int MyVal = OverlapBoundaryValues[i];
509 BoundaryGraph.ExtractMyRowView( i, theNumIndices, theIndices );
510 bool ColorFlag =
true;
512 while( Loc<theNumIndices && theIndices[Loc]<LocalBoundarySize ) ++Loc;
513 for(
int j = Loc; j < theNumIndices; ++j )
514 if( (OverlapBoundaryValues[theIndices[j]]>MyVal)
515 && !OverlapBoundaryColoring[theIndices[j]] )
520 if( ColorFlag ) LevelIndices.push_back(i);
526 std::cout << MyPID <<
" Level Indices: ";
527 int Lsize = (int) LevelIndices.size();
528 for(
int i = 0; i < Lsize; ++i ) std::cout << LevelIndices[i] <<
" ";
529 std::cout << std::endl;
533 set<int> levelColors;
534 int Lsize = (int) LevelIndices.size();
535 for(
int i = 0; i < Lsize; ++i )
537 BoundaryGraph.ExtractMyRowView( LevelIndices[i], theNumIndices, theIndices );
541 for(
int j = 0; j < theNumIndices; ++j )
543 color = OverlapBoundaryColoring[ theIndices[j] ];
544 if( color > 0 ) usedColors.insert( color );
549 if( !usedColors.count( testcolor ) ) color = testcolor;
553 OverlapBoundaryColoring[ LevelIndices[i] ] = color;
554 levelColors.insert( color );
557 if( verbosity_ > 2 ) std::cout << MyPID <<
" Level: " << Level <<
" Count: " << LevelIndices.size() <<
" NumColors: " << levelColors.size() << std::endl;
559 if( verbosity_ > 2 ) std::cout <<
"Current Level Boundary Coloring:\n" << OverlapBoundaryColoring;
562 BoundaryColoring.Import( OverlapBoundaryColoring, ReverseOverlapBoundaryImport,
Insert );
563 OverlapBoundaryColoring.Import( BoundaryColoring, OverlapBoundaryImport,
Insert );
564 Colored += LevelIndices.size();
567 RowMap.Comm().SumAll( &Colored, &GlobalColored, 1 );
568 if( verbosity_ > 2 ) std::cout <<
"Num Globally Colored: " << GlobalColored <<
" from Num Global Boundary Nodes: " << BoundarySize << std::endl;
572 if( verbosity_ > 1 ) std::cout <<
"BoundaryColoring:\n " << BoundaryColoring;
577 for(
int i = 0; i < LocalBoundarySize; ++i )
579 int_type GID = (int_type) BoundaryMap.GID64(i);
580 RowColorMap(GID) = BoundaryColoring(GID);
585 Adj2ColColorMap.Import( RowColorMap, Adj2Import,
Insert );
587 if( verbosity_ > 1 ) std::cout <<
"RowColoringMap:\n " << RowColorMap;
588 if( verbosity_ > 1 ) std::cout <<
"Adj2ColColorMap:\n " << Adj2ColColorMap;
590 std::vector<int> rowOrder( nRows );
591 if( reordering_ == 0 || reordering_ == 1 )
593 std::multimap<int,int> adjMap;
594 typedef std::multimap<int,int>::value_type adjMapValueType;
595 for(
int i = 0; i < nRows; ++i )
596 adjMap.insert( adjMapValueType( Adj2->
NumMyIndices(i), i ) );
597 std::multimap<int,int>::iterator
iter = adjMap.begin();
598 std::multimap<int,int>::iterator
end = adjMap.end();
599 if( reordering_ == 0 )
601 for(
int i = 1; iter !=
end; ++
iter, ++i )
602 rowOrder[nRows-i] = (*iter).second;
606 for(
int i = 0; iter !=
end; ++
iter, ++i )
607 rowOrder[i] = (*iter).second;
610 else if( reordering_ == 2 )
612 for(
int i = 0; i < nRows; ++i )
615 std::random_device rd;
616 std::mt19937 g(rd());
617 std::shuffle( rowOrder.begin(), rowOrder.end(), g );
622 set<int> InteriorColors;
623 for(
int row = 0; row < nRows; ++row )
625 if( !RowColorMap[ rowOrder[row] ] )
631 for(
int i = 0; i < NumIndices; ++i )
633 color = Adj2ColColorMap[ Indices[i] ];
634 if( color > 0 ) usedColors.insert( color );
639 if( !usedColors.count( testcolor ) ) color = testcolor;
643 Adj2ColColorMap[ rowOrder[row] ] = color;
644 InteriorColors.insert( color );
647 if( verbosity_ > 1 ) std::cout << MyPID <<
" Num Interior Colors: " << InteriorColors.size() << std::endl;
648 if( verbosity_ > 1 ) std::cout <<
"RowColorMap after Greedy:\n " << RowColorMap;
652 ColorMap->Import( Adj2ColColorMap, ColImport,
Insert );
654 if( !distance1_ )
delete Adj2;
657 if( verbosity_ > 0 ) std::cout << MyPID <<
" ColorMap Color Count: " << ColorMap->
NumColors() << std::endl;
658 if( verbosity_ > 1 ) std::cout <<
"ColorMap!\n" << *ColorMap;
669 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
670 if(orig.RowMap().GlobalIndicesInt()) {
671 return Toperator<int>(orig);
675 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
676 if(orig.RowMap().GlobalIndicesLongLong()) {
677 return Toperator<long long>(orig);
681 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)