//============================================================================ Epetra_CrsGraph* Ifpack_CreateOverlappingCrsMatrix(const Epetra_CrsGraph* Graph, const int OverlappingLevel) { if (OverlappingLevel == 0) return(0); // All done if (Graph->Comm().NumProc() == 1) return(0); // All done Epetra_CrsGraph* OverlappingGraph; Epetra_BlockMap* OverlappingMap; OverlappingGraph = const_cast<Epetra_CrsGraph*>(Graph); OverlappingMap = const_cast<Epetra_BlockMap*>(&(Graph->RowMap())); Epetra_CrsGraph* OldGraph; Epetra_BlockMap* OldMap; const Epetra_BlockMap* DomainMap = &(Graph->DomainMap()); const Epetra_BlockMap* RangeMap = &(Graph->RangeMap()); for (int level = 1; level <= OverlappingLevel ; ++level) { OldGraph = OverlappingGraph; OldMap = OverlappingMap; Epetra_Import* OverlappingImporter; OverlappingImporter = const_cast<Epetra_Import*>(OldGraph->Importer()); OverlappingMap = new Epetra_BlockMap(OverlappingImporter->TargetMap()); if (level < OverlappingLevel) OverlappingGraph = new Epetra_CrsGraph(Copy, *OverlappingMap, 0); else // On last iteration, we want to filter out all columns except // those that correspond // to rows in the graph. This assures that our matrix is square OverlappingGraph = new Epetra_CrsGraph(Copy, *OverlappingMap, *OverlappingMap, 0); OverlappingGraph->Import(*OldGraph, *OverlappingImporter, Insert); if (level < OverlappingLevel) OverlappingGraph->FillComplete(*DomainMap, *RangeMap); else { // Copy last OverlapImporter because we will use it later OverlappingImporter = new Epetra_Import(*OverlappingMap, *DomainMap); OverlappingGraph->FillComplete(*DomainMap, *RangeMap); } if (level > 1) { delete OldGraph; delete OldMap; } delete OverlappingMap; OverlappingGraph->FillComplete(); } return(OverlappingGraph); }
Zoltan_CrsGraph::NewTypeRef Zoltan_CrsGraph:: operator()( OriginalTypeRef orig ) { origObj_ = &orig; int err; //Setup Load Balance Object float version; char * dummy = 0; Zoltan::LoadBalance LB( 0, &dummy, &version ); err = LB.Create( dynamic_cast<const Epetra_MpiComm&>(orig.Comm()).Comm() ); if( err == ZOLTAN_OK ) err = LB.Set_Param( "LB_METHOD", "GRAPH" ); #ifdef HAVE_LIBPARMETIS if( err == ZOLTAN_OK ) err = LB.Set_Param( "GRAPH_PACKAGE", "PARMETIS" ); if( err == ZOLTAN_OK ) err = LB.Set_Param( "PARMETIS_METHOD", partitionMethod_ ); #endif //Setup Query Object CrsGraph_Transpose transposeTransform; Epetra_CrsGraph & TransGraph = transposeTransform( orig ); ZoltanQuery Query( orig, &TransGraph ); if( err == ZOLTAN_OK ) err = LB.Set_QueryObject( &Query ); if( err != ZOLTAN_OK ) { cout << "Setup of Zoltan Load Balancing Objects FAILED!\n"; exit(0); } //Generate Load Balance int changes; int num_gid_entries, num_lid_entries; int num_import; ZOLTAN_ID_PTR import_global_ids, import_local_ids; int * import_procs; int num_export; ZOLTAN_ID_PTR export_global_ids, export_local_ids; int * export_procs; orig.Comm().Barrier(); err = LB.Balance( &changes, &num_gid_entries, &num_lid_entries, &num_import, &import_global_ids, &import_local_ids, &import_procs, &num_export, &export_global_ids, &export_local_ids, &export_procs ); LB.Evaluate( 1, 0, 0, 0, 0, 0, 0 ); orig.Comm().Barrier(); //Generate New Element List int numMyElements = orig.RowMap().NumMyElements(); vector<int> elementList( numMyElements ); orig.RowMap().MyGlobalElements( &elementList[0] ); int newNumMyElements = numMyElements - num_export + num_import; vector<int> newElementList( newNumMyElements ); set<int> gidSet; for( int i = 0; i < num_export; ++i ) gidSet.insert( export_global_ids[i] ); //Add unmoved indices to new list int loc = 0; for( int i = 0; i < numMyElements; ++i ) if( !gidSet.count( elementList[i] ) ) newElementList[loc++] = elementList[i]; //Add imports to end of list for( int i = 0; i < num_import; ++i ) newElementList[loc+i] = import_global_ids[i]; //Free Zoltan Data if( err == ZOLTAN_OK ) err = LB.Free_Data( &import_global_ids, &import_local_ids, &import_procs, &export_global_ids, &export_local_ids, &export_procs ); //Create Import Map NewRowMap_ = new Epetra_Map( orig.RowMap().NumGlobalElements(), newNumMyElements, &newElementList[0], orig.RowMap().IndexBase(), orig.RowMap().Comm() ); //Create Importer Epetra_Import Importer( *NewRowMap_, orig.RowMap() ); //Create New Graph Epetra_CrsGraph * NewGraph = new Epetra_CrsGraph( Copy, *NewRowMap_, 0 ); NewGraph->Import( orig, Importer, Insert ); NewGraph->FillComplete(); Zoltan::LoadBalance LB2( 0, &dummy, &version ); err = LB2.Create( dynamic_cast<const Epetra_MpiComm&>(orig.Comm()).Comm() ); if( err == ZOLTAN_OK ) err = LB2.Set_Param( "LB_METHOD", "GRAPH" ); #ifdef HAVE_LIBPARMETIS if( err == ZOLTAN_OK ) err = LB2.Set_Param( "GRAPH_PACKAGE", "PARMETIS" ); if( err == ZOLTAN_OK ) err = LB2.Set_Param( "PARMETIS_METHOD", partitionMethod_ ); #endif CrsGraph_Transpose transTrans; Epetra_CrsGraph & trans2 = transTrans( *NewGraph ); ZoltanQuery query( *NewGraph, &trans2 ); if( err == ZOLTAN_OK ) err = LB2.Set_QueryObject( &query ); //err = LB2.Balance( &changes, // &num_gid_entries, &num_lid_entries, // &num_import, &import_global_ids, &import_local_ids, &import_procs, // &num_export, &export_global_ids, &export_local_ids, &export_procs ); LB2.Evaluate( 1, 0, 0, 0, 0, 0, 0 ); newObj_ = NewGraph; return *NewGraph; }
CrsGraph_SymmRCM::NewTypeRef CrsGraph_SymmRCM:: operator()( CrsGraph_SymmRCM::OriginalTypeRef orig ) { origObj_ = &orig; int err; //Generate Local Transpose Graph CrsGraph_Transpose transposeTransform; Epetra_CrsGraph & trans = transposeTransform( orig ); //Generate Local Symmetric Adj. List //Find Min Degree Node While at it int NumNodes = orig.NumMyRows(); int * LocalRow; int * LocalRowTrans; int RowSize, RowSizeTrans; std::vector< std::vector<int> > AdjList( NumNodes ); int MinDegree = NumNodes; int MinDegreeNode; for( int i = 0; i < NumNodes; ++i ) { orig.ExtractMyRowView( i, RowSize, LocalRow ); trans.ExtractMyRowView( i, RowSizeTrans, LocalRowTrans ); std::set<int> adjSet; for( int j = 0; j < RowSize; ++j ) if( LocalRow[j] < NumNodes ) adjSet.insert( LocalRow[j] ); for( int j = 0; j < RowSizeTrans; ++j ) if( LocalRowTrans[j] < NumNodes ) adjSet.insert( LocalRowTrans[j] ); std::set<int>::iterator iterS = adjSet.begin(); std::set<int>::iterator endS = adjSet.end(); AdjList[i].resize( adjSet.size() ); for( int j = 0; iterS != endS; ++iterS, ++j ) AdjList[i][j] = *iterS; if( AdjList[i].size() < MinDegree ) { MinDegree = AdjList[i].size(); MinDegreeNode = i; } } BFT * BestBFT; bool TooWide; //std::cout << "SymmRCM::bruteForce_ : " << bruteForce_ << std::endl; if( bruteForce_ ) { int bestWidth = NumNodes; int bestDepth = 0; for( int i = 0; i < NumNodes; ++i ) { BFT * TestBFT = new BFT( AdjList, i, NumNodes, TooWide ); if( TestBFT->Depth() > bestDepth || ( TestBFT->Depth() == bestDepth && TestBFT->Width() < bestWidth ) ) { BestBFT = TestBFT; bestDepth = TestBFT->Depth(); bestWidth = TestBFT->Width(); } else delete TestBFT; } } else { //Construct BFT for first BestBFT = new BFT( AdjList, MinDegreeNode, NumNodes, TooWide ); int MinWidth = BestBFT->Width(); int BestWidth = MinWidth; int Diameter = BestBFT->Depth(); std::vector<int> Leaves; BestBFT->NonNeighborLeaves( Leaves, AdjList, testLeafWidth_ ); bool DeeperFound; bool NarrowerFound; bool Finished = false; while( !Finished ) { DeeperFound = false; NarrowerFound = false; for( int i = 0; i < Leaves.size(); ++i ) { BFT * TestBFT = new BFT( AdjList, Leaves[i], MinWidth, TooWide ); if( TooWide ) delete TestBFT; else { if( TestBFT->Width() < MinWidth ) MinWidth = TestBFT->Width(); if( TestBFT->Depth() > Diameter ) { delete BestBFT; Diameter = TestBFT->Depth(); BestWidth = TestBFT->Width(); BestBFT = TestBFT; DeeperFound = true; NarrowerFound = false; } else if( (TestBFT->Depth()==Diameter) && (TestBFT->Width()<BestWidth) ) { delete BestBFT; BestWidth = TestBFT->Width(); BestBFT = TestBFT; NarrowerFound = true; } else delete TestBFT; } } if( DeeperFound ) BestBFT->NonNeighborLeaves( Leaves, AdjList, testLeafWidth_ ); else if( NarrowerFound ) Finished = true; else Finished = true; } } //std::cout << "\nSymmRCM:\n"; //std::cout << "----------------------------\n"; //std::cout << " Depth: " << BestBFT->Depth() << std::endl; //std::cout << " Width: " << BestBFT->Width() << std::endl; //std::cout << "----------------------------\n\n"; std::vector<int> RCM; BestBFT->ReverseVector( RCM ); for( int i = 0; i < NumNodes; ++i ) RCM[i] = orig.RowMap().GID( RCM[i] ); //Generate New Row Map RCMMap_ = new Epetra_Map( orig.RowMap().NumGlobalElements(), NumNodes, &RCM[0], orig.RowMap().IndexBase(), orig.RowMap().Comm() ); //Generate New Col Map if( RCMMap_->DistributedGlobal() ) { std::vector<int> colIndices = RCM; const Epetra_BlockMap & origColMap = orig.ColMap(); if( origColMap.NumMyElements() > RCMMap_->NumMyElements() ) { for( int i = RCMMap_->NumMyElements(); i < origColMap.NumMyElements(); ++i ) colIndices.push_back( origColMap.GID(i) ); } RCMColMap_ = new Epetra_Map( orig.ColMap().NumGlobalElements(), colIndices.size(), &colIndices[0], orig.ColMap().IndexBase(), orig.ColMap().Comm() ); } else RCMColMap_ = RCMMap_; //Create New Graph Epetra_Import Importer( *RCMMap_, orig.RowMap() ); Epetra_CrsGraph * RCMGraph = new Epetra_CrsGraph( Copy, *RCMMap_, *RCMColMap_, 0 ); RCMGraph->Import( orig, Importer, Insert ); RCMGraph->FillComplete(); /* std::cout << "origGraph\n"; std::cout << orig; std::cout << "RCMGraph\n"; std::cout << *RCMGraph; */ newObj_ = RCMGraph; return *RCMGraph; }