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();
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());
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());
225 ,
"DefaultClusteredSpmdProductVector::applyOp(...): Error targ_vecs["<<k<<
"]->space() "
226 <<
"of type \'"<<typeName(*vecs[k]->space())<<
"\' is not compatible with this "
227 <<
"\'VectorSpaceBlocked\' vector space!"
237 for (
int k = 0; k < num_vecs; ++k ) {
241 cl_vecs[k] = ptr_dynamic_cast<const DefaultClusteredSpmdProductVector<Scalar> >(vecs[k],
true);
244 for (
int k = 0; k < num_targ_vecs; ++k ) {
248 cl_targ_vecs[k] = ptr_dynamic_cast<DefaultClusteredSpmdProductVector<Scalar> >(targ_vecs[k],
true);
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
278 if (!is_null(reduct_obj))
282 const int numBlocks = vecs_.size();
283 if (overlap_first_cluster_ele_off >=0) {
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();
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)) {
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()