//============================================================================== 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 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])); } } }
//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; }
//============================================================================== 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) { }
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& 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); }