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"
44 template<
class Scalar>
57 template<
class Scalar>
62 this->spmdSpace(), true
70 template<
class Scalar>
74 using Teuchos::outArg;
77 this->getNonconstLocalData(outArg(localValues), outArg(leadingDim));
89 template<
class Scalar>
93 using Teuchos::outArg;
96 this->getLocalData(outArg(localValues), outArg(leadingDim));
111 template<
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 ) {
199 template<
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,
232 template<
class Scalar>
251 template<
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
289 template<
class Scalar>
311 template<
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(),
505 Y_local_tmp.values().begin() + Y_local_tmp.leadingDim()*j );
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
554 if (M_local.numSubCols() > 0) {
564 ,
const_cast<Scalar*
>(M_local.values().getRawPtr())
565 ,std::max((
int) M_local.leadingDim(),1)
566 ,const_cast<Scalar*>(X_local.values().getRawPtr())
567 ,std::max((
int) X_local.leadingDim(),1)
569 ,Y_local_tmp.values().getRawPtr()
570 ,std::max((
int) Y_local_tmp.leadingDim(),1)
574 std::fill( Y_local_tmp.values().begin(), Y_local_tmp.values().end(),
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);
594 Teuchos::reduceAll<Ordinal,Scalar>(
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 = "
632 template<
class Scalar>
635 if(globalDim_ == 0) {
638 globalDim_ = l_spmdSpace->
dim();
641 numCols_ = this->domain()->dim();
653 template<
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)<<
"]!"
669 template<
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)<<
"]!"
688 #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.