163 const Ordinal first_ele_offset_in = 0;
167 using Teuchos::ptr_dynamic_cast;
168 using Teuchos::tuple;
170 const int num_vecs = vecs.size();
171 const int num_targ_vecs = targ_vecs.size();
176 global_offset_in < 0, std::invalid_argument,
177 "DefaultClusteredSpmdProductVector::applyOp(...): Error, "
178 "global_offset_in = " << global_offset_in <<
" is not acceptable" );
180 for (
int k = 0; k < num_vecs; ++k) {
181 test_failed = !this->space()->isCompatible(*vecs[k]->space());
184 "DefaultClusteredSpmdProductVector::applyOp(...): Error vecs["<<k<<
"]->space() "
185 <<
"of type \'"<<typeName(*vecs[k]->space())<<
"\' is not compatible with this "
186 <<
"\'VectorSpaceBlocked\' vector space!"
189 for (
int k = 0; k < num_targ_vecs; ++k) {
190 test_failed = !this->space()->isCompatible(*targ_vecs[k]->space());
193 ,
"DefaultClusteredSpmdProductVector::applyOp(...): Error targ_vecs["<<k<<
"]->space() "
194 <<
"of type \'"<<typeName(*vecs[k]->space())<<
"\' is not compatible with this "
195 <<
"\'VectorSpaceBlocked\' vector space!"
205 for (
int k = 0; k < num_vecs; ++k ) {
209 cl_vecs[k] = ptr_dynamic_cast<const DefaultClusteredSpmdProductVector<Scalar> >(vecs[k],
true);
212 for (
int k = 0; k < num_targ_vecs; ++k ) {
216 cl_targ_vecs[k] = ptr_dynamic_cast<DefaultClusteredSpmdProductVector<Scalar> >(targ_vecs[k],
true);
224 intraClusterComm = productSpace_->intraClusterComm(),
225 interClusterComm = productSpace_->interClusterComm();
227 clusterSubDim = productSpace_->clusterSubDim(),
228 clusterOffset = productSpace_->clusterOffset(),
229 globalDim = productSpace_->dim();
230 Ordinal overlap_first_cluster_ele_off = 0;
231 Ordinal overlap_cluster_sub_dim = 0;
232 Ordinal overlap_global_off = 0;
234 RTOp_parallel_calc_overlap(
235 globalDim,clusterSubDim,clusterOffset,first_ele_offset_in,sub_dim_in
237 ,&overlap_first_cluster_ele_off,&overlap_cluster_sub_dim,&overlap_global_off
246 if (!is_null(reduct_obj))
250 const int numBlocks = vecs_.size();
251 if (overlap_first_cluster_ele_off >=0) {
259 Ordinal overall_global_offset = overlap_global_off;
260 for(
int j = 0; j < numBlocks; ++j ) {
264 &v_space = *v.
space();
266 for(
int k = 0; k < num_vecs ; ++k )
267 v_vecs[k] = cl_vecs[k]->vecs_[j].ptr();
268 for(
int k = 0; k < num_targ_vecs ; ++k )
269 v_targ_vecs[k] = cl_targ_vecs[k]->vecs_[j].ptr();
271 numBlocks > 1, std::logic_error
272 ,
"Error, Have not implemented general support for numBlocks > 1!"
274 Ordinal v_global_offset = overall_global_offset;
276 Thyra::applyOp<Scalar>(
277 op, v_vecs(), v_targ_vecs(), i_reduct_obj.
ptr(),
280 overall_global_offset += v_space.
dim();
290 if (!is_null(reduct_obj)) {
296 if (interClusterComm.get()) {
297 RTOpPack::SPMD_all_reduce(
301 tuple<const RTOpPack::ReductTarget*>(&*i_reduct_obj).getRawPtr(),
302 tuple<RTOpPack::ReductTarget*>(&*icl_reduct_obj).getRawPtr()
310 RTOpPack::SPMD_all_reduce(
314 tuple<const RTOpPack::ReductTarget*>(&*icl_reduct_obj).getRawPtr(),
315 tuple<RTOpPack::ReductTarget*>(&*reduct_obj).getRawPtr()