10#ifndef THYRA_SPMD_MULTI_VECTOR_DEFAULT_BASE_DEF_HPP 
   11#define THYRA_SPMD_MULTI_VECTOR_DEFAULT_BASE_DEF_HPP 
   14#if defined (__clang__) && !defined (__INTEL_COMPILER) 
   15#pragma clang system_header 
   19#include "Thyra_SpmdMultiVectorDefaultBase_decl.hpp" 
   20#include "Thyra_MultiVectorDefaultBase.hpp" 
   21#include "Thyra_MultiVectorAdapterBase.hpp" 
   22#include "Thyra_SpmdVectorSpaceDefaultBase.hpp" 
   23#include "Thyra_DetachedMultiVectorView.hpp" 
   24#include "Thyra_apply_op_helper.hpp" 
   25#include "Thyra_SpmdLocalDataAccess.hpp" 
   26#include "RTOpPack_SPMD_apply_op.hpp" 
   27#include "RTOp_parallel_helpers.h" 
   28#include "Teuchos_Workspace.hpp" 
   29#include "Teuchos_dyn_cast.hpp" 
   30#include "Teuchos_Time.hpp" 
   31#include "Teuchos_CommHelpers.hpp" 
   62    this->spmdSpace(), true
 
 
   74  using Teuchos::outArg;
 
   77  this->getNonconstLocalData(outArg(localValues), outArg(leadingDim));
 
 
   93  using Teuchos::outArg;
 
   96  this->getLocalData(outArg(localValues), outArg(leadingDim));
 
 
  111template<
class Scalar>
 
  117  const Ordinal pri_global_offset_in
 
  123  using Teuchos::rcpFromPtr;
 
  127  const Ordinal numCols = this->domain()->dim();
 
  132    in_applyOp_, std::invalid_argument,
 
  133    "SpmdMultiVectorDefaultBase<>::mvMultiReductApplyOpImpl(...): Error, this method is" 
  134    " being entered recursively which is a clear sign that one of the methods" 
  135    " acquireDetachedView(...), releaseDetachedView(...) or commitDetachedView(...)" 
  136    " was not implemented properly!" 
  139    "SpmdMultiVectorDefaultBase<>::mvMultiReductApplyOpImpl(...)", *this->domain(),
 
  140    *this->range(), pri_op, multi_vecs, targ_multi_vecs, reduct_objs,
 
  141    pri_global_offset_in);
 
  151  const Range1D local_rng(localOffset_, localOffset_+localSubDim_-1);
 
  152  const Range1D col_rng(0, numCols-1);
 
  155  Workspace<RTOpPack::ConstSubMultiVectorView<Scalar> >
 
  156    sub_multi_vecs(wss,multi_vecs.size());
 
  157  Workspace<RTOpPack::SubMultiVectorView<Scalar> >
 
  158    targ_sub_multi_vecs(wss,targ_multi_vecs.size());
 
  159  for(
int k = 0; k < multi_vecs.size(); ++k ) {
 
  160    sub_multi_vecs[k] = getLocalSubMultiVectorView<Scalar>(rcpFromPtr(multi_vecs[k]));
 
  161    sub_multi_vecs[k].setGlobalOffset(localOffset_+pri_global_offset_in);
 
  163  for(
int k = 0; k < targ_multi_vecs.size(); ++k ) {
 
  164    targ_sub_multi_vecs[k] =
 
  165      getNonconstLocalSubMultiVectorView<Scalar>(rcpFromPtr(targ_multi_vecs[k]));
 
  166    targ_sub_multi_vecs[k].setGlobalOffset(localOffset_+pri_global_offset_in);
 
  168  Workspace<RTOpPack::ReductTarget*> reduct_objs_ptr(wss, reduct_objs.size());
 
  169  for (
int k = 0; k < reduct_objs.size(); ++k) {
 
  170    reduct_objs_ptr[k] = &*reduct_objs[k];
 
  174  RTOpPack::SPMD_apply_op(
 
  175    locallyReplicated ? NULL : spmdSpc.
getComm().
get(), 
 
  178    sub_multi_vecs.size(), 
 
  179    sub_multi_vecs.getRawPtr(), 
 
  180    targ_sub_multi_vecs.size(), 
 
  181    targ_sub_multi_vecs.getRawPtr(), 
 
  182    reduct_objs_ptr.getRawPtr() 
 
  186  for(
int k = 0; k < multi_vecs.size(); ++k ) {
 
  189  for(
int k = 0; k < targ_multi_vecs.size(); ++k ) {
 
 
  199template<
class Scalar>
 
  206  using Teuchos::outArg;
 
  207  const Range1D rowRng = validateRowRange(rowRng_in);
 
  208  const Range1D colRng = validateColRange(colRng_in);
 
  209  if( rowRng.
lbound() < localOffset_ || localOffset_+localSubDim_-1 < rowRng.
ubound() ) {
 
  212      rowRng_in,colRng_in,sub_mv
 
  218  this->getLocalData(outArg(localValues), outArg(leadingDim));
 
  225    +(rowRng.
lbound()-localOffset_)
 
  226    +colRng.
lbound()*leadingDim, 
 
 
  232template<
class Scalar>
 
  240    localOffset_+localSubDim_ < sub_mv->globalOffset()+sub_mv->
subDim()
 
 
  251template<
class Scalar>
 
  258  using Teuchos::outArg;
 
  259  const Range1D rowRng = validateRowRange(rowRng_in);
 
  260  const Range1D colRng = validateColRange(colRng_in);
 
  262    rowRng.
lbound() < localOffset_
 
  264    localOffset_+localSubDim_-1 < rowRng.
ubound()
 
  269      rowRng_in, colRng_in, sub_mv
 
  275  this->getNonconstLocalData(outArg(localValues), outArg(leadingDim));
 
  282    +(rowRng.
lbound()-localOffset_)
 
  283    +colRng.
lbound()*leadingDim 
 
 
  289template<
class Scalar>
 
  297    localOffset_+localSubDim_ < sub_mv->globalOffset()+sub_mv->
subDim()
 
 
  311template<
class Scalar>
 
  322  using Teuchos::rcpFromPtr;
 
  325#ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  359  const int procRank = (nonnull(comm) ? comm->getRank() : 0 );
 
  363    &Y_range = *Y->range(),
 
  364    &X_range = *X.
range();
 
  367    ( globalDim_ > localSubDim_ ) && is_null(comm), std::logic_error
 
  368    ,
"SpmdMultiVectorDefaultBase<Scalar>::apply(...MultiVectorBase<Scalar>...): Error!" 
  375    ,
"SpmdMultiVectorDefaultBase<Scalar>::apply(...MultiVectorBase<Scalar>...): Error!" 
  379    ,
"SpmdMultiVectorDefaultBase<Scalar>::apply(...MultiVectorBase<Scalar>...): Error!" 
  387#ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  392    Y_local = getNonconstLocalSubMultiVectorView<Scalar>(rcpFromPtr(Y));
 
  394    M_local = getLocalSubMultiVectorView<Scalar>(rcpFromRef(*
this)),
 
  395    X_local = getLocalSubMultiVectorView<Scalar>(rcpFromRef(X));
 
  416#ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  418  std::cout << 
"\nSpmdMultiVectorDefaultBase<Scalar>::apply(...): Time for getting view = " << timer.
totalElapsedTime() << 
" seconds\n";
 
  424    ,
"SpmdMultiVectorDefaultBase<Scalar>::apply(...MultiVectorBase<Scalar>...): Error!" 
  429    ,
"SpmdMultiVectorDefaultBase<Scalar>::apply(...MultiVectorBase<Scalar>...): Error!" 
  458#ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  464  bool locallyReplicated = 
false;
 
  467    bool locallyReplicated_x    = locallyReplicated_this; 
 
  468    bool locallyReplicated_y    = 
false;
 
  472      locallyReplicated_y = spmd_Y->spmdSpace()->isLocallyReplicated();
 
  474    locallyReplicated = locallyReplicated_this && locallyReplicated_x && locallyReplicated_y;
 
  477  bool isNonLocalAdjoint = 
 
  481      (globalDim_ > localSubDim_  || (nonnull(comm) && comm->getSize() > 1))
 
  484  if (locallyReplicated)
 
  485    isNonLocalAdjoint = 
false;
 
  487  Workspace<Scalar> Y_local_tmp_store(wss, Y_local.
subDim()*Y_local.
numSubCols(), 
false);
 
  490  if (isNonLocalAdjoint) {
 
  495      Teuchos::arcpFromArrayView(Y_local_tmp_store()),
 
  500      for( 
int j = 0; j < Y_local.
numSubCols(); ++j ) {
 
  502        const Y_local_values_iter_t Y_local_j =
 
  504        std::copy( Y_local_j, Y_local_j + Y_local.
subDim(),
 
  516    Y_local_tmp = Y_local; 
 
  520#ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  522  std::cout << 
"\nSpmdMultiVectorDefaultBase<Scalar>::apply(...): Time for setting up Y_local_tmp and localBeta = " << timer.
totalElapsedTime() << 
" seconds\n";
 
  535#ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  566      ,
const_cast<Scalar*
>(X_local.values().getRawPtr()) 
 
  567      ,std::max((
int) X_local.leadingDim(),1) 
 
  577#ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  580    << 
"\nSpmdMultiVectorDefaultBase<Scalar>::apply(...): Time for GEMM = " 
  590    if (isNonLocalAdjoint) {
 
  592      Workspace<Scalar> Y_local_final_buff(wss,Y_local.
subDim()*Y_local.
numSubCols(),
false);
 
  596        Y_local_final_buff.getRawPtr()
 
  601      Y_local_final_buff_iter_t Y_local_final_buff_ptr = Y_local_final_buff_av.
begin();
 
  602      for( 
int j = 0; j < Y_local.
numSubCols(); ++j ) {
 
  604        Y_local_values_iter_t Y_local_ptr =
 
  606        for( 
int i = 0; i < Y_local.
subDim(); ++i ) {
 
  607          (*Y_local_ptr++) = (*Y_local_final_buff_ptr++);
 
  619#ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  622    << 
"\nSpmdMultiVectorDefaultBase<Scalar>::apply(...): Total time = " 
 
  632template<
class Scalar>
 
  635  if(globalDim_ == 0) {
 
  638      globalDim_ = l_spmdSpace->
dim();
 
  641      numCols_ = this->domain()->dim();
 
 
  653template<
class Scalar>
 
  656  const Range1D rowRng = Teuchos::full_range(rowRng_in,0,globalDim_-1);
 
  659    !( 0 <= rowRng.
lbound() && rowRng.
ubound() < globalDim_ ), std::invalid_argument
 
  660    ,
"SpmdMultiVectorDefaultBase<Scalar>::validateRowRange(rowRng): Error, the range rowRng = [" 
  662    "in the range [0,"<<(globalDim_-1)<<
"]!" 
 
  669template<
class Scalar>
 
  672  const Range1D colRng = Teuchos::full_range(colRng_in,0,numCols_-1);
 
  675    !(0 <= colRng.
lbound() && colRng.
ubound() < numCols_), std::invalid_argument
 
  676    ,
"SpmdMultiVectorDefaultBase<Scalar>::validateColRange(colRng): Error, the range colRng = [" 
  678    "in the range [0,"<<(numCols_-1)<<
"]!" 
 
const ArrayRCP< const Scalar > values() const
 
Ordinal leadingDim() const
 
void initialize(Ordinal globalOffset_in, Ordinal subDim_in, Ordinal colOffset_in, Ordinal numSubCols_in, const ArrayRCP< const Scalar > &values_in, Ordinal leadingDim_in)
 
Ordinal numSubCols() const
 
Ordinal globalOffset() const
 
void initialize(Ordinal globalOffset_in, Ordinal subDim_in, Ordinal colOffset_in, Ordinal numSubCols_in, const ArrayRCP< Scalar > &values_in, Ordinal leadingDim_in)
 
const ArrayRCP< Scalar > values() const
 
const_pointer const_iterator
 
double totalElapsedTime(bool readCurrentTime=false) const
 
void start(bool reset=false)
 
Thrown if vector spaces are incompatible.
 
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
 
Interface for a collection of column vectors called a multi-vector.
 
virtual void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
 
virtual void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
 
virtual void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
 
virtual void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
 
RCP< const ScalarProdVectorSpaceBase< Scalar > > rangeScalarProdVecSpc() const
Returns spmdSpace.
 
SpmdMultiVectorDefaultBase()
 
Range1D validateRowRange(const Range1D &rowRng) const
Validate and resize the row range.
 
Range1D validateColRange(const Range1D &rowCol) const
Validate and resize the column range.
 
void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
 
void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
 
RTOpPack::SubMultiVectorView< Scalar > getNonconstLocalSubMultiVectorImpl()
 
void euclideanApply(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
Uses GEMM() and Teuchos::reduceAll() to implement.
 
void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
 
virtual void updateSpmdSpace()
Subclasses should call whenever the structure of the VectorSpaceBase changes.
 
void mvMultiReductApplyOpImpl(const RTOpPack::RTOpT< Scalar > &primary_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 primary_global_offset) const
 
RTOpPack::ConstSubMultiVectorView< Scalar > getLocalSubMultiVectorImpl() const
 
void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
 
Base abstract VectorSpaceBase class for all SPMD-based vector spaces.
 
virtual Ordinal localSubDim() const =0
Returns the number of local elements stored on this process.
 
virtual Teuchos::RCP< const Teuchos::Comm< Ordinal > > getComm() const =0
Returns the SPMD communicator.
 
virtual bool isLocallyReplicated() const =0
Returns true if vector space is locally replicated space.
 
virtual Ordinal localOffset() const =0
Returns the offset for the local sub-vector stored on this process.
 
Abstract interface for objects that represent a space for vectors.
 
virtual Ordinal dim() const =0
Return the dimension of the vector space.
 
virtual bool isCompatible(const VectorSpaceBase< Scalar > &vecSpc) const =0
Compare the compatibility of two vector spaces.
 
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
 
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
 
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
 
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
 
@ TRANS
Use the transposed operator.
 
@ NOTRANS
Use the non-transposed operator.
 
@ CONJTRANS
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types).
 
void apply_op_validate_input(const std::string &func_name, const VectorSpaceBase< Scalar > &space, const RTOpPack::RTOpT< Scalar > &op, const ArrayView< const Ptr< const VectorBase< Scalar > > > &vecs, const ArrayView< const Ptr< VectorBase< Scalar > > > &targ_vecs, const Ptr< RTOpPack::ReductTarget > &reduct_obj, const Ordinal global_offset)
Validate the inputs to VectorBase::applyOp().
 
T_To & dyn_cast(T_From &from)
 
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()