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!
}
Beispiel #2
0
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);
  }
}
Beispiel #4
0
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());
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
  }
}
Beispiel #15
0
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_ );
}
Beispiel #16
0
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())
      )
    );
}
Beispiel #24
0
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);
}
Beispiel #25
0
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;
}
Beispiel #28
0
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
}
Beispiel #29
0
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;

}