RCP<const MultiVectorBase<Scalar> > MultiVectorDefaultBase<Scalar>::contigSubViewImpl( const Range1D& colRng_in ) const { using Teuchos::Workspace; using Teuchos::as; Teuchos::WorkspaceStore *wss = Teuchos::get_default_workspace_store().get(); const VectorSpaceBase<Scalar> &l_domain = *this->domain(); const VectorSpaceBase<Scalar> &l_range = *this->range(); const Ordinal dimDomain = l_domain.dim(); const Range1D colRng = Teuchos::full_range(colRng_in,0,dimDomain-1); if( colRng.lbound() == 0 && as<Ordinal>(colRng.ubound()) == dimDomain-1 ) return Teuchos::rcp(this,false); // Takes all of the columns! if( colRng.size() ) { // We have to create a view of a subset of the columns Workspace< RCP< VectorBase<Scalar> > > col_vecs(wss,colRng.size()); for( Ordinal j = colRng.lbound(); j <= colRng.ubound(); ++j ) col_vecs[j-colRng.lbound()] = Teuchos::rcp_const_cast<VectorBase<Scalar> >(this->col(j)); return Teuchos::rcp( new DefaultColumnwiseMultiVector<Scalar>( this->range(),l_range.smallVecSpcFcty()->createVecSpc(colRng.size()),col_vecs ) ); } return Teuchos::null; // There was an empty set in colRng_in! }
void SpmdMultiVectorBase<Scalar>::acquireNonconstDetachedMultiVectorViewImpl( const Range1D &rowRng_in, const Range1D &colRng_in, RTOpPack::SubMultiVectorView<Scalar> *sub_mv ) { using Teuchos::outArg; const Range1D rowRng = validateRowRange(rowRng_in); const Range1D colRng = validateColRange(colRng_in); if( rowRng.lbound() < localOffset_ || localOffset_+localSubDim_-1 < rowRng.ubound() ) { // rng consists of off-processor elements so use the default implementation! MultiVectorDefaultBase<Scalar>::acquireNonconstDetachedMultiVectorViewImpl( rowRng_in, colRng_in, sub_mv ); return; } ArrayRCP<Scalar> localValues; Ordinal leadingDim = 0; this->getNonconstLocalData(outArg(localValues), outArg(leadingDim)); sub_mv->initialize( rowRng.lbound() // globalOffset ,rowRng.size() // subDim ,colRng.lbound() // colOffset ,colRng.size() // numSubCols ,localValues +(rowRng.lbound()-localOffset_) +colRng.lbound()*leadingDim // values ,leadingDim // leadingDim ); }
void DefaultProductVector<Scalar>::acquireNonconstDetachedVectorViewImpl( const Range1D& rng_in, RTOpPack::SubVectorView<Scalar>* sub_vec ) { const Range1D rng = rng_in.full_range() ? Range1D(0,productSpace_->dim()-1) : rng_in; int kth_vector_space = -1; Ordinal kth_global_offset = 0; productSpace_->getVecSpcPoss(rng.lbound(),&kth_vector_space,&kth_global_offset); #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) ); #endif if( rng.lbound() + rng.size() <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim() ) { // This involves only one sub-vector so just return it. vecs_[kth_vector_space].getConstObj()->acquireDetachedView( rng - kth_global_offset, sub_vec ); sub_vec->setGlobalOffset( sub_vec->globalOffset() + kth_global_offset ); } else { // Just let the default implementation handle this. ToDo: In the future // we could manually construct an explicit sub-vector that spanned // two or more constituent vectors but this would be a lot of work. // However, this would require the use of temporary memory but // so what. VectorDefaultBase<Scalar>::acquireNonconstDetachedVectorViewImpl(rng_in,sub_vec); } }
void EpetraVector::acquireNonconstDetachedVectorViewImpl( const Teuchos::Range1D& rng_in, RTOpPack::SubVectorView<double>* sub_vec) { if( rng_in == Range1D::Invalid ) { // Just return an null view sub_vec->initialize(rng_in.lbound(), 0, Teuchos::ArrayRCP<double>(), 1); return; } const Range1D rng = validateRange(rng_in); if( rng.lbound() < localOffset_ || localOffset_+localSubDim_-1 < rng.ubound() ) { /* rng consists of off-processor elements so use the * default implementation! */ VectorDefaultBase<double>::acquireNonconstDetachedVectorViewImpl(rng_in, sub_vec); return; } /* All requested elements are on-processor. */ double* localValues = &(epetraVec_->operator[](0)); Teuchos::ArrayRCP<double> locVals(localValues, rng.lbound()-localOffset_, // rng.ubound()-localOffset_, false); rng.size(), false); OrdType stride = 1; sub_vec->initialize(rng.lbound(), rng.size(), locVals, stride); // localValues+(rng.lbound()-localOffset_),stride); }
RTOpPack::SparseSubVector AbstractLinAlgPack::sub_vec_view( const SpVectorSlice& sv_in ,const Range1D& rng_in ) { using Teuchos::null; const Range1D rng = RangePack::full_range(rng_in,1,sv_in.dim()); const SpVectorSlice sv = sv_in(rng); RTOpPack::SparseSubVector sub_vec; if(!sv.nz()) { sub_vec.initialize( rng.lbound()-1 // global_offset ,rng.size() // sub_dim ,0 // nz ,null // vlaues ,1 // values_stride ,null // indices ,1 // indices_stride ,0 // local_offset ,1 // is_sorted ); } else { SpVectorSlice::const_iterator itr = sv.begin(); TEUCHOS_TEST_FOR_EXCEPT( !( itr != sv.end() ) ); if( sv.dim() && sv.nz() == sv.dim() && sv.is_sorted() ) { const Teuchos::ArrayRCP<const value_type> values = Teuchos::arcp(&itr->value(), 0, values_stride*rng.size(), false) ; sub_vec.initialize( rng.lbound()-1 // global_offset ,rng.size() // sub_dim ,values // values ,values_stride // values_stride ); } else { const Teuchos::ArrayRCP<const value_type> values = Teuchos::arcp(&itr->value(), 0, values_stride*sv.nz(), false) ; const Teuchos::ArrayRCP<const index_type> indexes = Teuchos::arcp(&itr->index(), 0, indices_stride*sv.nz(), false); sub_vec.initialize( rng.lbound()-1 // global_offset ,sv.dim() // sub_dim ,sv.nz() // sub_nz ,values // values ,values_stride // values_stride ,indexes // indices ,indices_stride // indices_stride ,sv.offset() // local_offset ,sv.is_sorted() // is_sorted ); } } return sub_vec; }
inline DMatrixSlice::DMatrixSlice( DMatrixSlice& gms, const Range1D& I , const Range1D& J) : ptr_( gms.col_ptr(1) + (I.lbound() - 1) + (J.lbound() - 1) * gms.max_rows() ) , max_rows_(gms.max_rows()) , rows_(I.size()) , cols_(J.size()) { gms.validate_row_subscript(I.ubound()); gms.validate_col_subscript(J.ubound()); }
Teuchos::Range1D EpetraVector::validateRange(const Teuchos::Range1D& rng_in) const { const Range1D rng = Teuchos::full_range(rng_in,0,globalDim_-1); TEST_FOR_EXCEPTION( !( 0 <= rng.lbound() && rng.ubound() < globalDim_ ), std::invalid_argument ,"EpetraVector::validateRange(rowRng): Error, the range rng = [" <<rng.lbound()<<","<<rng.ubound()<<"] is not " "in the range [0,"<<(globalDim_-1)<<"]!" ); return rng; }
Range1D SpmdMultiVectorBase<Scalar>::validateRowRange( const Range1D &rowRng_in ) const { const Range1D rowRng = Teuchos::full_range(rowRng_in,0,globalDim_-1); #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( !( 0 <= rowRng.lbound() && rowRng.ubound() < globalDim_ ), std::invalid_argument ,"SpmdMultiVectorBase<Scalar>::validateRowRange(rowRng): Error, the range rowRng = [" <<rowRng.lbound()<<","<<rowRng.ubound()<<"] is not " "in the range [0,"<<(globalDim_-1)<<"]!" ); #endif return rowRng; }
Range1D SpmdMultiVectorBase<Scalar>::validateColRange( const Range1D &colRng_in ) const { const Range1D colRng = Teuchos::full_range(colRng_in,0,numCols_-1); #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( !(0 <= colRng.lbound() && colRng.ubound() < numCols_), std::invalid_argument ,"SpmdMultiVectorBase<Scalar>::validateColRange(colRng): Error, the range colRng = [" <<colRng.lbound()<<","<<colRng.ubound()<<"] is not " "in the range [0,"<<(numCols_-1)<<"]!" ); #endif return colRng; }
MultiVectorMutable::multi_vec_mut_ptr_t MultiVectorMutableCols::mv_sub_view(const Range1D& row_rng, const Range1D& col_rng) { #ifdef TEUCHOS_DEBUG const size_type rows = this->rows(); TEST_FOR_EXCEPTION( !( row_rng.full_range() || (row_rng.lbound() == 1 && row_rng.ubound() == rows) ) ,std::logic_error, "Error, can't handle subrange on vectors yet!" ); #endif return Teuchos::rcp( new MultiVectorMutableCols( space_cols_,space_rows_->sub_space(col_rng),&col_vecs_[col_rng.lbound()-1] ) ); }
inline const DMatrixSlice DMatrix::operator()(const Range1D& I, const Range1D& J) const { Range1D Ix = RangePack::full_range(I,1,rows()), Jx = RangePack::full_range(J,1,cols()); return DMatrixSlice( const_cast<value_type*>(col_ptr(1)) + (Ix.lbound() - 1) + (Jx.lbound() - 1) * rows() , max_rows() * cols(), max_rows(), Ix.size(), Jx.size() ); }
std::ostream& MatrixIdentConcat::output(std::ostream& out_arg) const { Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::getFancyOStream(Teuchos::rcp(&out_arg,false)); Teuchos::OSTab tab(out); const Range1D D_rng = this->D_rng(); const BLAS_Cpp::Transp D_trans = this->D_trans(); *out << "Converted to dense =\n"; MatrixOp::output(*out); *out << "This is a " << this->rows() << " x " << this->cols() << " general matrix / identity matrix concatenated matrix object "; if( D_rng.lbound() == 1 ) { if( D_trans == BLAS_Cpp::no_trans ) *out << "[ alpha*D; I ]"; else *out << "[ alpha*D'; I ]"; } else { if( D_trans == BLAS_Cpp::no_trans ) *out << "[ I; alpha*D ]"; else *out << "[ I; alpha*D' ]"; } *out << " where alpha and D are:"; tab.incrTab(); *out << "\nalpha = " << this->alpha(); *out << "\nD =\n" << D(); return out_arg; }
void MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl( const Range1D &rowRng_in, const Range1D &colRng_in, RTOpPack::ConstSubMultiVectorView<Scalar> *sub_mv ) const { const Ordinal rangeDim = this->range()->dim(), domainDim = this->domain()->dim(); const Range1D rowRng = rowRng_in.full_range() ? Range1D(0,rangeDim-1) : rowRng_in, colRng = colRng_in.full_range() ? Range1D(0,domainDim-1) : colRng_in; #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( !(rowRng.ubound() < rangeDim), std::out_of_range ,"MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(...): Error, rowRng = [" <<rowRng.lbound()<<","<<rowRng.ubound()<<"] is not in the range = [0," <<(rangeDim-1)<<"]!" ); TEUCHOS_TEST_FOR_EXCEPTION( !(colRng.ubound() < domainDim), std::out_of_range ,"MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(...): Error, colRng = [" <<colRng.lbound()<<","<<colRng.ubound()<<"] is not in the range = [0," <<(domainDim-1)<<"]!" ); #endif // Allocate storage for the multi-vector (stored column-major) const ArrayRCP<Scalar> values = Teuchos::arcp<Scalar>(rowRng.size() * colRng.size()); // Extract multi-vector values column by column RTOpPack::ConstSubVectorView<Scalar> sv; // uninitialized by default for( int k = colRng.lbound(); k <= colRng.ubound(); ++k ) { RCP<const VectorBase<Scalar> > col_k = this->col(k); col_k->acquireDetachedView( rowRng, &sv ); for( int i = 0; i < rowRng.size(); ++i ) values[ i + k*rowRng.size() ] = sv[i]; col_k->releaseDetachedView( &sv ); } // Initialize the multi-vector view object sub_mv->initialize( rowRng.lbound(), // globalOffset rowRng.size(), // subDim colRng.lbound(), // colOffset colRng.size(), // numSubCols values, // values rowRng.size() // leadingDim ); }
void MatrixOpSubView::initialize( const mat_ptr_t& M_full ,const Range1D& rng_rows_in ,const Range1D& rng_cols_in ,BLAS_Cpp::Transp M_trans ) { namespace rcp = MemMngPack; if( M_full.get() ) { const index_type M_rows = M_full->rows(), M_cols = M_full->cols(); const Range1D rng_rows = RangePack::full_range(rng_rows_in,1,M_rows), rng_cols = RangePack::full_range(rng_cols_in,1,M_cols); TEUCHOS_TEST_FOR_EXCEPTION( rng_rows.ubound() > M_rows, std::invalid_argument ,"MatrixOpSubView::initialize(...): Error, " "rng_rows = ["<<rng_rows.lbound()<<","<<rng_rows.ubound()<<"] is of range of " "[1,M_full->rows()] = [1,"<<M_rows<<"]" ); TEUCHOS_TEST_FOR_EXCEPTION( rng_cols.ubound() > M_cols, std::invalid_argument ,"MatrixOpSubView::initialize(...): Error, " "rng_cols = ["<<rng_cols.lbound()<<","<<rng_cols.ubound()<<"] is of range of " "[1,M_full->cols()] = [1,"<<M_cols<<"]" ); M_full_ = M_full; rng_rows_ = rng_rows; rng_cols_ = rng_cols; M_trans_ = M_trans; space_cols_ = ( M_trans == BLAS_Cpp::no_trans ? M_full->space_cols().sub_space(rng_rows)->clone() : M_full->space_rows().sub_space(rng_cols)->clone() ); space_rows_ = ( M_trans == BLAS_Cpp::no_trans ? M_full->space_rows().sub_space(rng_cols)->clone() : M_full->space_cols().sub_space(rng_rows)->clone() ); } else { M_full_ = Teuchos::null; rng_rows_ = Range1D::Invalid; rng_cols_ = Range1D::Invalid; M_trans_ = BLAS_Cpp::no_trans; space_cols_ = Teuchos::null; space_rows_ = Teuchos::null; } }
bool DefaultSpmdVectorSpace<Scalar>::hasInCoreView( const Range1D& rng_in, const EViewType viewType, const EStrideType strideType ) const { const Range1D rng = full_range(rng_in,0,this->dim()-1); const Ordinal l_localOffset = this->localOffset(); return ( l_localOffset<=rng.lbound() && rng.ubound()<l_localOffset+localSubDim_ ); }
inline void VectorDefaultBase<Scalar>::validateColRng( const Range1D &col_rng ) const { #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPT( !( col_rng.full_range() || ( col_rng.lbound() == 0 && col_rng.ubound() == 0) ) ); #endif }
VectorSpace::space_ptr_t VectorSpaceSubSpace::sub_space(const Range1D& rng_in) const { namespace rcp = MemMngPack; if( full_space_.get() == NULL && rng_in == Range1D::Invalid ) return Teuchos::rcp(this,false); validate_range(rng_in); const index_type dim = this->dim(); const Range1D rng = rng_in.full_range() ? Range1D(1,dim) : rng_in; if( rng.lbound() == 1 && rng.ubound() == dim ) return space_ptr_t( this, false ); const index_type this_offset = rng_.lbound() - 1; return Teuchos::rcp( new VectorSpaceSubSpace( full_space_ ,Range1D( this_offset + rng.lbound() ,this_offset + rng.ubound() ) ) ); }
void VectorSpaceSubSpace::validate_range(const Range1D& rng) const { const index_type n = this->dim(); TEST_FOR_EXCEPTION( full_space_.get() == NULL, std::logic_error ,"VectorSpaceSubSpace::validate_range(rng): Error, Uninitialized" ); TEST_FOR_EXCEPTION( full_space_.get() && !rng.full_range() && rng.ubound() > n, std::logic_error ,"VectorSpaceSubSpace::validate_range(rng): Error, " "rng = [" << rng.lbound() << "," << rng.ubound() << "] is not in the range " "[1,this->dim] = [1," << n << "]" ); }
MultiVectorMutable::multi_vec_mut_ptr_t MultiVectorMutableThyra::mv_sub_view(const Range1D& row_rng_in, const Range1D& col_rng_in) { const index_type this_rows = this->rows(); const Range1D row_rng = RangePack::full_range(row_rng_in,1,this->rows()); TEUCHOS_TEST_FOR_EXCEPTION( !(row_rng.lbound()==1 && row_rng.ubound()==this_rows), std::invalid_argument ,"MultiVectorMutableThyra::mv_sub_view(thyra_multi_vec): Error, can not handle subviews of the" " elements in a row yet!" ); return Teuchos::rcp(new MultiVectorMutableThyra(cast_thyra_multi_vec()->subView(convert(col_rng_in)))); }
VectorSpace::space_ptr_t VectorSpaceBlocked::sub_space(const Range1D& rng_in) const { namespace rcp = MemMngPack; const index_type dim = this->dim(); const Range1D rng = rng_in.full_range() ? Range1D(1,dim) : rng_in; // Validate the preconditions #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPTION( dim < rng.ubound(), std::out_of_range ,"VectorSpaceBlocked::sub_space(...): Error, rng = " << "["<<rng.lbound()<<","<<rng.ubound()<<"] is not in range [1,"<<dim<<"]" ); #endif if( rng.lbound() == 1 && rng.ubound() == dim ) return space_ptr_t( this, false ); // Client selected the whole composite vector space. // Get the position of the vector space object of interest int kth_vector_space = -1; index_type kth_global_offset = 0; this->get_vector_space_position(rng.lbound(),&kth_vector_space,&kth_global_offset); const vector_spaces_t &vector_spaces = vector_spaces_; // Need to examine in debugger! const vec_spaces_offsets_t &vec_spaces_offsets = vec_spaces_offsets_; #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= vector_spaces.size() ) ); #endif if( rng.lbound() == kth_global_offset + 1 && rng.size() == vec_spaces_offsets[kth_vector_space+1] - vec_spaces_offsets[kth_vector_space] ) // The client selected a whole single constituent vector space. return vector_spaces[kth_vector_space]; if( rng.ubound() <= vec_spaces_offsets[kth_vector_space+1] ) // The client selected a sub-space of a single consituent vector space return vector_spaces[kth_vector_space]->sub_space(rng-vec_spaces_offsets[kth_vector_space]); // The client selected a sub-space that spans two or more constituent vector spaces // Get the position of the vector space object with the last element of interest int end_kth_vector_space = -1; index_type end_kth_global_offset = 0; this->get_vector_space_position(rng.ubound(),&end_kth_vector_space,&end_kth_global_offset); #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPT( !( 0 <= end_kth_vector_space && end_kth_vector_space <= vector_spaces.size() ) ); TEST_FOR_EXCEPT( !( end_kth_vector_space > kth_vector_space ) ); #endif // Create a VectorSpaceComposite object containing the relavant constituent vector spaces Teuchos::RCP<VectorSpaceBlocked> vec_space_comp = Teuchos::rcp( new VectorSpaceBlocked( &vector_spaces[kth_vector_space] ,end_kth_vector_space - kth_vector_space + 1 ) ); if( rng.lbound() == kth_global_offset + 1 && rng.size() == vec_spaces_offsets[end_kth_vector_space+1] - vec_spaces_offsets[kth_vector_space] ) // The client selected exactly a contigous set of vector spaces return vec_space_comp; // The client selected some sub-set of elements in the contigous set of vector spaces return Teuchos::rcp( new VectorSpaceSubSpace( vec_space_comp ,Range1D( rng.lbound()-vec_spaces_offsets[kth_vector_space] ,rng.ubound()-vec_spaces_offsets[kth_vector_space] ) ) ); }
SparseVectorSlice<T_Element> create_slice(const SparseVectorUtilityPack::SpVecIndexLookup<T_Element>& index_lookup , size_type size, Range1D rng) { // Check preconditions if(rng.full_range()) { rng = Range1D(1,size); } else { #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPT( !( rng.ubound() <= size ) ); #endif } // If there are no elements then any subregion will also not have any elements. if(!index_lookup.nz()) return SparseVectorSlice<T_Element>(0, 0, 0, rng.ubound() - rng.lbound() + 1, true); // Create the slice (assumed sorted oviously). typedef SparseVectorUtilityPack::SpVecIndexLookup<T_Element> SpVecIndexLookup; index_lookup.validate_state(); typename SpVecIndexLookup::poss_type lower_poss = index_lookup.find_poss(rng.lbound(), SpVecIndexLookup::LOWER_ELE), upper_poss = index_lookup.find_poss(rng.ubound(), SpVecIndexLookup::UPPER_ELE); if( lower_poss.poss == upper_poss.poss && ( lower_poss.rel == SpVecIndexLookup::AFTER_ELE || upper_poss.rel == SpVecIndexLookup::BEFORE_ELE ) ) { // The requested subvector does not contain any elements. return SparseVectorSlice<T_Element>(0, 0, 0, rng.ubound() - rng.lbound() + 1, true); } else { // There are nonzero elements return SparseVectorSlice<T_Element>(index_lookup.ele() + lower_poss.poss , upper_poss.poss - lower_poss.poss + 1, index_lookup.offset() - rng.lbound() + 1 , rng.ubound() - rng.lbound() + 1, true); } }
VectorMutable::vec_mut_ptr_t VectorMutable::sub_view( const Range1D& rng_in ) { namespace rcp = MemMngPack; const index_type dim = this->dim(); const Range1D rng = rng_in.full_range() ? Range1D(1,dim) : rng_in; #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPTION( rng.ubound() > dim, std::out_of_range ,"VectorMutable::sub_view(rng): Error, rng = ["<<rng.lbound()<<","<<rng.ubound()<<"] " "is not in the range [1,this->dim()] = [1,"<<dim<<"]" ); #endif if( rng.lbound() == 1 && rng.ubound() == dim ) return Teuchos::rcp( this, false ); // We are returning a view that could change this vector so we had better // wipe out the cache //this->has_changed(); // I don't think this line is needed! return Teuchos::rcp( new VectorMutableSubView( Teuchos::rcp( this, false ) ,rng ) ); }
RCP<MultiVectorBase<Scalar> > DefaultColumnwiseMultiVector<Scalar>::nonconstContigSubViewImpl( const Range1D& col_rng_in ) { const Ordinal numCols = domain_->dim(); const Range1D col_rng = Teuchos::full_range(col_rng_in,0,numCols-1); #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( !( col_rng.ubound() < numCols ), std::logic_error ,"DefaultColumnwiseMultiVector<Scalar>::subView(col_rng):" "Error, the input range col_rng = ["<<col_rng.lbound() <<","<<col_rng.ubound()<<"] " "is not in the range [0,"<<(numCols-1)<<"]!" ); #endif return Teuchos::rcp( new DefaultColumnwiseMultiVector<Scalar>( range_, domain_->smallVecSpcFcty()->createVecSpc(col_rng.size()), col_vecs_(col_rng.lbound(),col_rng.size()) ) ); }
void EpetraVector::acquireDetachedVectorViewImpl( const Teuchos::Range1D& rng_in, RTOpPack::ConstSubVectorView<double>* sub_vec) const { /* if range is empty, return a null view */ if (rng_in == Range1D::Invalid) { sub_vec->initialize(rng_in.lbound(), 0, Teuchos::ArrayRCP<double>(), 1); return ; } /* */ const Range1D rng = validateRange(rng_in); /* If any requested elements are off-processor, fall back to slow * VDB implementation */ if ( rng.lbound() < localOffset_ || localOffset_ + localSubDim_ - 1 < rng.ubound()) { VectorDefaultBase<double>::acquireDetachedVectorViewImpl(rng_in,sub_vec); return ; } /* All requested elements are on-processor. */ const double* localValues = &(epetraVec_->operator[](0)); Teuchos::ArrayRCP<const double> locVals(localValues, rng.lbound()-localOffset_, rng.size(), false); // rng.ubound()-localOffset_, false); OrdType stride = 1; sub_vec->initialize(rng.lbound(), rng.size(), locVals, stride); // localValues+(rng.lbound()-localOffset_), stride); }
void VectorDefaultBase<Scalar>::acquireDetachedVectorViewImpl( const Range1D& rng_in, RTOpPack::ConstSubVectorView<Scalar>* sub_vec_inout ) const { using Teuchos::dyn_cast; const Range1D rng = rng_in.full_range() ? Range1D(0,this->space()->dim()-1) : rng_in; #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( !(rng.ubound() < this->space()->dim()), std::out_of_range ,"VectorDefaultBase<Scalar>::acquireDetachedVectorViewImpl(rng,...):" " Error, rng = ["<<rng.lbound()<<","<<rng.ubound() <<"] is not in range = [0,"<<(this->space()->dim()-1)<<"]" ); #endif // Initialize the operator RTOpPack::ROpGetSubVector<Scalar> get_sub_vector_op(rng.lbound(),rng.ubound()); // Create the reduction object (another sub_vec) RCP<RTOpPack::ReductTarget> reduct_obj = get_sub_vector_op.reduct_obj_create(); // This is really of type RTOpPack::ConstSubVectorView<Scalar>! // Perform the reduction (get the sub-vector requested) ::Thyra::applyOp<Scalar>(get_sub_vector_op, tuple(Teuchos::ptr<const VectorBase<Scalar> >(this))(), Teuchos::null, reduct_obj.ptr()); // Get the sub-vector. *sub_vec_inout = get_sub_vector_op(*reduct_obj); }
Vector::vec_ptr_t VectorSubView::sub_view( const Range1D& rng_in ) const { namespace rcp = MemMngPack; const index_type this_dim = this->dim(); const Range1D rng = RangePack::full_range(rng_in,1,this_dim); space_.validate_range(rng); const index_type this_offset = space_.rng().lbound() - 1; return Teuchos::rcp( new VectorSubView( full_vec_ ,Range1D( this_offset + rng.lbound() ,this_offset + rng.ubound() ) ) ); }
void VectorSpaceSubSpace::initialize( const space_ptr_t& full_space, const Range1D& rng ) { #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPTION( full_space.get() == NULL, std::invalid_argument ,"VectorSpaceSubSpace::initialize(...): Error!" ); #endif const index_type n = full_space->dim(); #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPTION( !rng.full_range() && rng.ubound() > n, std::out_of_range ,"VectorSpaceSubSpace::initialize(...): Error, " "rng = [" << rng.lbound() << "," << rng.ubound() << "] is not in the range " "[1,vec->dim()] = [1," << n << "]" ); #endif full_space_ = full_space; rng_ = rng.full_range() ? Range1D(1,n) : rng; }
void EpetraVector::applyOp( const RTOpPack::RTOpT<double> &op, const int num_vecs, const VectorBase<double>*const vecs[], const int num_targ_vecs, VectorBase<double>*const targ_vecs[], RTOpPack::ReductTarget *reduct_obj, const OrdType first_ele_offset_in, const OrdType sub_dim_in, const OrdType global_offset_in ) const { #ifdef THYRA_SPMD_VECTOR_BASE_DUMP Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream(); Teuchos::OSTab tab(out); if(show_dump) { *out << "\nEntering SpmdVectorBase<double>::applyOp(...) ...\n"; *out << "\nop = " << typeName(op) << "\nnum_vecs = " << num_vecs << "\nnum_targ_vecs = " << num_targ_vecs << "\nreduct_obj = " << reduct_obj << "\nfirst_ele_offset_in = " << first_ele_offset_in << "\nsub_dim_in = " << sub_dim_in << "\nglobal_offset_in = " << global_offset_in << "\n" ; } #endif // THYRA_SPMD_VECTOR_BASE_DUMP using Teuchos::dyn_cast; using Teuchos::Workspace; Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get(); #ifdef TEUCHOS_DEBUG // ToDo: Validate input! TEST_FOR_EXCEPTION( in_applyOpImpl_, std::invalid_argument ,"SpmdVectorBase<>::applyOp(...): Error, this method is being entered recursively which is a " "clear sign that one of the methods acquireDetachedView(...), releaseDetachedView(...) or commitDetachedView(...) " "was not implemented properly!" ); Thyra::apply_op_validate_input( "SpmdVectorBase<>::applyOp(...)",*space() ,op,num_vecs,vecs,num_targ_vecs,targ_vecs,reduct_obj,first_ele_offset_in,sub_dim_in,global_offset_in ); #endif const Teuchos::RCP<const Teuchos::Comm<OrdType> >& comm = epetraVecSpace_->getComm(); const SerialComm<OrdType>* serialComm = dynamic_cast<const SerialComm<OrdType>* >(comm.get()); // Flag that we are in applyOp() in_applyOpImpl_ = true; // First see if this is a locally replicated vector in which case // we treat this as a local operation only. const bool locallyReplicated = ( serialComm != 0 && localSubDim_ == globalDim_ ); // Get the overlap in the current process with the input logical sub-vector // from (first_ele_offset_in,sub_dim_in,global_offset_in) OrdType overlap_first_local_ele_off = 0; OrdType overlap_local_sub_dim = 0; OrdType overlap_global_off = 0; if(localSubDim_) { RTOp_parallel_calc_overlap( globalDim_, localSubDim_, localOffset_, first_ele_offset_in, sub_dim_in, global_offset_in ,&overlap_first_local_ele_off, &overlap_local_sub_dim, &overlap_global_off ); } const Range1D local_rng = ( overlap_first_local_ele_off>=0 ? Range1D( localOffset_ + overlap_first_local_ele_off, localOffset_ + overlap_first_local_ele_off + overlap_local_sub_dim - 1 ) : Range1D::Invalid ); #ifdef THYRA_SPMD_VECTOR_BASE_DUMP if(show_dump) { *out << "\noverlap_first_local_ele_off = " << overlap_first_local_ele_off << "\noverlap_local_sub_dim = " << overlap_local_sub_dim << "\noverlap_global_off = " << overlap_global_off << "\nlocal_rng = ["<<local_rng.lbound()<<","<<local_rng.ubound()<<"]" << "\n" ; } #endif // THYRA_SPMD_VECTOR_BASE_DUMP // Create sub-vector views of all of the *participating* local data Workspace<RTOpPack::ConstSubVectorView<double> > sub_vecs(wss,num_vecs); Workspace<RTOpPack::SubVectorView<double> > sub_targ_vecs(wss,num_targ_vecs); if( overlap_first_local_ele_off >= 0 ) { {for(int k = 0; k < num_vecs; ++k ) { vecs[k]->acquireDetachedView( local_rng, &sub_vecs[k] ); sub_vecs[k].setGlobalOffset( overlap_global_off ); }} {for(int k = 0; k < num_targ_vecs; ++k ) { targ_vecs[k]->acquireDetachedView( local_rng, &sub_targ_vecs[k] ); sub_targ_vecs[k].setGlobalOffset( overlap_global_off ); }} } // Apply the RTOp operator object (all processors must participate) const bool validSubVecs = ( localSubDim_ > 0 && overlap_first_local_ele_off >= 0 ); RTOpPack::SPMD_apply_op( locallyReplicated ? NULL : comm.get() // comm ,op // op ,num_vecs // num_vecs ,num_vecs && validSubVecs ? &sub_vecs[0] : NULL // sub_vecs ,num_targ_vecs // num_targ_vecs ,num_targ_vecs && validSubVecs ? &sub_targ_vecs[0] : NULL // targ_sub_vecs ,reduct_obj // reduct_obj ); // Free and commit the local data if( overlap_first_local_ele_off >= 0 ) { {for(int k = 0; k < num_vecs; ++k ) { sub_vecs[k].setGlobalOffset(local_rng.lbound()); vecs[k]->releaseDetachedView( &sub_vecs[k] ); }} {for(int k = 0; k < num_targ_vecs; ++k ) { sub_targ_vecs[k].setGlobalOffset(local_rng.lbound()); targ_vecs[k]->commitDetachedView( &sub_targ_vecs[k] ); }} } // Flag that we are leaving applyOp() in_applyOpImpl_ = false; #ifdef THYRA_SPMD_VECTOR_BASE_DUMP if(show_dump) { *out << "\nLeaving SpmdVectorBase<double>::applyOp(...) ...\n"; } #endif // THYRA_SPMD_VECTOR_BASE_DUMP }
void SpmdMultiVectorBase<Scalar>::mvMultiReductApplyOpImpl( const RTOpPack::RTOpT<Scalar> &pri_op, const ArrayView<const Ptr<const MultiVectorBase<Scalar> > > &multi_vecs, const ArrayView<const Ptr<MultiVectorBase<Scalar> > > &targ_multi_vecs, const ArrayView<const Ptr<RTOpPack::ReductTarget> > &reduct_objs, const Ordinal pri_global_offset_in ) const { using Teuchos::dyn_cast; using Teuchos::Workspace; Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get(); const Ordinal numCols = this->domain()->dim(); const SpmdVectorSpaceBase<Scalar> &spmdSpc = *spmdSpace(); #ifdef TEUCHOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( in_applyOp_, std::invalid_argument, "SpmdMultiVectorBase<>::mvMultiReductApplyOpImpl(...): Error, this method is" " being entered recursively which is a clear sign that one of the methods" " acquireDetachedView(...), releaseDetachedView(...) or commitDetachedView(...)" " was not implemented properly!" ); apply_op_validate_input( "SpmdMultiVectorBase<>::mvMultiReductApplyOpImpl(...)", *this->domain(), *this->range(), pri_op, multi_vecs, targ_multi_vecs, reduct_objs, pri_global_offset_in); #endif // Flag that we are in applyOp() in_applyOp_ = true; // First see if this is a locally replicated vector in which case // we treat this as a local operation only. const bool locallyReplicated = (localSubDim_ == globalDim_); const Range1D local_rng(localOffset_, localOffset_+localSubDim_-1); const Range1D col_rng(0, numCols-1); // Create sub-vector views of all of the *participating* local data Workspace<RTOpPack::ConstSubMultiVectorView<Scalar> > sub_multi_vecs(wss,multi_vecs.size()); Workspace<RTOpPack::SubMultiVectorView<Scalar> > targ_sub_multi_vecs(wss,targ_multi_vecs.size()); for(int k = 0; k < multi_vecs.size(); ++k ) { multi_vecs[k]->acquireDetachedView(local_rng, col_rng, &sub_multi_vecs[k]); sub_multi_vecs[k].setGlobalOffset(localOffset_+pri_global_offset_in); } for(int k = 0; k < targ_multi_vecs.size(); ++k ) { targ_multi_vecs[k]->acquireDetachedView(local_rng, col_rng, &targ_sub_multi_vecs[k]); targ_sub_multi_vecs[k].setGlobalOffset(localOffset_+pri_global_offset_in); } Workspace<RTOpPack::ReductTarget*> reduct_objs_ptr(wss, reduct_objs.size()); for (int k = 0; k < reduct_objs.size(); ++k) { reduct_objs_ptr[k] = &*reduct_objs[k]; } // Apply the RTOp operator object (all processors must participate) RTOpPack::SPMD_apply_op( locallyReplicated ? NULL : spmdSpc.getComm().get(), // comm pri_op, // op col_rng.size(), // num_cols multi_vecs.size(), // multi_vecs.size() multi_vecs.size() ? &sub_multi_vecs[0] : NULL, // sub_multi_vecs targ_multi_vecs.size(), // targ_multi_vecs.size() targ_multi_vecs.size() ? &targ_sub_multi_vecs[0] : NULL, // targ_sub_multi_vecs reduct_objs.size() ? &reduct_objs_ptr[0] : 0 // reduct_objs ); // Free and commit the local data for(int k = 0; k < multi_vecs.size(); ++k ) { sub_multi_vecs[k].setGlobalOffset(local_rng.lbound()); multi_vecs[k]->releaseDetachedView( &sub_multi_vecs[k] ); } for(int k = 0; k < targ_multi_vecs.size(); ++k ) { targ_sub_multi_vecs[k].setGlobalOffset(local_rng.lbound()); targ_multi_vecs[k]->commitDetachedView( &targ_sub_multi_vecs[k] ); } // Flag that we are leaving applyOp() in_applyOp_ = false; }