void MatrixAdapter<Matrix>::do_getCcs(const Teuchos::ArrayView<scalar_t> nzval, const Teuchos::ArrayView<global_ordinal_t> rowind, const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> colptr, typename MatrixAdapter<Matrix>::global_size_t& nnz, const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > colmap, EDistribution distribution, EStorage_Ordering ordering, col_access ca) const { using Teuchos::RCP; using Teuchos::ArrayView; using Teuchos::OrdinalTraits; RCP<const type> get_mat; if( *colmap == *this->col_map_ ){ // No need to redistribute get_mat = rcp(this,false); // non-owning } else { get_mat = get(colmap, distribution); } // If all is well and good, then colmap == cmap RCP<const Tpetra::Map<scalar_t,local_ordinal_t,global_ordinal_t> > cmap = get_mat->getColMap(); TEUCHOS_ASSERT( *colmap == *cmap ); ArrayView<global_ordinal_t> node_elements = cmap->getNodeElementList(); if( node_elements.size() == 0 ) return; // no more contribution typename ArrayView<global_ordinal_t>::iterator col_it, col_end; col_end = node_elements.end(); size_t colptr_ind = OrdinalTraits<size_t>::zero(); global_ordinal_t colInd = OrdinalTraits<global_ordinal_t>::zero(); for( col_it = node_elements.begin(); col_it != col_end; ++col_it ){ colptr[colptr_ind++] = colInd; size_t colNNZ = getGlobalColNNZ(*col_it); size_t nnzRet = 0; ArrayView<global_ordinal_t> rowind_view = rowind.view(colInd,colNNZ); ArrayView<scalar_t> nzval_view = nzval.view(colInd,colNNZ); getGlobalColCopy(*col_it, rowind_view, nzval_view, nnzRet); // It was suggested that instead of sorting each row's indices // individually, that we instead do a double-transpose at the // end, which would also lead to the indices being sorted. if( ordering == SORTED_INDICES ){ Tpetra::sort2(rowind_view.begin(), rowind_view.end(), nzval_view.begin()); } TEUCHOS_TEST_FOR_EXCEPTION( colNNZ != nnzRet, std::runtime_error, "Number of values returned different from " "number of values reported"); colInd += colNNZ; } colptr[colptr_ind] = nnz = colInd; }
void MatrixAdapter<Matrix>::do_getCrs(const Teuchos::ArrayView<scalar_t> nzval, const Teuchos::ArrayView<global_ordinal_t> colind, const Teuchos::ArrayView<typename MatrixAdapter<Matrix>::global_size_t> rowptr, typename MatrixAdapter<Matrix>::global_size_t& nnz, const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > rowmap, EDistribution distribution, EStorage_Ordering ordering, row_access ra) const { using Teuchos::rcp; using Teuchos::RCP; using Teuchos::ArrayView; using Teuchos::OrdinalTraits; ((void) ra); RCP<const type> get_mat; if( *rowmap == *this->row_map_ ){ // No need to redistribute get_mat = rcp(this,false); // non-owning } else { get_mat = get(rowmap, distribution); } // RCP<const type> get_mat = get(rowmap); // rmap may not necessarily check same as rowmap because rmap may // have been constructued with Tpetra's "expert" constructor, // which assumes that the map points are non-contiguous. // // TODO: There may be some more checking between the row map // compatibility, but things are working fine now. RCP<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > rmap = get_mat->getRowMap(); ArrayView<const global_ordinal_t> node_elements = rmap->getNodeElementList(); if( node_elements.size() == 0 ) return; // no more contribution typename ArrayView<const global_ordinal_t>::iterator row_it, row_end; row_end = node_elements.end(); size_t rowptr_ind = OrdinalTraits<size_t>::zero(); global_ordinal_t rowInd = OrdinalTraits<global_ordinal_t>::zero(); for( row_it = node_elements.begin(); row_it != row_end; ++row_it ){ rowptr[rowptr_ind++] = rowInd; size_t rowNNZ = get_mat->getGlobalRowNNZ(*row_it); size_t nnzRet = OrdinalTraits<size_t>::zero(); ArrayView<global_ordinal_t> colind_view = colind.view(rowInd,rowNNZ); ArrayView<scalar_t> nzval_view = nzval.view(rowInd,rowNNZ); get_mat->getGlobalRowCopy(*row_it, colind_view, nzval_view, nnzRet); for (size_t rr = 0; rr < nnzRet ; rr++) { colind_view[rr] = colind_view[rr] - rmap->getIndexBase(); } // It was suggested that instead of sorting each row's indices // individually, that we instead do a double-transpose at the // end, which would also lead to the indices being sorted. if( ordering == SORTED_INDICES ){ Tpetra::sort2(colind_view.begin(), colind_view.end(), nzval_view.begin()); } TEUCHOS_TEST_FOR_EXCEPTION( rowNNZ != nnzRet, std::runtime_error, "Number of values returned different from " "number of values reported"); rowInd += rowNNZ; } rowptr[rowptr_ind] = nnz = rowInd; }