42 #ifndef THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_HPP 43 #define THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_HPP 45 #include "Thyra_DefaultClusteredSpmdProductVector_decl.hpp" 46 #include "Thyra_DefaultClusteredSpmdProductVectorSpace.hpp" 47 #include "Thyra_SpmdVectorBase.hpp" 48 #include "RTOp_parallel_helpers.h" 49 #include "RTOpPack_SPMD_apply_op.hpp" 50 #include "Teuchos_Workspace.hpp" 51 #include "Teuchos_dyn_cast.hpp" 52 #include "Teuchos_implicit_cast.hpp" 61 template <
class Scalar>
68 template <
class Scalar>
74 initialize(productSpace_in,vecs);
78 template <
class Scalar>
85 productSpace_ = productSpace_in;
86 const int numBlocks = productSpace_->numBlocks();
87 vecs_.resize(numBlocks);
89 std::copy( vecs, vecs + numBlocks, &vecs_[0] );
92 for(
int k = 0; k < numBlocks; ++k )
93 vecs_[k] = createMember(productSpace_->getBlock(k));
98 template <
class Scalar>
104 const int numBlocks = vecs_.size();
105 if(productSpace_in) *productSpace_in = productSpace_;
106 if(vecs) std::copy( &vecs_[0], &vecs_[0]+numBlocks, vecs );
107 productSpace_ = Teuchos::null;
115 template <
class Scalar>
116 Teuchos::RCP<VectorBase<Scalar> >
119 using Teuchos::implicit_cast;
120 TEUCHOS_TEST_FOR_EXCEPT( ! ( 0 <= k && k < implicit_cast<int>(vecs_.size()) ) );
125 template <
class Scalar>
126 Teuchos::RCP<const VectorBase<Scalar> >
129 using Teuchos::implicit_cast;
130 TEUCHOS_TEST_FOR_EXCEPT( ! ( 0 <= k && k < implicit_cast<int>(vecs_.size()) ) );
138 template <
class Scalar>
139 Teuchos::RCP<const ProductVectorSpaceBase<Scalar> >
142 return productSpace_;
146 template <
class Scalar>
149 using Teuchos::implicit_cast;
150 TEUCHOS_TEST_FOR_EXCEPT( ! ( 0 <= k && k < implicit_cast<int>(vecs_.size()) ) );
155 template <
class Scalar>
156 Teuchos::RCP<MultiVectorBase<Scalar> >
159 return getNonconstVectorBlock(k);
163 template <
class Scalar>
164 Teuchos::RCP<const MultiVectorBase<Scalar> >
167 return getVectorBlock(k);
174 template <
class Scalar>
175 Teuchos::RCP< const VectorSpaceBase<Scalar> >
178 return productSpace_;
185 template <
class Scalar>
190 const Ptr<RTOpPack::ReductTarget> &reduct_obj,
195 const Ordinal first_ele_offset_in = 0;
199 using Teuchos::ptr_dynamic_cast;
200 using Teuchos::tuple;
202 const int num_vecs = vecs.size();
203 const int num_targ_vecs = targ_vecs.size();
207 TEUCHOS_TEST_FOR_EXCEPTION(
208 global_offset_in < 0, std::invalid_argument,
209 "DefaultClusteredSpmdProductVector::applyOp(...): Error, " 210 "global_offset_in = " << global_offset_in <<
" is not acceptable" );
212 for (
int k = 0; k < num_vecs; ++k) {
213 test_failed = !this->space()->isCompatible(*vecs[k]->space());
214 TEUCHOS_TEST_FOR_EXCEPTION(
216 "DefaultClusteredSpmdProductVector::applyOp(...): Error vecs["<<k<<
"]->space() " 217 <<
"of type \'"<<typeName(*vecs[k]->space())<<
"\' is not compatible with this " 218 <<
"\'VectorSpaceBlocked\' vector space!" 221 for (
int k = 0; k < num_targ_vecs; ++k) {
222 test_failed = !this->space()->isCompatible(*targ_vecs[k]->space());
223 TEUCHOS_TEST_FOR_EXCEPTION(
225 ,
"DefaultClusteredSpmdProductVector::applyOp(...): Error targ_vecs["<<k<<
"]->space() " 226 <<
"of type \'"<<typeName(*vecs[k]->space())<<
"\' is not compatible with this " 227 <<
"\'VectorSpaceBlocked\' vector space!" 236 Array<Ptr<const DefaultClusteredSpmdProductVector<Scalar> > > cl_vecs(num_vecs);
237 for (
int k = 0; k < num_vecs; ++k ) {
239 TEUCHOS_TEST_FOR_EXCEPT(vecs[k]==null);
243 Array<Ptr<DefaultClusteredSpmdProductVector<Scalar> > > cl_targ_vecs(num_targ_vecs);
244 for (
int k = 0; k < num_targ_vecs; ++k ) {
246 TEUCHOS_TEST_FOR_EXCEPT(targ_vecs[k]==null);
255 const Teuchos::RCP<const Teuchos::Comm<Ordinal> >
256 intraClusterComm = productSpace_->intraClusterComm(),
257 interClusterComm = productSpace_->interClusterComm();
259 clusterSubDim = productSpace_->clusterSubDim(),
260 clusterOffset = productSpace_->clusterOffset(),
261 globalDim = productSpace_->dim();
262 Ordinal overlap_first_cluster_ele_off = 0;
263 Ordinal overlap_cluster_sub_dim = 0;
264 Ordinal overlap_global_off = 0;
266 RTOp_parallel_calc_overlap(
267 globalDim,clusterSubDim,clusterOffset,first_ele_offset_in,sub_dim_in
269 ,&overlap_first_cluster_ele_off,&overlap_cluster_sub_dim,&overlap_global_off
277 Teuchos::RCP<RTOpPack::ReductTarget> i_reduct_obj;
278 if (!is_null(reduct_obj))
282 const int numBlocks = vecs_.size();
283 if (overlap_first_cluster_ele_off >=0) {
289 Array<Ptr<const VectorBase<Scalar> > > v_vecs(num_vecs);
290 Array<Ptr<VectorBase<Scalar> > > v_targ_vecs(num_targ_vecs);
291 Ordinal overall_global_offset = overlap_global_off;
292 for(
int j = 0; j < numBlocks; ++j ) {
296 &v_space = *v.
space();
298 for(
int k = 0; k < num_vecs ; ++k )
299 v_vecs[k] = cl_vecs[k]->vecs_[j].ptr();
300 for(
int k = 0; k < num_targ_vecs ; ++k )
301 v_targ_vecs[k] = cl_targ_vecs[k]->vecs_[j].ptr();
302 TEUCHOS_TEST_FOR_EXCEPTION(
303 numBlocks > 1, std::logic_error
304 ,
"Error, Have not implemented general support for numBlocks > 1!" 306 Ordinal v_global_offset = overall_global_offset;
308 Thyra::applyOp<Scalar>(
309 op, v_vecs(), v_targ_vecs(), i_reduct_obj.ptr(),
312 overall_global_offset += v_space.
dim();
322 if (!is_null(reduct_obj)) {
323 Teuchos::RCP<RTOpPack::ReductTarget>
328 if (interClusterComm.get()) {
329 RTOpPack::SPMD_all_reduce(
333 tuple<const RTOpPack::ReductTarget*>(&*i_reduct_obj).getRawPtr(),
334 tuple<RTOpPack::ReductTarget*>(&*icl_reduct_obj).getRawPtr()
342 RTOpPack::SPMD_all_reduce(
346 tuple<const RTOpPack::ReductTarget*>(&*icl_reduct_obj).getRawPtr(),
347 tuple<RTOpPack::ReductTarget*>(&*reduct_obj).getRawPtr()
360 #endif // THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_HPP virtual RCP< const VectorSpaceBase< Scalar > > space() const =0
Return a smart pointer to the vector space that this vector belongs to.
void uninitialize(Teuchos::RCP< const DefaultClusteredSpmdProductVectorSpace< Scalar > > *productSpace=NULL, Teuchos::RCP< VectorBase< Scalar > > vecs[]=NULL)
Uninitialize.
Thrown if vector spaces are incompatible.
Teuchos::RCP< const VectorBase< Scalar > > getVectorBlock(const int k) const
Abstract interface for objects that represent a space for vectors.
Teuchos::RCP< const VectorSpaceBase< Scalar > > space() const
Teuchos::RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
void initialize(const Teuchos::RCP< const DefaultClusteredSpmdProductVectorSpace< Scalar > > &productSpace, const Teuchos::RCP< VectorBase< Scalar > > vecs[])
Initialize.
Teuchos::RCP< ReductTarget > reduct_obj_create() const
void applyOpImpl(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) const
Teuchos::RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)
Concrete implementation of a clustered Spmd-based product vector.
Abstract interface for finite-dimensional dense vectors.
Teuchos::RCP< const ProductVectorSpaceBase< Scalar > > productSpace() const
bool blockIsConst(const int k) const
Teuchos::RCP< VectorBase< Scalar > > getNonconstVectorBlock(const int k)
virtual Ordinal dim() const =0
Return the dimension of the vector space.
DefaultClusteredSpmdProductVector()
Constructs to uninitialized (see postconditions for uninitialize()).