42 #ifndef THYRA_SPMD_MULTI_VECTOR_DEFAULT_BASE_DEF_HPP 
   43 #define THYRA_SPMD_MULTI_VECTOR_DEFAULT_BASE_DEF_HPP 
   46 #if defined (__clang__) && !defined (__INTEL_COMPILER) 
   47 #pragma clang system_header 
   51 #include "Thyra_SpmdMultiVectorDefaultBase_decl.hpp" 
   52 #include "Thyra_MultiVectorDefaultBase.hpp" 
   53 #include "Thyra_MultiVectorAdapterBase.hpp" 
   54 #include "Thyra_SpmdVectorSpaceDefaultBase.hpp" 
   55 #include "Thyra_DetachedMultiVectorView.hpp" 
   56 #include "Thyra_apply_op_helper.hpp" 
   57 #include "Thyra_SpmdLocalDataAccess.hpp" 
   58 #include "RTOpPack_SPMD_apply_op.hpp" 
   59 #include "RTOp_parallel_helpers.h" 
   60 #include "Teuchos_Workspace.hpp" 
   61 #include "Teuchos_dyn_cast.hpp" 
   62 #include "Teuchos_Time.hpp" 
   63 #include "Teuchos_CommHelpers.hpp" 
   76 template<
class Scalar>
 
   89 template<
class Scalar>
 
   94     this->spmdSpace(), true
 
  102 template<
class Scalar>
 
  106   using Teuchos::outArg;
 
  109   this->getNonconstLocalData(outArg(localValues), outArg(leadingDim));
 
  121 template<
class Scalar>
 
  125   using Teuchos::outArg;
 
  128   this->getLocalData(outArg(localValues), outArg(leadingDim));
 
  143 template<
class Scalar>
 
  149   const Ordinal pri_global_offset_in
 
  155   using Teuchos::rcpFromPtr;
 
  159   const Ordinal numCols = this->domain()->dim();
 
  164     in_applyOp_, std::invalid_argument,
 
  165     "SpmdMultiVectorDefaultBase<>::mvMultiReductApplyOpImpl(...): Error, this method is" 
  166     " being entered recursively which is a clear sign that one of the methods" 
  167     " acquireDetachedView(...), releaseDetachedView(...) or commitDetachedView(...)" 
  168     " was not implemented properly!" 
  171     "SpmdMultiVectorDefaultBase<>::mvMultiReductApplyOpImpl(...)", *this->domain(),
 
  172     *this->range(), pri_op, multi_vecs, targ_multi_vecs, reduct_objs,
 
  173     pri_global_offset_in);
 
  183   const Range1D local_rng(localOffset_, localOffset_+localSubDim_-1);
 
  184   const Range1D col_rng(0, numCols-1);
 
  187   Workspace<RTOpPack::ConstSubMultiVectorView<Scalar> >
 
  188     sub_multi_vecs(wss,multi_vecs.size());
 
  189   Workspace<RTOpPack::SubMultiVectorView<Scalar> >
 
  190     targ_sub_multi_vecs(wss,targ_multi_vecs.size());
 
  191   for(
int k = 0; k < multi_vecs.size(); ++k ) {
 
  192     sub_multi_vecs[k] = getLocalSubMultiVectorView<Scalar>(rcpFromPtr(multi_vecs[k]));
 
  193     sub_multi_vecs[k].setGlobalOffset(localOffset_+pri_global_offset_in);
 
  195   for(
int k = 0; k < targ_multi_vecs.size(); ++k ) {
 
  196     targ_sub_multi_vecs[k] =
 
  197       getNonconstLocalSubMultiVectorView<Scalar>(rcpFromPtr(targ_multi_vecs[k]));
 
  198     targ_sub_multi_vecs[k].setGlobalOffset(localOffset_+pri_global_offset_in);
 
  200   Workspace<RTOpPack::ReductTarget*> reduct_objs_ptr(wss, reduct_objs.size());
 
  201   for (
int k = 0; k < reduct_objs.size(); ++k) {
 
  202     reduct_objs_ptr[k] = &*reduct_objs[k];
 
  206   RTOpPack::SPMD_apply_op(
 
  207     locallyReplicated ? NULL : spmdSpc.
getComm().
get(), 
 
  210     sub_multi_vecs.size(), 
 
  211     sub_multi_vecs.getRawPtr(), 
 
  212     targ_sub_multi_vecs.size(), 
 
  213     targ_sub_multi_vecs.getRawPtr(), 
 
  214     reduct_objs_ptr.getRawPtr() 
 
  218   for(
int k = 0; k < multi_vecs.size(); ++k ) {
 
  221   for(
int k = 0; k < targ_multi_vecs.size(); ++k ) {
 
  231 template<
class Scalar>
 
  238   using Teuchos::outArg;
 
  239   const Range1D rowRng = validateRowRange(rowRng_in);
 
  240   const Range1D colRng = validateColRange(colRng_in);
 
  241   if( rowRng.
lbound() < localOffset_ || localOffset_+localSubDim_-1 < rowRng.
ubound() ) {
 
  244       rowRng_in,colRng_in,sub_mv
 
  250   this->getLocalData(outArg(localValues), outArg(leadingDim));
 
  257     +(rowRng.
lbound()-localOffset_)
 
  258     +colRng.
lbound()*leadingDim, 
 
  264 template<
class Scalar>
 
  283 template<
class Scalar>
 
  290   using Teuchos::outArg;
 
  291   const Range1D rowRng = validateRowRange(rowRng_in);
 
  292   const Range1D colRng = validateColRange(colRng_in);
 
  294     rowRng.
lbound() < localOffset_
 
  296     localOffset_+localSubDim_-1 < rowRng.
ubound()
 
  301       rowRng_in, colRng_in, sub_mv
 
  307   this->getNonconstLocalData(outArg(localValues), outArg(leadingDim));
 
  314     +(rowRng.
lbound()-localOffset_)
 
  315     +colRng.
lbound()*leadingDim 
 
  321 template<
class Scalar>
 
  343 template<
class Scalar>
 
  354   using Teuchos::rcpFromPtr;
 
  357 #ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  391   const int procRank = (
nonnull(comm) ? comm->getRank() : 0 );
 
  395     &Y_range = *Y->range(),
 
  396     &X_range = *X.
range();
 
  399     ( globalDim_ > localSubDim_ ) && 
is_null(comm), std::logic_error
 
  400     ,
"SpmdMultiVectorDefaultBase<Scalar>::apply(...MultiVectorBase<Scalar>...): Error!" 
  407     ,
"SpmdMultiVectorDefaultBase<Scalar>::apply(...MultiVectorBase<Scalar>...): Error!" 
  411     ,
"SpmdMultiVectorDefaultBase<Scalar>::apply(...MultiVectorBase<Scalar>...): Error!" 
  419 #ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  424     Y_local = getNonconstLocalSubMultiVectorView<Scalar>(rcpFromPtr(Y));
 
  426     M_local = getLocalSubMultiVectorView<Scalar>(rcpFromRef(*
this)),
 
  427     X_local = getLocalSubMultiVectorView<Scalar>(rcpFromRef(X));
 
  448 #ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  450   std::cout << 
"\nSpmdMultiVectorDefaultBase<Scalar>::apply(...): Time for getting view = " << timer.
totalElapsedTime() << 
" seconds\n";
 
  456     ,
"SpmdMultiVectorDefaultBase<Scalar>::apply(...MultiVectorBase<Scalar>...): Error!" 
  461     ,
"SpmdMultiVectorDefaultBase<Scalar>::apply(...MultiVectorBase<Scalar>...): Error!" 
  490 #ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  496   bool locallyReplicated = 
false;
 
  499     bool locallyReplicated_x    = locallyReplicated_this; 
 
  500     bool locallyReplicated_y    = 
false;
 
  504       locallyReplicated_y = spmd_Y->spmdSpace()->isLocallyReplicated();
 
  506     locallyReplicated = locallyReplicated_this && locallyReplicated_x && locallyReplicated_y;
 
  509   bool isNonLocalAdjoint = 
 
  513       (globalDim_ > localSubDim_  || (
nonnull(comm) && comm->getSize() > 1))
 
  516   if (locallyReplicated)
 
  517     isNonLocalAdjoint = 
false;
 
  519   Workspace<Scalar> Y_local_tmp_store(wss, Y_local.
subDim()*Y_local.
numSubCols(), 
false);
 
  522   if (isNonLocalAdjoint) {
 
  527       Teuchos::arcpFromArrayView(Y_local_tmp_store()),
 
  532       for( 
int j = 0; j < Y_local.
numSubCols(); ++j ) {
 
  534         const Y_local_values_iter_t Y_local_j =
 
  536         std::copy( Y_local_j, Y_local_j + Y_local.
subDim(),
 
  537           Y_local_tmp.values().begin() + Y_local_tmp.leadingDim()*j );
 
  548     Y_local_tmp = Y_local; 
 
  552 #ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  554   std::cout << 
"\nSpmdMultiVectorDefaultBase<Scalar>::apply(...): Time for setting up Y_local_tmp and localBeta = " << timer.
totalElapsedTime() << 
" seconds\n";
 
  567 #ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  586   if (M_local.numSubCols() > 0) {
 
  596       ,
const_cast<Scalar*
>(M_local.values().getRawPtr()) 
 
  597       ,std::max((
int) M_local.leadingDim(),1) 
 
  598       ,const_cast<Scalar*>(X_local.values().getRawPtr()) 
 
  599       ,std::max((
int) X_local.leadingDim(),1) 
 
  601       ,Y_local_tmp.values().getRawPtr() 
 
  602       ,std::max((
int) Y_local_tmp.leadingDim(),1) 
 
  606     std::fill( Y_local_tmp.values().begin(), Y_local_tmp.values().end(),
 
  609 #ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  612     << 
"\nSpmdMultiVectorDefaultBase<Scalar>::apply(...): Time for GEMM = " 
  622     if (isNonLocalAdjoint) {
 
  624       Workspace<Scalar> Y_local_final_buff(wss,Y_local.
subDim()*Y_local.
numSubCols(),
false);
 
  626       Teuchos::reduceAll<Ordinal,Scalar>(
 
  628         Y_local_final_buff.getRawPtr()
 
  633       Y_local_final_buff_iter_t Y_local_final_buff_ptr = Y_local_final_buff_av.
begin();
 
  634       for( 
int j = 0; j < Y_local.
numSubCols(); ++j ) {
 
  636         Y_local_values_iter_t Y_local_ptr =
 
  638         for( 
int i = 0; i < Y_local.
subDim(); ++i ) {
 
  639           (*Y_local_ptr++) = (*Y_local_final_buff_ptr++);
 
  651 #ifdef THYRA_SPMD_MULTI_VECTOR_BASE_PRINT_TIMES 
  654     << 
"\nSpmdMultiVectorDefaultBase<Scalar>::apply(...): Total time = " 
  664 template<
class Scalar>
 
  667   if(globalDim_ == 0) {
 
  670       globalDim_ = l_spmdSpace->
dim();
 
  673       numCols_ = this->domain()->dim();
 
  685 template<
class Scalar>
 
  688   const Range1D rowRng = Teuchos::full_range(rowRng_in,0,globalDim_-1);
 
  691     !( 0 <= rowRng.
lbound() && rowRng.
ubound() < globalDim_ ), std::invalid_argument
 
  692     ,
"SpmdMultiVectorDefaultBase<Scalar>::validateRowRange(rowRng): Error, the range rowRng = [" 
  694     "in the range [0,"<<(globalDim_-1)<<
"]!" 
  701 template<
class Scalar>
 
  704   const Range1D colRng = Teuchos::full_range(colRng_in,0,numCols_-1);
 
  707     !(0 <= colRng.
lbound() && colRng.
ubound() < numCols_), std::invalid_argument
 
  708     ,
"SpmdMultiVectorDefaultBase<Scalar>::validateColRange(colRng): Error, the range colRng = [" 
  710     "in the range [0,"<<(numCols_-1)<<
"]!" 
  720 #endif // THYRA_SPMD_MULTI_VECTOR_DEFAULT_BASE_DEF_HPP 
SpmdMultiVectorDefaultBase()
 
Ordinal numSubCols() const 
 
bool is_null(const boost::shared_ptr< T > &p)
 
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator. 
 
EOpTransp
Enumeration for determining how a linear operator is applied. `*. 
 
virtual void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const 
 
Thrown if vector spaces are incompatible. 
 
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(). 
 
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. 
 
Base interface class for SPMD multi-vectors. 
 
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 
 
virtual void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
 
Use the non-transposed operator. 
 
const_pointer const_iterator
 
T_To & dyn_cast(T_From &from)
 
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
 
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types)...
 
const ArrayRCP< Scalar > values() const 
 
Abstract interface for objects that represent a space for vectors. 
 
Ordinal globalOffset() const 
 
RTOpPack::ConstSubMultiVectorView< Scalar > getLocalSubMultiVectorImpl() const 
 
Use the transposed operator. 
 
RCP< const ScalarProdVectorSpaceBase< Scalar > > rangeScalarProdVecSpc() const 
Returns spmdSpace. 
 
void start(bool reset=false)
 
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*. 
 
Interface for a collection of column vectors called a multi-vector. 
 
Ordinal leadingDim() const 
 
void initialize(Ordinal globalOffset_in, Ordinal subDim_in, Ordinal colOffset_in, Ordinal numSubCols_in, const ArrayRCP< Scalar > &values_in, Ordinal leadingDim_in)
 
virtual void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
 
void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const 
 
void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
 
bool nonnull(const boost::shared_ptr< T > &p)
 
virtual Teuchos::RCP< const Teuchos::Comm< Ordinal > > getComm() const =0
Returns the SPMD communicator. 
 
virtual Ordinal localOffset() const =0
Returns the offset for the local sub-vector stored on this process. 
 
void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const 
 
double totalElapsedTime(bool readCurrentTime=false) const 
 
void initialize(Ordinal globalOffset_in, Ordinal subDim_in, Ordinal colOffset_in, Ordinal numSubCols_in, const ArrayRCP< const Scalar > &values_in, Ordinal leadingDim_in)
 
Range1D validateColRange(const Range1D &rowCol) const 
Validate and resize the column range. 
 
virtual void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const 
 
void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
 
virtual bool isCompatible(const VectorSpaceBase< Scalar > &vecSpc) const =0
Compare the compatibility of two vector spaces. 
 
Base abstract VectorSpaceBase class for all SPMD-based vector spaces. 
 
virtual Ordinal dim() const =0
Return the dimension of the vector space. 
 
virtual void updateSpmdSpace()
Subclasses should call whenever the structure of the VectorSpaceBase changes. 
 
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
 
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()
 
virtual bool isLocallyReplicated() const =0
Returns true if vector space is locally replicated space. 
 
Range1D validateRowRange(const Range1D &rowRng) const 
Validate and resize the row range. 
 
virtual Ordinal localSubDim() const =0
Returns the number of local elements stored on this process.