int compute_graph_metrics(const Epetra_CrsGraph &graph, Isorropia::Epetra::CostDescriber &costs, double &myGoalWeight, double &balance, int &numCuts, double &cutWgt, double &cutn, double &cutl) { const Epetra_BlockMap & rmap = graph.RowMap(); const Epetra_BlockMap & cmap = graph.ColMap(); int maxEdges = cmap.NumMyElements(); std::vector<std::vector<int> > myRows(rmap.NumMyElements()); if (maxEdges > 0){ int numEdges = 0; int *nborLID = new int [maxEdges]; for (int i=0; i<rmap.NumMyElements(); i++){ graph.ExtractMyRowCopy(i, maxEdges, numEdges, nborLID); std::vector<int> cols(numEdges); for (int j=0; j<numEdges; j++){ cols[j] = nborLID[j]; } myRows[i] = cols; } delete [] nborLID; } return compute_graph_metrics(rmap, cmap, myRows, costs, myGoalWeight, balance, numCuts, cutWgt, cutn, cutl); }
//============================================================================== BlockCrsMatrix::BlockCrsMatrix( const Epetra_CrsGraph & BaseGraph, const Epetra_CrsGraph & LocalBlockGraph, const Epetra_Comm & GlobalComm ) : Epetra_CrsMatrix( Copy, *(BlockUtility::GenerateBlockGraph( BaseGraph, LocalBlockGraph, GlobalComm )) ), BaseGraph_( BaseGraph ), #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES RowStencil_int_( ), RowIndices_int_( ), #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES RowStencil_LL_( ), RowIndices_LL_( ), #endif ROffset_(BlockUtility::CalculateOffset64(BaseGraph.RowMap())), COffset_(BlockUtility::CalculateOffset64(BaseGraph.ColMap())) { #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES if(Epetra_CrsMatrix::RowMatrixRowMap().GlobalIndicesInt() && LocalBlockGraph.RowMap().GlobalIndicesInt()) BlockUtility::GenerateRowStencil(LocalBlockGraph, RowIndices_int_, RowStencil_int_); else #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES if(Epetra_CrsMatrix::RowMatrixRowMap().GlobalIndicesLongLong() && LocalBlockGraph.RowMap().GlobalIndicesLongLong()) BlockUtility::GenerateRowStencil(LocalBlockGraph, RowIndices_LL_, RowStencil_LL_); else #endif throw "EpetraExt::BlockCrsMatrix::BlockCrsMatrix: Error, Global indices unknown."; }
//EpetraCrsMatrix_To_TpetraCrsMatrix: copies Epetra_CrsMatrix to its analogous Tpetra_CrsMatrix Teuchos::RCP<Tpetra_CrsMatrix> Petra::EpetraCrsMatrix_To_TpetraCrsMatrix(const Epetra_CrsMatrix& epetraCrsMatrix_, const Teuchos::RCP<const Teuchos::Comm<int> >& commT_) { //get row map of Epetra::CrsMatrix & convert to Tpetra::Map auto tpetraRowMap_ = EpetraMap_To_TpetraMap(epetraCrsMatrix_.RowMap(), commT_); //get col map of Epetra::CrsMatrix & convert to Tpetra::Map auto tpetraColMap_ = EpetraMap_To_TpetraMap(epetraCrsMatrix_.ColMap(), commT_); //get CrsGraph of Epetra::CrsMatrix & convert to Tpetra::CrsGraph const Epetra_CrsGraph epetraCrsGraph_ = epetraCrsMatrix_.Graph(); std::size_t maxEntries = epetraCrsGraph_.GlobalMaxNumIndices(); Teuchos::RCP<Tpetra_CrsGraph> tpetraCrsGraph_ = Teuchos::rcp(new Tpetra_CrsGraph(tpetraRowMap_, tpetraColMap_, maxEntries)); for (LO i=0; i<epetraCrsGraph_.NumMyRows(); i++) { LO NumEntries; LO *Indices; epetraCrsGraph_.ExtractMyRowView(i, NumEntries, Indices); tpetraCrsGraph_->insertLocalIndices(i, NumEntries, Indices); } tpetraCrsGraph_->fillComplete(); //convert Epetra::CrsMatrix to Tpetra::CrsMatrix, after creating Tpetra::CrsMatrix based on above Tpetra::CrsGraph Teuchos::RCP<Tpetra_CrsMatrix> tpetraCrsMatrix_ = Teuchos::rcp(new Tpetra_CrsMatrix(tpetraCrsGraph_)); tpetraCrsMatrix_->setAllToScalar(0.0); for (LO i=0; i<epetraCrsMatrix_.NumMyRows(); i++) { LO NumEntries; LO *Indices; ST *Values; epetraCrsMatrix_.ExtractMyRowView(i, NumEntries, Values, Indices); tpetraCrsMatrix_->replaceLocalValues(i, NumEntries, Values, Indices); } tpetraCrsMatrix_->fillComplete(); return tpetraCrsMatrix_; }
//----------------------------------------------------------------------------- // Function : Indexor::setupAcceleratedMatrixIndexing // Purpose : // Special Notes : // Scope : public // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences // Creation Date : 08/23/02 //----------------------------------------------------------------------------- bool Indexor::setupAcceleratedMatrixIndexing( const std::string & graph_name ) { Epetra_CrsGraph * graph = 0; assert( pdsMgr_ != 0 ); // Never, EVER do work inside an assert argument, or that work will not // be done when asserts are disabled. graph = pdsMgr_->getMatrixGraph( graph_name ); assert( graph != 0 ); int NumRows = graph->NumMyRows(); matrixIndexMap_.clear(); matrixIndexMap_.resize( NumRows ); int NumElements; int * Elements; for( int i = 0; i < NumRows; ++i ) { graph->ExtractMyRowView( i, NumElements, Elements ); for( int j = 0; j < NumElements; ++j ) matrixIndexMap_[i][ Elements[j] ] = j; } accelMatrixIndex_ = true; return true; }
int compute_hypergraph_metrics(const Epetra_CrsGraph &graph, Isorropia::Epetra::CostDescriber &costs, double &myGoalWeight, double &balance, double &cutn, double &cutl) // output { return compute_hypergraph_metrics(graph.RowMap(), graph.ColMap(), graph.NumGlobalCols(), costs, myGoalWeight, balance, cutn, cutl); }
//============================================================================== // Epetra_OffsetIndex constructor from Importer Epetra_OffsetIndex::Epetra_OffsetIndex( const Epetra_CrsGraph & SourceGraph, const Epetra_CrsGraph & TargetGraph, Epetra_Import & Importer ) : Epetra_Object("Epetra::OffsetIndex"), NumSame_(0), SameOffsets_(0), NumPermute_(0), PermuteOffsets_(0), NumExport_(0), NumRemote_(0), RemoteOffsets_(0), DataOwned_(true) { NumSame_ = Importer.NumSameIDs(); NumPermute_ = Importer.NumPermuteIDs(); int * PermuteLIDs = Importer.PermuteToLIDs(); NumExport_ = Importer.NumExportIDs(); int * ExportLIDs = Importer.ExportLIDs(); NumRemote_ = Importer.NumRemoteIDs(); int * RemoteLIDs = Importer.RemoteLIDs(); if(!SourceGraph.RowMap().GlobalIndicesTypeMatch(TargetGraph.RowMap())) throw ReportError("Epetra_OffsetIndex::Epetra_OffsetIndex: SourceGraph and TargetGraph global indices type mismatch", -1); if(SourceGraph.RowMap().GlobalIndicesInt()) { #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES GenerateLocalOffsets_<int>( SourceGraph, TargetGraph, PermuteLIDs ); GenerateRemoteOffsets_<int>( SourceGraph, TargetGraph, ExportLIDs, RemoteLIDs, Importer.Distributor() ); #else throw ReportError("Epetra_OffsetIndex::Epetra_OffsetIndex: ERROR, GlobalIndicesInt but no API for it.",-1); #endif } else if(SourceGraph.RowMap().GlobalIndicesLongLong()) { #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES GenerateLocalOffsets_<long long>( SourceGraph, TargetGraph, PermuteLIDs ); GenerateRemoteOffsets_<long long>( SourceGraph, TargetGraph, ExportLIDs, RemoteLIDs, Importer.Distributor() ); #else throw ReportError("Epetra_OffsetIndex::Epetra_OffsetIndex: ERROR, GlobalIndicesLongLong but no API for it.",-1); #endif } else throw ReportError("Epetra_OffsetIndex::Epetra_OffsetIndex: SourceGraph global indices type unknown", -1); }
BlockCrsMatrix::BlockCrsMatrix( const Epetra_CrsGraph & BaseGraph, const vector<int> & RowStencil, int RowIndex, const Epetra_Comm & GlobalComm ) : Epetra_CrsMatrix( Copy, *(BlockUtility::GenerateBlockGraph( BaseGraph, vector< vector<int> >(1,RowStencil), vector<int>(1,RowIndex), GlobalComm )) ), BaseGraph_( BaseGraph ), RowStencil_int_( vector< vector<int> >(1,RowStencil) ), RowIndices_int_( vector<int>(1,RowIndex) ), ROffset_(BlockUtility::CalculateOffset64(BaseGraph.RowMap())), COffset_(BlockUtility::CalculateOffset64(BaseGraph.ColMap())) { }
BlockCrsMatrix::BlockCrsMatrix( const Epetra_CrsGraph & BaseGraph, const vector< vector<long long> > & RowStencil, const vector<long long> & RowIndices, const Epetra_Comm & GlobalComm ) : Epetra_CrsMatrix( Copy, *(BlockUtility::GenerateBlockGraph( BaseGraph, RowStencil, RowIndices, GlobalComm )) ), BaseGraph_( BaseGraph ), RowStencil_LL_( RowStencil ), RowIndices_LL_( RowIndices ), ROffset_(BlockUtility::CalculateOffset64(BaseGraph.RowMap())), COffset_(BlockUtility::CalculateOffset64(BaseGraph.ColMap())) { }
void BlockUtility::TGenerateRowStencil(const Epetra_CrsGraph& LocalBlockGraph, std::vector<int_type> RowIndices, std::vector< std::vector<int_type> >& RowStencil) { // Get row indices int NumMyRows = LocalBlockGraph.NumMyRows(); RowIndices.resize(NumMyRows); const Epetra_BlockMap& RowMap = LocalBlockGraph.RowMap(); RowMap.MyGlobalElements(&RowIndices[0]); // Get stencil RowStencil.resize(NumMyRows); if (LocalBlockGraph.IndicesAreGlobal()) { for (int i=0; i<NumMyRows; i++) { int_type Row = RowIndices[i]; int NumCols = LocalBlockGraph.NumGlobalIndices(Row); RowStencil[i].resize(NumCols); LocalBlockGraph.ExtractGlobalRowCopy(Row, NumCols, NumCols, &RowStencil[i][0]); for (int k=0; k<NumCols; k++) RowStencil[i][k] -= Row; } } else { for (int i=0; i<NumMyRows; i++) { int NumCols = LocalBlockGraph.NumMyIndices(i); std::vector<int> RowStencil_local(NumCols); RowStencil[i].resize(NumCols); LocalBlockGraph.ExtractMyRowCopy(i, NumCols, NumCols, &RowStencil_local[0]); for (int k=0; k<NumCols; k++) RowStencil[i][k] = (int_type) ((int) (LocalBlockGraph.GCID64(RowStencil_local[k]) - RowIndices[i])); } } }
OffBlock_Manager::OffBlock_Manager(Problem_Manager& problemMan_, Epetra_CrsGraph& graph_, int probEqId, int probVarId) : GenericEpetraProblem(graph_.Comm(), 0), problemEqId(probEqId), problemVarId(probVarId) { setManager(&problemMan_); // Assign a meaningful name GenericEpetraProblem &problemEq = myManager->getProblem(problemEqId), &problemVar = myManager->getProblem(problemVarId); string myName = "OffBlock " + problemEq.getName() + " wrt " + problemVar.getName(); setName(myName); // Set our graph (held in base class) after converting from incoming // global indices to shifted block indices AA = Teuchos::rcp( &( createBlockGraphFromComposite(graph_) ) ); // Create a problem interface to the manager offBlockInterface = Teuchos::rcp(new Problem_Interface(*this)); // Use our graph to create FDC objects needed for off-diagonal block fills createFDobjects( true ); // Reset number of dofs (overwrites base constructor assignment) NumMyNodes = 0; }
void Epetra_OffsetIndex::GenerateLocalOffsets_( const Epetra_CrsGraph & SourceGraph, const Epetra_CrsGraph & TargetGraph, const int * PermuteLIDs ) { const int GlobalMaxNumSourceIndices = SourceGraph.GlobalMaxNumIndices(); int NumSourceIndices; int_type * SourceIndices = 0; if( GlobalMaxNumSourceIndices>0 ) SourceIndices = new int_type[GlobalMaxNumSourceIndices]; //setup Same Offsets SameOffsets_ = new int*[NumSame_]; for( int i = 0; i < NumSame_; ++i ) SameOffsets_[i] = 0; for( int i = 0; i < NumSame_; ++i ) { int_type GID = (int_type) SourceGraph.GRID64(i); SourceGraph.ExtractGlobalRowCopy( GID, GlobalMaxNumSourceIndices, NumSourceIndices, SourceIndices ); if( NumSourceIndices > 0 ) SameOffsets_[i] = new int[NumSourceIndices]; int Loc = 0; int Start = 0; for( int j = 0; j < NumSourceIndices; ++j ) { Start = Loc; if( TargetGraph.FindGlobalIndexLoc(i,SourceIndices[j],Start,Loc) ) SameOffsets_[i][j] = Loc; else SameOffsets_[i][j] = -1; } } //do also for permuted ids PermuteOffsets_ = new int*[NumPermute_]; for( int i = 0; i < NumPermute_; ++i ) PermuteOffsets_[i] = 0; for( int i = 0; i < NumPermute_; ++i ) { int_type GID = (int_type) SourceGraph.GRID64(PermuteLIDs[i]); SourceGraph.ExtractGlobalRowCopy( GID, GlobalMaxNumSourceIndices, NumSourceIndices, SourceIndices ); if( NumSourceIndices > 0 ) PermuteOffsets_[i] = new int[NumSourceIndices]; int Loc = 0; int Start = 0; for( int j = 0; j < NumSourceIndices; ++j ) { Start = Loc; if( TargetGraph.FindGlobalIndexLoc(PermuteLIDs[i],SourceIndices[j],Start,Loc) ) PermuteOffsets_[i][j] = Loc; else PermuteOffsets_[i][j] = -1; } } if( GlobalMaxNumSourceIndices>0 ) delete [] SourceIndices; }
void BlockUtility::GenerateRowStencil(const Epetra_CrsGraph& LocalBlockGraph, std::vector<long long> RowIndices, std::vector< std::vector<long long> >& RowStencil) { if(LocalBlockGraph.RowMap().GlobalIndicesLongLong()) BlockUtility::TGenerateRowStencil<long long>(LocalBlockGraph, RowIndices, RowStencil); else throw "EpetraExt::BlockUtility::GenerateRowStencil: Global Indices not long long."; }
//============================================================================ 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); }
Stokhos::AdaptivityManager::AdaptivityManager( const Teuchos::RCP<const Stokhos::ProductBasis<int,double> >& sg_master_basis, const std::vector<Teuchos::RCP<const Stokhos::ProductBasis<int,double> > > & sg_basis_row_dof, const Epetra_CrsGraph & determ_graph, bool onlyUseLinear,int kExpOrder, bool scaleOp) : sg_master_basis_(sg_master_basis), sg_basis_row_dof_(sg_basis_row_dof), scaleOp_(scaleOp) { rowMap_ = adapt_utils::buildAdaptedRowMapAndOffsets(determ_graph.Comm(),sg_basis_row_dof_,myRowGidOffsets_); setupWithGraph(determ_graph,onlyUseLinear,kExpOrder); }
/*----------------------------------------------------------------------* | make a deep copy of a graph m.gee 01/05| | allocate the new graph | *----------------------------------------------------------------------*/ Epetra_CrsGraph* ML_NOX::deepcopy_graph(const Epetra_CrsGraph* oldgraph) { int i,ierr; int nrows = oldgraph->NumMyRows(); int* nIndicesperRow = new int[nrows]; for (i=0; i<nrows; i++) nIndicesperRow[i] = oldgraph->NumMyIndices(i); Epetra_CrsGraph* graph = new Epetra_CrsGraph(Copy,oldgraph->RowMap(),oldgraph->ColMap(), &(nIndicesperRow[0])); delete [] nIndicesperRow; nIndicesperRow = 0; for (i=0; i<nrows; i++) { int numIndices; int* Indices=0; ierr = oldgraph->ExtractMyRowView(i,numIndices,Indices); ierr = graph->InsertMyIndices(i,numIndices,Indices); } graph->FillComplete(); return graph; }
//----------------------------------------------------------------------------- // Function : Indexor::matrixGlobalToLocal // Purpose : // Special Notes : // Scope : public // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences // Creation Date : 08/23/02 //----------------------------------------------------------------------------- bool Indexor::matrixGlobalToLocal( const std::string & graph_name, const std::vector<int> & gids, std::vector< std::vector<int> > & stamp ) { Epetra_CrsGraph * graph = 0; assert( pdsMgr_ != 0 ); // Never, EVER do work inside an assert argument, or that work will not // be done when asserts are disabled. graph = pdsMgr_->getMatrixGraph( graph_name ); assert( graph != 0 ); int numRows = stamp.size(); int numElements; int * elements; if( accelMatrixIndex_ ) { for( int i = 0; i < numRows; ++i ) { int RowLID = graph->LRID(gids[i]); int NumCols = stamp[i].size(); for( int j = 0; j < NumCols; ++j ) { int lid = graph->LCID(stamp[i][j]); stamp[i][j] = matrixIndexMap_[RowLID][lid]; } } } else { for( int i = 0; i < numRows; ++i ) { graph->ExtractMyRowView( graph->LRID(gids[i]), numElements, elements ); std::map<int,int> indexToOffsetMap; for( int j = 0; j < numElements; ++j ) indexToOffsetMap[ elements[j] ] = j; int numCols = stamp[i].size(); for( int j = 0; j < numCols; ++j ) { int lid = graph->LCID(stamp[i][j]); // assert( indexToOffsetMap.count(lid) ); stamp[i][j] = indexToOffsetMap[lid]; } } } return true; }
//============================================================================== int Ifpack_CrsRiluk::BlockGraph2PointGraph(const Epetra_CrsGraph & BG, Epetra_CrsGraph & PG, bool Upper) { if (!BG.IndicesAreLocal()) {EPETRA_CHK_ERR(-1);} // Must have done FillComplete on BG int * ColFirstPointInElementList = BG.RowMap().FirstPointInElementList(); int * ColElementSizeList = BG.RowMap().ElementSizeList(); if (BG.Importer()!=0) { ColFirstPointInElementList = BG.ImportMap().FirstPointInElementList(); ColElementSizeList = BG.ImportMap().ElementSizeList(); } int Length = (BG.MaxNumIndices()+1) * BG.ImportMap().MaxMyElementSize(); vector<int> tmpIndices(Length); int BlockRow, BlockOffset, NumEntries; int NumBlockEntries; int * BlockIndices; int NumMyRows_tmp = PG.NumMyRows(); for (int i=0; i<NumMyRows_tmp; i++) { EPETRA_CHK_ERR(BG.RowMap().FindLocalElementID(i, BlockRow, BlockOffset)); EPETRA_CHK_ERR(BG.ExtractMyRowView(BlockRow, NumBlockEntries, BlockIndices)); int * ptr = &tmpIndices[0]; // Set pointer to beginning of buffer int RowDim = BG.RowMap().ElementSize(BlockRow); NumEntries = 0; // This next line make sure that the off-diagonal entries in the block diagonal of the // original block entry matrix are included in the nonzero pattern of the point graph if (Upper) { int jstart = i+1; int jstop = EPETRA_MIN(NumMyRows_tmp,i+RowDim-BlockOffset); for (int j= jstart; j< jstop; j++) {*ptr++ = j; NumEntries++;} } for (int j=0; j<NumBlockEntries; j++) { int ColDim = ColElementSizeList[BlockIndices[j]]; NumEntries += ColDim; assert(NumEntries<=Length); // Sanity test int Index = ColFirstPointInElementList[BlockIndices[j]]; for (int k=0; k < ColDim; k++) *ptr++ = Index++; } // This next line make sure that the off-diagonal entries in the block diagonal of the // original block entry matrix are included in the nonzero pattern of the point graph if (!Upper) { int jstart = EPETRA_MAX(0,i-RowDim+1); int jstop = i; for (int j = jstart; j < jstop; j++) {*ptr++ = j; NumEntries++;} } EPETRA_CHK_ERR(PG.InsertMyIndices(i, NumEntries, &tmpIndices[0])); } SetAllocated(true); return(0); }
void BroydenOperator::removeEntriesFromBroydenUpdate( const Epetra_CrsGraph & graph ) { int numRemoveIndices ; int * removeIndPtr ; int ierr ; cout << graph << endl; for( int row = 0; row < graph.NumMyRows(); ++row) { ierr = graph.ExtractMyRowView( row, numRemoveIndices, removeIndPtr ); if( ierr ) { cout << "ERROR (" << ierr << ") : " << "NOX::Epetra::BroydenOperator::removeEntriesFromBroydenUpdate(...)" << " - Extract indices error for row --> " << row << endl; throw "NOX Broyden Operator Error"; } if( 0 != numRemoveIndices ) { // Create a map for quick queries map<int, bool> removeIndTable; for( int k = 0; k < numRemoveIndices; ++k ) removeIndTable[ graph.ColMap().GID(removeIndPtr[k]) ] = true; // Get our matrix column indices for the current row int numOrigIndices = 0; int * indPtr; ierr = crsMatrix->Graph().ExtractMyRowView( row, numOrigIndices, indPtr ); if( ierr ) { cout << "ERROR (" << ierr << ") : " << "NOX::Epetra::BroydenOperator::removeEntriesFromBroydenUpdate(...)" << " - Extract indices error for row --> " << row << endl; throw "NOX Broyden Operator Error"; } // Remove appropriate active entities if( retainedEntries.end() == retainedEntries.find(row) ) { list<int> inds; for( int k = 0; k < numOrigIndices; ++k ) { if( removeIndTable.end() == removeIndTable.find( crsMatrix->Graph().ColMap().GID(indPtr[k]) ) ) inds.push_back(k); } retainedEntries[row] = inds; } else { list<int> & inds = retainedEntries[row]; list<int>::iterator iter = inds.begin() , iter_end = inds.end() ; for( ; iter_end != iter; ++iter ) { if( !removeIndTable[ *iter ] ) inds.remove( *iter ); } } entriesRemoved[row] = true; } } return; }
Teuchos::RCP<Epetra_CrsGraph> BlockAdjacencyGraph::compute( Epetra_CrsGraph& B, int nbrr, std::vector<int>&r, std::vector<double>& weights, bool verbose) { // Check if the graph is on one processor. int myMatProc = -1, matProc = -1; int myPID = B.Comm().MyPID(); for (int proc=0; proc<B.Comm().NumProc(); proc++) { if (B.NumGlobalEntries() == B.NumMyEntries()) myMatProc = myPID; } B.Comm().MaxAll( &myMatProc, &matProc, 1 ); if( matProc == -1) { cout << "FAIL for Global! All CrsGraph entries must be on one processor!\n"; abort(); } int i= 0, j = 0, k, l = 0, p, pm, q = -1, ns; int tree_height; int error = -1; /* error detected, possibly a problem with the input */ int nrr; /* number of rows in B */ int nzM = 0; /* number of edges in graph */ int m = 0; /* maximum number of nonzeros in any block row of B */ int* colstack = 0; /* stack used to process each block row */ int* bstree = 0; /* binary search tree */ std::vector<int> Mi, Mj, Mnum(nbrr+1,0); nrr = B.NumMyRows(); if ( matProc == myPID && verbose ) std::printf(" Matrix Size = %d Number of Blocks = %d\n",nrr, nbrr); else nrr = -1; /* Prevent processor from doing any computations */ bstree = csr_bst(nbrr); /* 0 : nbrr-1 */ tree_height = ceil31log2(nbrr) + 1; error = -1; l = 0; j = 0; m = 0; for( i = 0; i < nrr; i++ ){ if( i >= r[l+1] ){ ++l; /* new block row */ m = EPETRA_MAX(m,j) ; /* nonzeros in block row */ j = B.NumGlobalIndices(i); }else{ j += B.NumGlobalIndices(i); } } /* one more time for the final block */ m = EPETRA_MAX(m,j) ; /* nonzeros in block row */ colstack = (int*) malloc( EPETRA_MAX(m,1) * sizeof(int) ); // The compressed graph is actually computed twice, // due to concerns about memory limitations. First, // without memory allocation, just nzM is computed. // Next Mj is allocated. Then, the second time, the // arrays are actually populated. nzM = 0; q = -1; l = 0; int * indices; int numEntries; for( i = 0; i <= nrr; i++ ){ if( i >= r[l+1] ){ if( q > 0 ) std::qsort(colstack,q+1,sizeof(int),compare_ints); /* sort stack */ if( q >= 0 ) ns = 1; /* l, colstack[0] M */ for( j=1; j<=q ; j++ ){ /* delete copies */ if( colstack[j] > colstack[j-1] ) ++ns; } nzM += ns; /*M->p[l+1] = M->p[l] + ns;*/ ++l; q = -1; } if( i < nrr ){ B.ExtractMyRowView( i, numEntries, indices ); for( k = 0; k < numEntries; k++){ j = indices[k]; ns = 0; p = 0; while( (r[bstree[p]] > j) || (j >= r[bstree[p]+1]) ){ if( r[bstree[p]] > j){ p = 2*p+1; }else{ if( r[bstree[p]+1] <= j) p = 2*p+2; } ++ns; if( p > nbrr || ns > tree_height ) { error = j; std::printf("error: p %d nbrr %d ns %d %d\n",p,nbrr,ns,j); break; } } colstack[++q] = bstree[p]; } //if( error >-1 ){ std::printf("%d\n",error); break; } // p > nbrr is a fatal error that is ignored } } if ( matProc == myPID && verbose ) std::printf("nzM = %d \n", nzM ); Mi.resize( nzM ); Mj.resize( nzM ); q = -1; l = 0; pm = -1; for( i = 0; i <= nrr; i++ ){ if( i >= r[l+1] ){ if( q > 0 ) std::qsort(colstack,q+1,sizeof(colstack[0]),compare_ints); /* sort stack */ if( q >= 0 ){ Mi[++pm] = l; Mj[pm] = colstack[0]; } for( j=1; j<=q ; j++ ){ /* delete copies */ if( colstack[j] > colstack[j-1] ){ /* l, colstack[j] */ Mi[++pm] = l; Mj[pm] = colstack[j]; } } ++l; Mnum[l] = pm + 1; /* sparse row format: M->p[l+1] = M->p[l] + ns; */ q = -1; } if( i < nrr ){ B.ExtractMyRowView( i, numEntries, indices ); for( k = 0; k < numEntries; k++){ j = indices[k]; ns = 0; p = 0; while( (r[bstree[p]] > j) || (j >= r[bstree[p]+1]) ){ if( r[bstree[p]] > j){ p = 2*p+1; }else{ if( r[bstree[p]+1] <= j) p = 2*p+2; } ++ns; } colstack[++q] = bstree[p]; } } } if ( bstree ) free ( bstree ); if ( colstack ) free( colstack ); // Compute weights as number of rows in each block. weights.resize( nbrr ); for( l=0; l<nbrr; l++) weights[l] = r[l+1] - r[l]; // Compute Epetra_CrsGraph and return Teuchos::RCP<Epetra_Map> newMap; if ( matProc == myPID ) newMap = Teuchos::rcp( new Epetra_Map(nbrr, nbrr, 0, B.Comm() ) ); else newMap = Teuchos::rcp( new Epetra_Map( nbrr, 0, 0, B.Comm() ) ); Teuchos::RCP<Epetra_CrsGraph> newGraph = Teuchos::rcp( new Epetra_CrsGraph( Copy, *newMap, 0 ) ); for( l=0; l<newGraph->NumMyRows(); l++) { newGraph->InsertGlobalIndices( l, Mnum[l+1]-Mnum[l], &Mj[Mnum[l]] ); } newGraph->FillComplete(); return (newGraph); }
int check(Epetra_CrsGraph& L, Epetra_CrsGraph& U, Ifpack_IlukGraph& LU, int NumGlobalRows1, int NumMyRows1, int LevelFill1, bool verbose) { using std::cout; using std::endl; int i, j; int NumIndices, * Indices; int NumIndices1, * Indices1; bool debug = true; Epetra_CrsGraph& L1 = LU.L_Graph(); Epetra_CrsGraph& U1 = LU.U_Graph(); // Test entries and count nonzeros int Nout = 0; for (i=0; i<LU.NumMyRows(); i++) { assert(L.ExtractMyRowView(i, NumIndices, Indices)==0); assert(L1.ExtractMyRowView(i, NumIndices1, Indices1)==0); assert(NumIndices==NumIndices1); for (j=0; j<NumIndices1; j++) { if (debug &&(Indices[j]!=Indices1[j])) { int MyPID = L.RowMap().Comm().MyPID(); cout << "Proc " << MyPID << " Local Row = " << i << " L.Indices["<< j <<"] = " << Indices[j] << " L1.Indices["<< j <<"] = " << Indices1[j] << endl; } assert(Indices[j]==Indices1[j]); } Nout += (NumIndices-NumIndices1); assert(U.ExtractMyRowView(i, NumIndices, Indices)==0); assert(U1.ExtractMyRowView(i, NumIndices1, Indices1)==0); assert(NumIndices==NumIndices1); for (j=0; j<NumIndices1; j++) { if (debug &&(Indices[j]!=Indices1[j])) { int MyPID = L.RowMap().Comm().MyPID(); cout << "Proc " << MyPID << " Local Row = " << i << " U.Indices["<< j <<"] = " << Indices[j] << " U1.Indices["<< j <<"] = " << Indices1[j] << endl; } assert(Indices[j]==Indices1[j]); } Nout += (NumIndices-NumIndices1); } // Test query functions int NumGlobalRows = LU.NumGlobalRows(); if (verbose) cout << "\n\nNumber of Global Rows = " << NumGlobalRows << endl<< endl; assert(NumGlobalRows==NumGlobalRows1); int NumGlobalNonzeros = LU.NumGlobalNonzeros(); if (verbose) cout << "\n\nNumber of Global Nonzero entries = " << NumGlobalNonzeros << endl<< endl; int NoutG = 0; L.RowMap().Comm().SumAll(&Nout, &NoutG, 1); assert(NumGlobalNonzeros==L.NumGlobalNonzeros()+U.NumGlobalNonzeros()-NoutG); int NumMyRows = LU.NumMyRows(); if (verbose) cout << "\n\nNumber of Rows = " << NumMyRows << endl<< endl; assert(NumMyRows==NumMyRows1); int NumMyNonzeros = LU.NumMyNonzeros(); if (verbose) cout << "\n\nNumber of Nonzero entries = " << NumMyNonzeros << endl<< endl; assert(NumMyNonzeros==L.NumMyNonzeros()+U.NumMyNonzeros()-Nout); if (verbose) cout << "\n\nLU check OK" << endl<< endl; return(0); }
int four_quads(const Epetra_Comm& Comm, bool preconstruct_graph, bool verbose) { if (verbose) { cout << "******************* four_quads ***********************"<<endl; } //This function assembles a matrix representing a finite-element mesh //of four 2-D quad elements. There are 9 nodes in the problem. The //same problem is assembled no matter how many processors are being used //(within reason). It may not work if more than 9 processors are used. // // *------*------* // 6| 7| 8| // | E2 | E3 | // *------*------* // 3| 4| 5| // | E0 | E1 | // *------*------* // 0 1 2 // //Nodes are denoted by * with node-numbers below and left of each node. //E0, E1 and so on are element-numbers. // //Each processor will contribute a sub-matrix of size 4x4, filled with 1's, //for each element. Thus, the coefficient value at position 0,0 should end up //being 1.0*numProcs, the value at position 4,4 should be 1.0*4*numProcs, etc. // //Depending on the number of processors being used, the locations of the //specific matrix positions (in terms of which processor owns them) will vary. // int numProcs = Comm.NumProc(); int numNodes = 9; int numElems = 4; int numNodesPerElem = 4; int blockSize = 1; int indexBase = 0; //Create a map using epetra-defined linear distribution. Epetra_BlockMap map(numNodes, blockSize, indexBase, Comm); Epetra_CrsGraph* graph = NULL; int* nodes = new int[numNodesPerElem]; int i, j, k, err = 0; if (preconstruct_graph) { graph = new Epetra_CrsGraph(Copy, map, 1); //we're going to fill the graph with indices, but remember it will only //accept indices in rows for which map.MyGID(row) is true. for(i=0; i<numElems; ++i) { switch(i) { case 0: nodes[0] = 0; nodes[1] = 1; nodes[2] = 4; nodes[3] = 3; break; case 1: nodes[0] = 1; nodes[1] = 2; nodes[2] = 5; nodes[3] = 4; break; case 2: nodes[0] = 3; nodes[1] = 4; nodes[2] = 7; nodes[3] = 6; break; case 3: nodes[0] = 4; nodes[1] = 5; nodes[2] = 8; nodes[3] = 7; break; } for(j=0; j<numNodesPerElem; ++j) { if (map.MyGID(nodes[j])) { err = graph->InsertGlobalIndices(nodes[j], numNodesPerElem, nodes); if (err<0) return(err); } } } EPETRA_CHK_ERR( graph->FillComplete() ); } Epetra_FEVbrMatrix* A = NULL; if (preconstruct_graph) { A = new Epetra_FEVbrMatrix(Copy, *graph); } else { A = new Epetra_FEVbrMatrix(Copy, map, 1); } //EPETRA_CHK_ERR( A->PutScalar(0.0) ); double* values_1d = new double[numNodesPerElem*numNodesPerElem]; double** values_2d = new double*[numNodesPerElem]; for(i=0; i<numNodesPerElem*numNodesPerElem; ++i) values_1d[i] = 1.0; int offset = 0; for(i=0; i<numNodesPerElem; ++i) { values_2d[i] = &(values_1d[offset]); offset += numNodesPerElem; } for(i=0; i<numElems; ++i) { switch(i) { case 0: nodes[0] = 0; nodes[1] = 1; nodes[2] = 4; nodes[3] = 3; break; case 1: nodes[0] = 1; nodes[1] = 2; nodes[2] = 5; nodes[3] = 4; break; case 2: nodes[0] = 3; nodes[1] = 4; nodes[2] = 7; nodes[3] = 6; break; case 3: nodes[0] = 4; nodes[1] = 5; nodes[2] = 8; nodes[3] = 7; break; } for(j=0; j<numNodesPerElem; ++j) { if (preconstruct_graph) { err = A->BeginSumIntoGlobalValues(nodes[j], numNodesPerElem, nodes); if (err<0) return(err); } else { err = A->BeginInsertGlobalValues(nodes[j], numNodesPerElem, nodes); if (err<0) return(err); } for(k=0; k<numNodesPerElem; ++k) { err = A->SubmitBlockEntry(values_1d, blockSize, blockSize, blockSize); if (err<0) return(err); } err = A->EndSubmitEntries(); if (err<0) return(err); } } EPETRA_CHK_ERR( A->GlobalAssemble() ); Epetra_FEVbrMatrix* Acopy = new Epetra_FEVbrMatrix(*A); if (verbose) { cout << "A:"<<*A << endl; cout << "Acopy:"<<*Acopy<<endl; } Epetra_Vector x(A->RowMap()), y(A->RowMap()); x.PutScalar(1.0); y.PutScalar(0.0); Epetra_Vector x2(Acopy->RowMap()), y2(Acopy->RowMap()); x2.PutScalar(1.0); y2.PutScalar(0.0); A->Multiply(false, x, y); Acopy->Multiply(false, x2, y2); double ynorm2, y2norm2; y.Norm2(&ynorm2); y2.Norm2(&y2norm2); if (ynorm2 != y2norm2) { cerr << "norm2(A*ones) != norm2(*Acopy*ones)"<<endl; return(-99); } Epetra_FEVbrMatrix* Acopy2 = new Epetra_FEVbrMatrix(Copy, A->RowMap(), A->ColMap(), 1); *Acopy2 = *Acopy; Epetra_Vector x3(Acopy->RowMap()), y3(Acopy->RowMap()); x3.PutScalar(1.0); y3.PutScalar(0.0); Acopy2->Multiply(false, x3, y3); double y3norm2; y3.Norm2(&y3norm2); if (y3norm2 != y2norm2) { cerr << "norm2(Acopy*ones) != norm2(Acopy2*ones)"<<endl; return(-999); } int len = 20; int* indices = new int[len]; double* values = new double[len]; int numIndices; if (map.MyGID(0)) { int lid = map.LID(0); EPETRA_CHK_ERR( A->ExtractMyRowCopy(lid, len, numIndices, values, indices) ); if (numIndices != 4) { return(-1); } if (indices[0] != lid) { return(-2); } if (values[0] != 1.0*numProcs) { cout << "ERROR: values[0] ("<<values[0]<<") should be "<<numProcs<<endl; return(-3); } } if (map.MyGID(4)) { int lid = map.LID(4); EPETRA_CHK_ERR( A->ExtractMyRowCopy(lid, len, numIndices, values, indices) ); if (numIndices != 9) { return(-4); } int lcid = A->LCID(4); // if (indices[lcid] != 4) { // cout << "ERROR: indices[4] ("<<indices[4]<<") should be " // <<A->LCID(4)<<endl; // return(-5); // } if (values[lcid] != 4.0*numProcs) { cout << "ERROR: values["<<lcid<<"] ("<<values[lcid]<<") should be " <<4*numProcs<<endl; return(-6); } } delete [] values_2d; delete [] values_1d; delete [] nodes; delete [] indices; delete [] values; delete A; delete Acopy2; delete Acopy; delete graph; return(0); }
//============================================================================== int checkSharedOwnership(Epetra_Comm& Comm, bool verbose) { // check to make sure each function returns 1 when it should // check to make sure each function doesn't return 1 when it shouldn't int ierr = 0; // initialize Map const int NumMyElements = 10; const int IndexBase = 0; Epetra_Map Map1((long long) -1, NumMyElements, IndexBase, Comm); // initialize Graphs const int NumIndicesPerRow = 5; Epetra_CrsGraph * SoleOwner = new Epetra_CrsGraph(Copy, Map1, Map1, NumIndicesPerRow); Epetra_CrsGraph SharedOrig(Copy, Map1, Map1, NumIndicesPerRow); Epetra_CrsGraph SharedOwner(SharedOrig); // arrays used by Insert & Remove Epetra_IntSerialDenseVector array1(2); array1[0] = NumIndicesPerRow / 2; array1[1] = array1[0] + 1; Epetra_LongLongSerialDenseVector array2(NumIndicesPerRow); for(int i = 0; i < NumIndicesPerRow; i++) array2[i] = i; // output variables (declaring them here lets us comment out indiv. tests) int soleOutput, sharedOutput; // InsertMyIndices if(verbose) cout << "InsertMyIndices..." << endl; soleOutput = SoleOwner->InsertMyIndices(0, 2, array1.Values()); sharedOutput = SharedOwner.InsertMyIndices(0, 2, array1.Values()); EPETRA_TEST_ERR(!(soleOutput == 0), ierr); EPETRA_TEST_ERR(!(sharedOutput == 1), ierr); if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; // RemoveMyIndices (#0) if(verbose) cout << "RemoveMyIndices(#0)..." << endl; soleOutput = SoleOwner->RemoveMyIndices(0); EPETRA_TEST_ERR(!(soleOutput == 0), ierr); EPETRA_TEST_ERR(!(SoleOwner->NumMyIndices(0)==0),ierr); if (ierr != 0) cout << "tests FAILED" << std::endl; soleOutput = SoleOwner->InsertMyIndices(0, 2, array1.Values()); EPETRA_TEST_ERR(!(soleOutput == 0), ierr); // SortIndices //if(verbose) cout << "SortIndices..." << endl; //soleOutput = SoleOwner.SortIndices(); //sharedOutput = SharedOwner.SortIndices(); //EPETRA_TEST_ERR(!(soleOutput == 0), ierr); //EPETRA_TEST_ERR(!(sharedOutput == 1), ierr); //if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; // RemoveRedundantIndices //if(verbose) cout << "RemoveRedundantIndices..." << endl; //SoleOwner.InsertGlobalIndices(0, 1, array1.Values()); //SharedOwner.InsertGlobalIndices(0, 1, array1.Values()); //soleOutput = SoleOwner.RemoveRedundantIndices(); //sharedOutput = SharedOwner.RemoveRedundantIndices(); //EPETRA_TEST_ERR(!(soleOutput == 0), ierr); //EPETRA_TEST_ERR(!(sharedOutput == 1), ierr); //if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; // FillComplete (#1) if(verbose) cout << "FillComplete..." << endl; soleOutput = SoleOwner->FillComplete(); sharedOutput = SharedOwner.FillComplete(); EPETRA_TEST_ERR(!(soleOutput == 0), ierr); EPETRA_TEST_ERR(!(sharedOutput == 1), ierr); if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; // OptimizeStorage if(verbose) cout << "OptimizeStorage..." << endl; soleOutput = SoleOwner->OptimizeStorage(); sharedOutput = SharedOwner.OptimizeStorage(); EPETRA_TEST_ERR(!(soleOutput == 0), ierr); EPETRA_TEST_ERR(!(sharedOutput == 0), ierr); if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; // RemoveMyIndices (#1) if(verbose) cout << "RemoveMyIndices..." << endl; soleOutput = SoleOwner->RemoveMyIndices(0, 1, &array1[1]); sharedOutput = SharedOwner.RemoveMyIndices(0, 1, &array1[1]); EPETRA_TEST_ERR(!(soleOutput == -1), ierr); EPETRA_TEST_ERR(!(sharedOutput == -1), ierr); if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; // RemoveMyIndices (#2) if(verbose) cout << "RemoveMyIndices(#2)..." << endl; soleOutput = SoleOwner->RemoveMyIndices(0); sharedOutput = SharedOwner.RemoveMyIndices(0); EPETRA_TEST_ERR(!(soleOutput == -1), ierr); EPETRA_TEST_ERR(!(sharedOutput == -1), ierr); if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; // FillComplete (#2) if(verbose) cout << "FillComplete(#2)..." << endl; soleOutput = SoleOwner->FillComplete(SoleOwner->DomainMap(), SoleOwner->RangeMap()); sharedOutput = SharedOwner.FillComplete(SharedOwner.DomainMap(), SharedOwner.RangeMap()); EPETRA_TEST_ERR(!(soleOutput == 0), ierr); EPETRA_TEST_ERR(!(sharedOutput == 1), ierr); if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; { // make new Graphs so that we can insert Global instead of Local // inside of new scope so that we can use same names Epetra_CrsGraph SoleOwnerG(Copy, Map1, NumIndicesPerRow); Epetra_CrsGraph SharedOrigG(Copy, Map1, NumIndicesPerRow); Epetra_CrsGraph SharedOwnerG(SharedOrig); long long GlobalRow = SoleOwnerG.GRID64(0); // InsertGlobalIndices if(verbose) cout << "InsertGlobalIndices..." << endl; soleOutput = SoleOwnerG.InsertGlobalIndices(GlobalRow, 2, array2.Values()); sharedOutput = SharedOwnerG.InsertGlobalIndices(GlobalRow, 2, array2.Values()); EPETRA_TEST_ERR(!(soleOutput == 0), ierr); EPETRA_TEST_ERR(!(sharedOutput == 1), ierr); if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; // RemoveGlobalIndices (#1) if(verbose) cout << "RemoveGlobalIndices..." << endl; soleOutput = SoleOwnerG.RemoveGlobalIndices(GlobalRow, 1, &array2[1]); sharedOutput = SharedOwnerG.RemoveGlobalIndices(GlobalRow, 1, &array2[1]); EPETRA_TEST_ERR(!(soleOutput == 0), ierr); EPETRA_TEST_ERR(!(sharedOutput == 1), ierr); if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; // RemoveGlobalIndices (#2) if(verbose) cout << "RemoveGlobalIndices(#2)..." << endl; soleOutput = SoleOwnerG.RemoveGlobalIndices(GlobalRow); sharedOutput = SharedOwnerG.RemoveGlobalIndices(GlobalRow); EPETRA_TEST_ERR(!(soleOutput == 0), ierr); EPETRA_TEST_ERR(!(sharedOutput == 1), ierr); if(verbose && ierr > 0) cout << "soleOutput = " << soleOutput << " sharedOutput = " << sharedOutput << endl; } // *PROT* InsertIndices // *PROT* MakeIndicesLocal delete SoleOwner; return(ierr); }
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; }
//============================================================================== int check(Epetra_CrsGraph& A, int NumMyRows1, long long NumGlobalRows1, int NumMyNonzeros1, long long NumGlobalNonzeros1, long long* MyGlobalElements, bool verbose) { (void)MyGlobalElements; int ierr = 0; int i; int j; int forierr = 0; int NumGlobalIndices; int NumMyIndices; int* MyViewIndices; int MaxNumIndices = A.MaxNumIndices(); int* MyCopyIndices = new int[MaxNumIndices]; long long* GlobalCopyIndices = new long long[MaxNumIndices]; // Test query functions int NumMyRows = A.NumMyRows(); if(verbose) cout << "Number of local Rows = " << NumMyRows << endl; EPETRA_TEST_ERR(!(NumMyRows==NumMyRows1),ierr); int NumMyNonzeros = A.NumMyNonzeros(); if(verbose) cout << "Number of local Nonzero entries = " << NumMyNonzeros << endl; EPETRA_TEST_ERR(!(NumMyNonzeros==NumMyNonzeros1),ierr); long long NumGlobalRows = A.NumGlobalRows64(); if(verbose) cout << "Number of global Rows = " << NumGlobalRows << endl; EPETRA_TEST_ERR(!(NumGlobalRows==NumGlobalRows1),ierr); long long NumGlobalNonzeros = A.NumGlobalNonzeros64(); if(verbose) cout << "Number of global Nonzero entries = " << NumGlobalNonzeros << endl; EPETRA_TEST_ERR(!(NumGlobalNonzeros==NumGlobalNonzeros1),ierr); // GlobalRowView should be illegal (since we have local indices) EPETRA_TEST_ERR(!(A.ExtractGlobalRowView(A.RowMap().MaxMyGID64(), NumGlobalIndices, GlobalCopyIndices)==-2),ierr); // Other binary tests EPETRA_TEST_ERR(A.NoDiagonal(),ierr); EPETRA_TEST_ERR(!(A.Filled()),ierr); EPETRA_TEST_ERR(!(A.MyGRID(A.RowMap().MaxMyGID64())),ierr); EPETRA_TEST_ERR(!(A.MyGRID(A.RowMap().MinMyGID64())),ierr); EPETRA_TEST_ERR(A.MyGRID(1+A.RowMap().MaxMyGID64()),ierr); EPETRA_TEST_ERR(A.MyGRID(-1+A.RowMap().MinMyGID64()),ierr); EPETRA_TEST_ERR(!(A.MyLRID(0)),ierr); EPETRA_TEST_ERR(!(A.MyLRID(NumMyRows-1)),ierr); EPETRA_TEST_ERR(A.MyLRID(-1),ierr); EPETRA_TEST_ERR(A.MyLRID(NumMyRows),ierr); forierr = 0; for(i = 0; i < NumMyRows; i++) { long long Row = A.GRID64(i); A.ExtractGlobalRowCopy(Row, MaxNumIndices, NumGlobalIndices, GlobalCopyIndices); A.ExtractMyRowView(i, NumMyIndices, MyViewIndices); forierr += !(NumGlobalIndices==NumMyIndices); for(j = 1; j < NumMyIndices; j++) EPETRA_TEST_ERR(!(MyViewIndices[j-1]<MyViewIndices[j]),ierr); for(j = 0; j < NumGlobalIndices; j++) { forierr += !(GlobalCopyIndices[j]==A.GCID64(MyViewIndices[j])); forierr += !(A.LCID(GlobalCopyIndices[j])==MyViewIndices[j]); } } EPETRA_TEST_ERR(forierr,ierr); forierr = 0; for(i = 0; i < NumMyRows; i++) { long long Row = A.GRID64(i); A.ExtractGlobalRowCopy(Row, MaxNumIndices, NumGlobalIndices, GlobalCopyIndices); A.ExtractMyRowCopy(i, MaxNumIndices, NumMyIndices, MyCopyIndices); forierr += !(NumGlobalIndices==NumMyIndices); for(j = 1; j < NumMyIndices; j++) EPETRA_TEST_ERR(!(MyCopyIndices[j-1]<MyCopyIndices[j]),ierr); for(j = 0; j < NumGlobalIndices; j++) { forierr += !(GlobalCopyIndices[j]==A.GCID64(MyCopyIndices[j])); forierr += !(A.LCID(GlobalCopyIndices[j])==MyCopyIndices[j]); } } EPETRA_TEST_ERR(forierr,ierr); delete[] MyCopyIndices; delete[] GlobalCopyIndices; if(verbose) cout << "Rows sorted check OK" << endl; return(ierr); }
//============================================================================== Ifpack_IlukGraph::Ifpack_IlukGraph(const Epetra_CrsGraph & Graph_in, int LevelFill_in, int LevelOverlap_in) : Graph_(Graph_in), DomainMap_(Graph_in.DomainMap()), RangeMap_(Graph_in.RangeMap()), Comm_(Graph_in.Comm()), LevelFill_(LevelFill_in), LevelOverlap_(LevelOverlap_in), IndexBase_(Graph_in.IndexBase64()), NumGlobalRows_(Graph_in.NumGlobalRows64()), NumGlobalCols_(Graph_in.NumGlobalCols64()), NumGlobalBlockRows_(Graph_in.NumGlobalBlockRows64()), NumGlobalBlockCols_(Graph_in.NumGlobalBlockCols64()), NumGlobalBlockDiagonals_(0), NumGlobalNonzeros_(0), NumGlobalEntries_(0), NumMyBlockRows_(Graph_in.NumMyBlockRows()), NumMyBlockCols_(Graph_in.NumMyBlockCols()), NumMyRows_(Graph_in.NumMyRows()), NumMyCols_(Graph_in.NumMyCols()), NumMyBlockDiagonals_(0), NumMyNonzeros_(0), NumMyEntries_(0) { }
CrsGraph_Transpose::NewTypeRef CrsGraph_Transpose:: operator()( OriginalTypeRef orig ) { origObj_ = &orig; int nRows = orig.NumMyRows(); int nCols = orig.NumMyCols(); const Epetra_BlockMap & RowMap = orig.RowMap(); int numIndices; int * Indices; Epetra_CrsGraph * TransposeGraph = 0; if( !ignoreNonLocalCols_ && orig.DistributedGlobal() ) { std::vector<int> TransNumNZ( nCols, 0 ); for( int i = 0; i < nRows; ++i ) { orig.ExtractMyRowView( i, numIndices, Indices ); for( int j = 0; j < numIndices; ++j ) ++TransNumNZ[ Indices[j] ]; } std::vector< std::vector<int> > TransIndices( nCols ); for( int i = 0; i < nCols; ++i ) if( TransNumNZ[i] ) { TransIndices[i].resize( TransNumNZ[i] ); TransNumNZ[i] = 0; } for( int i = 0; i < nRows; ++i ) { orig.ExtractMyRowView( i, numIndices, Indices ); for( int j = 0; j < numIndices; ++j ) TransIndices[ Indices[j] ][ TransNumNZ[ Indices[j] ]++ ] = i; } Epetra_CrsGraph SharedTransGraph( View, orig.ImportMap(), RowMap, &TransNumNZ[0] ); for( int i = 0; i < nCols; ++i ) if( TransNumNZ[i] ) SharedTransGraph.InsertMyIndices( i, TransNumNZ[i], &TransIndices[i][0] ); SharedTransGraph.FillComplete(); TransposeGraph = new Epetra_CrsGraph( Copy, RowMap, 0 ); Epetra_Export Exporter( orig.ImportMap(), RowMap ); TransposeGraph->Export( SharedTransGraph, Exporter, Add ); TransposeGraph->FillComplete(); } else { std::vector<int> TransNumNZ( nRows, 0 ); for( int i = 0; i < nRows; ++i ) { orig.ExtractMyRowView( i, numIndices, Indices ); for( int j = 0; j < numIndices; ++j ) if( Indices[j] < nRows ) ++TransNumNZ[ Indices[j] ]; } std::vector< std::vector<int> > TransIndices( nRows ); for( int i = 0; i < nRows; ++i ) if( TransNumNZ[i] ) { TransIndices[i].resize( TransNumNZ[i] ); TransNumNZ[i] = 0; } for( int i = 0; i < nRows; ++i ) { orig.ExtractMyRowView( i, numIndices, Indices ); for( int j = 0; j < numIndices; ++j ) if( Indices[j] < nRows ) TransIndices[ Indices[j] ][ TransNumNZ[ Indices[j] ]++ ] = i; } TransposeGraph = new Epetra_CrsGraph( Copy, RowMap, RowMap, &TransNumNZ[0] ); for( int i = 0; i < nRows; ++i ) if( TransNumNZ[i] ) TransposeGraph->InsertMyIndices( i, TransNumNZ[i], &TransIndices[i][0] ); TransposeGraph->FillComplete(); } newObj_ = TransposeGraph; return *TransposeGraph; }
void show_matrix(const char *txt, const Epetra_CrsGraph &graph, const Epetra_Comm &comm) { int me = comm.MyPID(); if (comm.NumProc() > 10){ if (me == 0){ std::cerr << txt << std::endl; std::cerr << "Printed matrix format only works for 10 or fewer processes" << std::endl; } return; } const Epetra_BlockMap &rowmap = graph.RowMap(); const Epetra_BlockMap &colmap = graph.ColMap(); int myRows = rowmap.NumMyElements(); int numRows = graph.NumGlobalRows(); int numCols = graph.NumGlobalCols(); int base = rowmap.IndexBase(); if ((numRows > 200) || (numCols > 500)){ if (me == 0){ std::cerr << txt << std::endl; std::cerr << "show_matrix: problem is too large to display" << std::endl; } return; } int *myA = new int [numRows * numCols]; memset(myA, 0, sizeof(int) * numRows * numCols); int *myIndices; int *myRowGIDs = rowmap.MyGlobalElements(); for (int i=0; i< myRows; i++){ int myRowLID = rowmap.LID(myRowGIDs[i]); int numEntries = graph.NumMyIndices(myRowLID); if (numEntries > 0){ int rc = graph.ExtractMyRowView(myRowLID, numEntries, myIndices); if (rc){ std::cerr << txt << std::endl; std::cerr << "extract graph error" << std::endl; return; } int *row = myA + (numCols * (myRowGIDs[i] - base)); for (int j=0; j < numEntries; j++){ int gid = colmap.GID(myIndices[j]); row[gid-base] = me+1; } } } printMatrix(txt, myA, NULL, NULL, numRows, numCols, comm); delete [] myA; }
Epetra_CrsGraph * BlockUtility::TGenerateBlockGraph( const Epetra_CrsGraph & BaseGraph, const Epetra_CrsGraph & LocalBlockGraph, const Epetra_Comm & GlobalComm ) { const Epetra_BlockMap & BaseRowMap = BaseGraph.RowMap(); const Epetra_BlockMap & BaseColMap = BaseGraph.ColMap(); int_type ROffset = BlockUtility::TCalculateOffset<int_type>(BaseRowMap); (void) ROffset; // Silence "unused variable" compiler warning. int_type COffset = BlockUtility::TCalculateOffset<int_type>(BaseColMap); //Get Base Global IDs const Epetra_BlockMap & BlockRowMap = LocalBlockGraph.RowMap(); const Epetra_BlockMap & BlockColMap = LocalBlockGraph.ColMap(); int NumBlockRows = BlockRowMap.NumMyElements(); vector<int_type> RowIndices(NumBlockRows); BlockRowMap.MyGlobalElements(&RowIndices[0]); int Size = BaseRowMap.NumMyElements(); Epetra_Map *GlobalRowMap = GenerateBlockMap(BaseRowMap, BlockRowMap, GlobalComm); int MaxIndices = BaseGraph.MaxNumIndices(); vector<int_type> Indices(MaxIndices); Epetra_CrsGraph * GlobalGraph = new Epetra_CrsGraph( Copy, dynamic_cast<Epetra_BlockMap&>(*GlobalRowMap), 0 ); int NumBlockIndices, NumBaseIndices; int *BlockIndices, *BaseIndices; for( int i = 0; i < NumBlockRows; ++i ) { LocalBlockGraph.ExtractMyRowView(i, NumBlockIndices, BlockIndices); for( int j = 0; j < Size; ++j ) { int_type GlobalRow = (int_type) GlobalRowMap->GID64(j+i*Size); BaseGraph.ExtractMyRowView( j, NumBaseIndices, BaseIndices ); for( int k = 0; k < NumBlockIndices; ++k ) { int_type ColOffset = (int_type) BlockColMap.GID64(BlockIndices[k]) * COffset; for( int l = 0; l < NumBaseIndices; ++l ) Indices[l] = (int_type) BaseGraph.GCID64(BaseIndices[l]) + ColOffset; GlobalGraph->InsertGlobalIndices( GlobalRow, NumBaseIndices, &Indices[0] ); } } } const Epetra_BlockMap & BaseDomainMap = BaseGraph.DomainMap(); const Epetra_BlockMap & BaseRangeMap = BaseGraph.RangeMap(); const Epetra_BlockMap & BlockDomainMap = LocalBlockGraph.DomainMap(); const Epetra_BlockMap & BlockRangeMap = LocalBlockGraph.RangeMap(); Epetra_Map *GlobalDomainMap = GenerateBlockMap(BaseDomainMap, BlockDomainMap, GlobalComm); Epetra_Map *GlobalRangeMap = GenerateBlockMap(BaseRangeMap, BlockRangeMap, GlobalComm); GlobalGraph->FillComplete(*GlobalDomainMap, *GlobalRangeMap); delete GlobalDomainMap; delete GlobalRangeMap; delete GlobalRowMap; return GlobalGraph; }
Epetra_CrsGraph * BlockUtility::TGenerateBlockGraph( const Epetra_RowMatrix & BaseMatrix, const vector< vector<int_type> > & RowStencil, const vector<int_type> & RowIndices, const Epetra_Comm & GlobalComm ) { const Epetra_BlockMap & BaseMap = BaseMatrix.RowMatrixRowMap(); const Epetra_BlockMap & BaseColMap = BaseMatrix.RowMatrixColMap(); int_type BaseIndex = (int_type) BaseMap.IndexBase64(); int_type Offset = BlockUtility::TCalculateOffset<int_type>(BaseMap); //Get Base Global IDs int NumBlockRows = RowIndices.size(); int Size = BaseMap.NumMyElements(); int TotalSize = NumBlockRows * Size; vector<int_type> GIDs(Size); BaseMap.MyGlobalElements( &GIDs[0] ); vector<int_type> GlobalGIDs( TotalSize ); for( int i = 0; i < NumBlockRows; ++i ) { for( int j = 0; j < Size; ++j ) GlobalGIDs[i*Size+j] = GIDs[j] + RowIndices[i] * Offset; } int_type GlobalSize; int_type TotalSize_int_type = TotalSize; GlobalComm.SumAll( &TotalSize_int_type, &GlobalSize, 1 ); Epetra_Map GlobalMap( GlobalSize, TotalSize, &GlobalGIDs[0], BaseIndex, GlobalComm ); int MaxIndices = BaseMatrix.MaxNumEntries(); vector<int> Indices_local(MaxIndices); vector<int_type> Indices_global(MaxIndices); vector<double> Values(MaxIndices); int NumIndices; Epetra_CrsGraph * GlobalGraph = new Epetra_CrsGraph( Copy, dynamic_cast<Epetra_BlockMap&>(GlobalMap), 0 ); for( int i = 0; i < NumBlockRows; ++i ) { int StencilSize = RowStencil[i].size(); for( int j = 0; j < Size; ++j ) { int_type GlobalRow = (int_type) GlobalMap.GID64(j+i*Size); BaseMatrix.ExtractMyRowCopy( j, MaxIndices, NumIndices, &Values[0], &Indices_local[0] ); for( int l = 0; l < NumIndices; ++l ) Indices_global[l] = (int_type) BaseColMap.GID64(Indices_local[l]); for( int k = 0; k < StencilSize; ++k ) { int_type ColOffset = (RowIndices[i]+RowStencil[i][k]) * Offset; if( k > 0 ) ColOffset -= (RowIndices[i]+RowStencil[i][k-1]) * Offset; for( int l = 0; l < NumIndices; ++l ) Indices_global[l] += ColOffset; GlobalGraph->InsertGlobalIndices( GlobalRow, NumIndices, &Indices_global[0] ); } } } GlobalGraph->FillComplete(); return GlobalGraph; }
int four_quads(const Epetra_Comm& Comm, bool preconstruct_graph, bool verbose) { if (verbose) { cout << "******************* four_quads ***********************"<<endl; } //This function assembles a matrix representing a finite-element mesh //of four 2-D quad elements. There are 9 nodes in the problem. The //same problem is assembled no matter how many processors are being used //(within reason). It may not work if more than 9 processors are used. // // *------*------* // 6| 7| 8| // | E2 | E3 | // *------*------* // 3| 4| 5| // | E0 | E1 | // *------*------* // 0 1 2 // //Nodes are denoted by * with node-numbers below and left of each node. //E0, E1 and so on are element-numbers. // //Each processor will contribute a sub-matrix of size 4x4, filled with 1's, //for each element. Thus, the coefficient value at position 0,0 should end up //being 1.0*numProcs, the value at position 4,4 should be 1.0*4*numProcs, etc. // //Depending on the number of processors being used, the locations of the //specific matrix positions (in terms of which processor owns them) will vary. // int numProcs = Comm.NumProc(); int numNodes = 9; int numElems = 4; int numNodesPerElem = 4; int indexBase = 0; //Create a map using epetra-defined linear distribution. Epetra_Map map(numNodes, indexBase, Comm); Epetra_CrsGraph* graph = NULL; int* nodes = new int[numNodesPerElem]; int i, j, err = 0; if (preconstruct_graph) { graph = new Epetra_CrsGraph(Copy, map, 1); //we're going to fill the graph with indices, but remember it will only //accept indices in rows for which map.MyGID(row) is true. for(i=0; i<numElems; ++i) { switch(i) { case 0: nodes[0] = 0; nodes[1] = 1; nodes[2] = 4; nodes[3] = 3; break; case 1: nodes[0] = 1; nodes[1] = 2; nodes[2] = 5; nodes[3] = 4; break; case 2: nodes[0] = 3; nodes[1] = 4; nodes[2] = 7; nodes[3] = 6; break; case 3: nodes[0] = 4; nodes[1] = 5; nodes[2] = 8; nodes[3] = 7; break; } for(j=0; j<numNodesPerElem; ++j) { if (map.MyGID(nodes[j])) { err = graph->InsertGlobalIndices(nodes[j], numNodesPerElem, nodes); if (err<0) return(err); } } } EPETRA_CHK_ERR( graph->FillComplete() ); } Epetra_FECrsMatrix* A = NULL; if (preconstruct_graph) { A = new Epetra_FECrsMatrix(Copy, *graph); } else { A = new Epetra_FECrsMatrix(Copy, map, 1); } EPETRA_CHK_ERR( A->PutScalar(0.0) ); double* values_1d = new double[numNodesPerElem*numNodesPerElem]; double** values_2d = new double*[numNodesPerElem]; for(i=0; i<numNodesPerElem*numNodesPerElem; ++i) values_1d[i] = 1.0; int offset = 0; for(i=0; i<numNodesPerElem; ++i) { values_2d[i] = &(values_1d[offset]); offset += numNodesPerElem; } int format = Epetra_FECrsMatrix::ROW_MAJOR; Epetra_IntSerialDenseVector epetra_nodes(View, nodes, numNodesPerElem); Epetra_SerialDenseMatrix epetra_values(View, values_1d, numNodesPerElem, numNodesPerElem, numNodesPerElem); for(i=0; i<numElems; ++i) { switch(i) { case 0: nodes[0] = 0; nodes[1] = 1; nodes[2] = 4; nodes[3] = 3; if (preconstruct_graph) { err = A->SumIntoGlobalValues(epetra_nodes, epetra_values, format); if (err<0) return(err); } else { err = A->InsertGlobalValues(epetra_nodes, epetra_values, format); if (err<0) return(err); } break; case 1: nodes[0] = 1; nodes[1] = 2; nodes[2] = 5; nodes[3] = 4; if (preconstruct_graph) { err = A->SumIntoGlobalValues(nodes[0], numNodesPerElem, values_2d[0], nodes); err += A->SumIntoGlobalValues(nodes[1], numNodesPerElem, values_2d[1], nodes); err += A->SumIntoGlobalValues(nodes[2], numNodesPerElem, values_2d[2], nodes); err += A->SumIntoGlobalValues(nodes[3], numNodesPerElem, values_2d[3], nodes); if (err<0) return(err); } else { err = A->InsertGlobalValues(numNodesPerElem, nodes, values_2d, format); if (err<0) return(err); } break; case 2: nodes[0] = 3; nodes[1] = 4; nodes[2] = 7; nodes[3] = 6; if (preconstruct_graph) { err = A->SumIntoGlobalValues(numNodesPerElem, nodes, numNodesPerElem, nodes, values_1d, format); if (err<0) return(err); } else { err = A->InsertGlobalValues(numNodesPerElem, nodes, numNodesPerElem, nodes, values_1d, format); if (err<0) return(err); } break; case 3: nodes[0] = 4; nodes[1] = 5; nodes[2] = 8; nodes[3] = 7; if (preconstruct_graph) { err = A->SumIntoGlobalValues(numNodesPerElem, nodes, numNodesPerElem, nodes, values_2d, format); if (err<0) return(err); } else { err = A->InsertGlobalValues(numNodesPerElem, nodes, numNodesPerElem, nodes, values_2d, format); if (err<0) return(err); } break; } } err = A->GlobalAssemble(); if (err < 0) { return(err); } Epetra_Vector x(A->RowMap()), y(A->RowMap()); x.PutScalar(1.0); y.PutScalar(0.0); Epetra_FECrsMatrix Acopy(*A); err = Acopy.GlobalAssemble(); if (err < 0) { return(err); } bool the_same = epetra_test::compare_matrices(*A, Acopy); if (!the_same) { return(-1); } Epetra_FECrsMatrix Acopy2(Copy, A->RowMap(), A->ColMap(), 1); Acopy2 = Acopy; the_same = epetra_test::compare_matrices(*A, Acopy); if (!the_same) { return(-1); } int len = 20; int* indices = new int[len]; double* values = new double[len]; int numIndices; if (map.MyGID(0)) { EPETRA_CHK_ERR( A->ExtractGlobalRowCopy(0, len, numIndices, values, indices) ); if (numIndices != 4) { return(-1); } if (indices[0] != 0) { return(-2); } if (values[0] != 1.0*numProcs) { cout << "ERROR: values[0] ("<<values[0]<<") should be "<<numProcs<<endl; return(-3); } } if (map.MyGID(4)) { EPETRA_CHK_ERR( A->ExtractGlobalRowCopy(4, len, numIndices, values, indices) ); if (numIndices != 9) { return(-4); } int lcid = A->LCID(4); if (lcid<0) { return(-5); } if (values[lcid] != 4.0*numProcs) { cout << "ERROR: values["<<lcid<<"] ("<<values[lcid]<<") should be " <<4*numProcs<<endl; return(-6); } } delete [] values_2d; delete [] values_1d; delete [] nodes; delete [] indices; delete [] values; delete A; delete graph; return(0); }