43 #ifndef RTOPPACK_SPMD_APPLY_OP_DEF_HPP 44 #define RTOPPACK_SPMD_APPLY_OP_DEF_HPP 46 #include "RTOpPack_SPMD_apply_op_decl.hpp" 47 #include "Teuchos_Workspace.hpp" 48 #include "Teuchos_CommHelpers.hpp" 59 RCP<FancyOStream>& spmdApplyOpDumpOut();
62 template<
class Scalar>
63 void print(
const ConstSubVectorView<Scalar> &v, Teuchos::FancyOStream &out_arg )
65 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::rcp(&out_arg,
false);
66 Teuchos::OSTab tab(out);
67 *out <<
"globalOffset="<<v.globalOffset()<<
"\n";
68 *out <<
"subDim="<<v.subDim()<<
"\n";
71 for(
int i = 0; i < v.subDim(); ++i )
72 *out <<
" " << v(i) <<
":" << (v.globalOffset()+i);
89 template<
class PrimitiveScalar>
90 int RTOpPack::serializedSize(
96 return 3 *
sizeof(index_type)
97 + num_values *
sizeof(PrimitiveScalar)
98 + num_indexes *
sizeof(index_type)
99 + num_chars *
sizeof(char_type);
103 template<
class Scalar>
104 void RTOpPack::serialize(
105 const RTOpT<Scalar> &op,
109 const ReductTarget &reduct_obj,
110 char reduct_obj_ext[]
113 using Teuchos::arrayView;
115 typedef Teuchos::SerializationTraits<Ordinal, primitive_value_type> PVTST;
116 typedef Teuchos::SerializationTraits<Ordinal, index_type> ITST;
117 typedef Teuchos::SerializationTraits<Ordinal, char_type> CTST;
119 prim_value_type_size = PVTST::fromCountToDirectBytes(1),
120 index_type_size = ITST::fromCountToDirectBytes(1);
124 num_indexes_off = num_values_off + index_type_size,
125 num_chars_off = num_indexes_off + index_type_size,
126 values_off = num_chars_off + index_type_size,
127 indexes_off = values_off + num_values * prim_value_type_size,
128 chars_off = indexes_off + num_indexes * index_type_size;
129 ITST::serialize(1, &num_values, index_type_size, &reduct_obj_ext[num_values_off]);
130 ITST::serialize(1, &num_indexes, index_type_size, &reduct_obj_ext[num_indexes_off]);
131 ITST::serialize(1, &num_chars, index_type_size, &reduct_obj_ext[num_chars_off]);
132 op.extract_reduct_obj_state(
134 arrayView(PVTST::convertFromCharPtr(&reduct_obj_ext[values_off]), num_values),
135 arrayView(ITST::convertFromCharPtr(&reduct_obj_ext[indexes_off]), num_indexes),
136 arrayView(CTST::convertFromCharPtr(&reduct_obj_ext[chars_off]), num_chars)
142 template<
class Scalar>
143 void RTOpPack::deserialize(
144 const RTOpT<Scalar> &op,
148 const char reduct_obj_ext[],
149 ReductTarget *reduct_obj
152 using Teuchos::arrayView;
154 typedef Teuchos::SerializationTraits<int,primitive_value_type> PVTST;
155 typedef Teuchos::SerializationTraits<int,index_type> ITST;
156 typedef Teuchos::SerializationTraits<int,char_type> CTST;
158 prim_value_type_size = PVTST::fromCountToDirectBytes(1),
159 index_type_size = ITST::fromCountToDirectBytes(1);
163 num_indexes_off = num_values_off + index_type_size,
164 num_chars_off = num_indexes_off + index_type_size,
165 values_off = num_chars_off + index_type_size,
166 indexes_off = values_off + num_values_in * prim_value_type_size,
167 chars_off = indexes_off + num_indexes_in * index_type_size;
169 Ordinal num_values = -1, num_indexes = -1, num_chars = -1;
170 ITST::deserialize(index_type_size, &reduct_obj_ext[num_values_off], 1, &num_values);
171 ITST::deserialize(index_type_size, &reduct_obj_ext[num_indexes_off], 1, &num_indexes);
172 ITST::deserialize(index_type_size, &reduct_obj_ext[num_chars_off], 1, &num_chars);
173 TEUCHOS_TEST_FOR_EXCEPTION(
175 num_values==num_values_in && num_indexes==num_indexes_in
176 && num_chars==num_chars_in ),
178 "Error: RTOp="<<op.op_name()
179 <<
", num_values="<<num_values<<
", num_values_in="<<num_values_in
180 <<
", num_indexes="<<num_indexes<<
", num_indexes_in="<<num_indexes_in
181 <<
", num_chars="<<num_chars<<
", num_chars_in="<<num_chars_in
184 op.load_reduct_obj_state(
185 arrayView(PVTST::convertFromCharPtr(&reduct_obj_ext[values_off]), num_values_in),
186 arrayView(ITST::convertFromCharPtr(&reduct_obj_ext[indexes_off]), num_indexes_in),
187 arrayView(CTST::convertFromCharPtr(&reduct_obj_ext[chars_off]), num_chars_in),
188 Teuchos::ptr(reduct_obj)
202 template<
class Scalar>
206 :op_(op.assert_not_null())
208 using Teuchos::outArg;
210 op_->get_reduct_type_num_entries(
211 outArg(num_values_), outArg(num_indexes_), outArg(num_chars_) );
212 reduct_obj_ext_size_ =
213 serializedSize<PrimitiveScalar>(num_values_,num_indexes_,num_chars_);
217 template<
class Scalar>
221 return reduct_obj_ext_size_ * count;
225 template<
class Scalar>
227 const index_type count
229 ,
const index_type bytes
234 TEUCHOS_TEST_FOR_EXCEPT( !(count > 0) );
235 TEUCHOS_TEST_FOR_EXCEPT( !reduct_objs );
236 TEUCHOS_TEST_FOR_EXCEPT( !(bytes==this->getBufferSize(count)) );
237 TEUCHOS_TEST_FOR_EXCEPT( !charBuffer );
240 for( Ordinal i = 0; i < count; ++i, offset += reduct_obj_ext_size_ ) {
242 *op_,num_values_,num_indexes_,num_chars_
243 ,*reduct_objs[i],&charBuffer[offset]
249 template<
class Scalar>
250 Teuchos::RCP<ReductTarget>
253 return op_->reduct_obj_create();
256 template<
class Scalar>
258 const index_type bytes
259 ,
const char charBuffer[]
260 ,
const index_type count
265 TEUCHOS_TEST_FOR_EXCEPT( !(bytes > 0) );
266 TEUCHOS_TEST_FOR_EXCEPT( !charBuffer );
267 TEUCHOS_TEST_FOR_EXCEPT( !(bytes==getBufferSize(count)) );
268 TEUCHOS_TEST_FOR_EXCEPT( !reduct_objs );
271 for( Ordinal i = 0; i < count; ++i, offset += reduct_obj_ext_size_ ) {
272 RTOpPack::deserialize(
273 *op_,num_values_,num_indexes_,num_chars_
274 ,&charBuffer[offset],reduct_objs[i]
285 template<
class Scalar>
293 template<
class Scalar>
300 for(
Ordinal i = 0; i < count; ++i )
301 op_->reduce_reduct_objs( *inBuffer[i], Teuchos::ptr(inoutBuffer[i]) );
308 template<
class Scalar>
309 void RTOpPack::SPMD_all_reduce(
310 const Teuchos::Comm<index_type> *comm,
311 const RTOpT<Scalar> &op,
313 const ReductTarget*
const i_reduct_objs[],
314 ReductTarget*
const reduct_objs[]
317 using Teuchos::Workspace;
318 using Teuchos::reduceAll;
319 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
320 Workspace<Teuchos::RCP<ReductTarget> >
321 i_i_reduct_objs( wss, num_cols );
322 Workspace<ReductTarget*>
323 _i_i_reduct_objs( wss, num_cols );
324 for(
int kc = 0; kc < num_cols; ++kc ) {
325 i_i_reduct_objs[kc] = op.reduct_obj_create();
326 _i_i_reduct_objs[kc] = &*i_i_reduct_objs[kc];
328 ReductTargetSerializer<Scalar>
329 serializer(Teuchos::rcpFromRef(op));
330 ReductTargetReductionOp<Scalar>
331 reductOp(Teuchos::rcpFromRef(op));
333 *comm, serializer, reductOp,
334 num_cols, &i_reduct_objs[0], &_i_i_reduct_objs[0]);
335 for(
int kc = 0; kc < num_cols; ++kc ) {
336 op.reduce_reduct_objs(*_i_i_reduct_objs[kc], Teuchos::ptr(reduct_objs[kc]));
341 template<
class Scalar>
342 void RTOpPack::SPMD_apply_op(
343 const Teuchos::Comm<index_type> *comm,
344 const RTOpT<Scalar> &op,
347 const int num_targ_vecs,
349 ReductTarget *reduct_obj
352 ReductTarget* reduct_objs[] = { reduct_obj };
354 comm,op,1,num_vecs,sub_vecs,num_targ_vecs,targ_sub_vecs
355 ,reduct_obj ? reduct_objs : NULL
361 template<
class Scalar>
362 void RTOpPack::SPMD_apply_op(
363 const Teuchos::Comm<index_type> *comm,
364 const RTOpT<Scalar> &op,
366 const int num_multi_vecs,
368 const int num_targ_multi_vecs,
374 using Teuchos::Workspace;
375 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
377 Workspace<ConstSubVectorView<Scalar> > c_sub_vecs(wss,num_multi_vecs*num_cols);
379 for( off = 0, j = 0; j < num_cols; ++j ) {
380 for( k = 0; k < num_multi_vecs; ++k ) {
381 const ConstSubMultiVectorView<Scalar> &mv = sub_multi_vecs[k];
383 c_sub_vecs[off++].
initialize(mv.globalOffset(), mv.subDim(),
384 arcp(&mv(0,j), 0, mv.subDim(),
false), 1);
387 c_sub_vecs[off++].initialize(mv.globalOffset(), mv.subDim(),
393 Workspace<SubVectorView<Scalar> > c_targ_sub_vecs(wss,num_targ_multi_vecs*num_cols);
394 if(targ_sub_multi_vecs) {
395 for( off = 0, j = 0; j < num_cols; ++j ) {
396 for( k = 0; k < num_targ_multi_vecs; ++k ) {
397 const SubMultiVectorView<Scalar> &mv = targ_sub_multi_vecs[k];
398 ArrayRCP<Scalar> mv_j = Teuchos::null;
399 if (mv.subDim()) { mv_j = arcp(&mv(0,j), 0, mv.subDim(),
false); }
400 c_targ_sub_vecs[off++].
initialize(mv.globalOffset(), mv.subDim(), mv_j, 1);
406 ,num_multi_vecs, num_multi_vecs && sub_multi_vecs ? &c_sub_vecs[0] : NULL
407 ,num_targ_multi_vecs, num_targ_multi_vecs && targ_sub_multi_vecs ? &c_targ_sub_vecs[0] : NULL
413 template<
class Scalar>
414 void RTOpPack::SPMD_apply_op(
415 const Teuchos::Comm<index_type> *comm,
416 const RTOpT<Scalar> &op,
419 const ConstSubVectorView<Scalar> sub_vecs[],
420 const int num_targ_vecs,
421 const SubVectorView<Scalar> sub_targ_vecs[],
422 ReductTarget*
const reduct_objs[]
425 using Teuchos::arrayView;
426 Teuchos::RCP<Teuchos::FancyOStream> out = spmdApplyOpDumpOut();
427 Teuchos::OSTab tab(out);
429 *out <<
"\nEntering RTOpPack::SPMD_apply_op(...) ...\n";
431 <<
"\ncomm = " << (comm?comm->description():
"NULL")
432 <<
"\nop = " << op.description()
433 <<
"\nnum_cols = " << num_cols
434 <<
"\nnum_vecs = " << num_vecs
435 <<
"\nnum_targ_vecs = " << num_targ_vecs
437 if( num_vecs && sub_vecs ) {
438 *out <<
"\nInput vectors:\n";
439 Teuchos::OSTab tab2(out);
440 for(
int kc = 0; kc < num_cols; ++kc ) {
441 for(
int k = 0; k < num_vecs; ++k ) {
442 *out <<
"\nvecs["<<kc<<
","<<k<<
"] =\n";
443 print(sub_vecs[kc*num_vecs+k],*out);
447 if( num_targ_vecs && sub_targ_vecs ) {
448 *out <<
"\nInput/output vectors *before* transforamtion:\n";
449 Teuchos::OSTab tab2(out);
450 for(
int kc = 0; kc < num_cols; ++kc ) {
451 for(
int k = 0; k < num_targ_vecs; ++k ) {
452 *out <<
"\nvecs["<<kc<<
","<<k<<
"] =\n";
453 print(sub_targ_vecs[kc*num_targ_vecs+k],*out);
458 *out <<
"\nInput/output reduction objects *before* reduction:\n";
459 Teuchos::OSTab tab2(out);
460 for(
int kc = 0; kc < num_cols; ++kc ) {
462 <<
"\nreduct_objs["<<kc<<
"] =\n" 463 << describe(*reduct_objs[kc],Teuchos::VERB_EXTREME);
467 using Teuchos::Workspace;
468 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
469 if( reduct_objs == NULL && sub_vecs == NULL && sub_targ_vecs == NULL ) {
474 const int localSubDim =
476 ? ( sub_vecs ? sub_vecs[0].subDim() : 0 )
477 : ( sub_targ_vecs ? sub_targ_vecs[0].subDim() : 0 )
480 if( comm==NULL || reduct_objs == NULL ) {
481 if( ( sub_vecs || sub_targ_vecs ) && localSubDim ) {
482 for(
int kc = 0; kc < num_cols; ++kc ) {
484 arrayView(sub_vecs+kc*num_vecs, num_vecs),
485 arrayView(sub_targ_vecs+kc*num_targ_vecs, num_targ_vecs),
486 reduct_objs ? Teuchos::ptr(reduct_objs[kc]) : Teuchos::null
493 TEUCHOS_TEST_FOR_EXCEPTION(
494 ( ( num_vecs && !sub_vecs) || ( num_targ_vecs && !sub_targ_vecs) ) && !( !sub_vecs && !sub_targ_vecs )
496 ,
"SPMD_apply_op(...): Error, invalid arguments num_vecs = " << num_vecs
497 <<
", sub_vecs = " << sub_vecs <<
", num_targ_vecs = " << num_targ_vecs
498 <<
", sub_targ_vecs = " << sub_targ_vecs
507 Workspace<Teuchos::RCP<ReductTarget> >
508 i_reduct_objs( wss, num_cols );
509 for(
int kc = 0; kc < num_cols; ++kc ) {
510 i_reduct_objs[kc] = op.reduct_obj_create();
511 if( ( sub_vecs || sub_targ_vecs ) && localSubDim ) {
513 arrayView(sub_vecs+kc*num_vecs, num_vecs),
514 arrayView(sub_targ_vecs+kc*num_targ_vecs, num_targ_vecs),
515 i_reduct_objs[kc].ptr()
521 *out <<
"\nIntermediate reduction objects in this process before global reduction:\n";
522 Teuchos::OSTab tab2(out);
523 for(
int kc = 0; kc < num_cols; ++kc ) {
525 <<
"\ni_reduct_objs["<<kc<<
"] =\n" 526 << describe(*i_reduct_objs[kc],Teuchos::VERB_EXTREME);
533 Workspace<const ReductTarget*>
534 _i_reduct_objs( wss, num_cols );
535 for(
int kc = 0; kc < num_cols; ++kc ) {
536 _i_reduct_objs[kc] = &*i_reduct_objs[kc];
540 *out <<
"\nPerforming global reduction ...\n";
543 SPMD_all_reduce(comm,op,num_cols,&_i_reduct_objs[0],reduct_objs);
547 if( num_targ_vecs && sub_targ_vecs ) {
548 *out <<
"\nInput/output vectors *after* transforamtion:\n";
549 Teuchos::OSTab tab2(out);
550 for(
int kc = 0; kc < num_cols; ++kc ) {
551 for(
int k = 0; k < num_targ_vecs; ++k ) {
552 *out <<
"\nvecs["<<kc<<
","<<k<<
"] =\n";
553 print(sub_targ_vecs[kc*num_targ_vecs+k],*out);
558 *out <<
"\nInput/output reduction objects *after* reduction:\n";
559 Teuchos::OSTab tab2(out);
560 for(
int kc = 0; kc < num_cols; ++kc ) {
562 <<
"\nreduct_objs["<<kc<<
"] =\n" 563 << describe(*reduct_objs[kc],Teuchos::VERB_EXTREME);
566 *out <<
"\nLeaving RTOpPack::SPMD_apply_op(...) ...\n";
577 #define RTOPPACK_SPMD_APPLY_OP_INSTANT_SCALAR(SCALAR) \ 579 template int serializedSize<SCALAR >( \ 585 template void serialize<SCALAR >( \ 586 const RTOpT<SCALAR > &op, \ 587 Ordinal num_values, \ 588 Ordinal num_indexes, \ 590 const ReductTarget &reduct_obj, \ 591 char reduct_obj_ext[] \ 594 template void deserialize<SCALAR >( \ 595 const RTOpT<SCALAR > &op, \ 597 int num_indexes_in, \ 599 const char reduct_obj_ext[], \ 600 ReductTarget *reduct_obj \ 603 template class ReductTargetSerializer<SCALAR >; \ 605 template class ReductTargetReductionOp<SCALAR >; \ 607 template void SPMD_all_reduce<SCALAR >( \ 608 const Teuchos::Comm<index_type> *comm, \ 609 const RTOpT<SCALAR > &op, \ 610 const int num_cols, \ 611 const ReductTarget*const i_reduct_objs[], \ 612 ReductTarget*const reduct_objs[] \ 615 template void SPMD_apply_op<SCALAR >( \ 616 const Teuchos::Comm<index_type> *comm, \ 617 const RTOpT<SCALAR > &op, \ 618 const int num_vecs, \ 619 const RTOpPack::ConstSubVectorView<SCALAR > sub_vecs[], \ 620 const int num_targ_vecs, \ 621 const RTOpPack::SubVectorView<SCALAR > targ_sub_vecs[], \ 622 ReductTarget *reduct_obj \ 625 template void SPMD_apply_op<SCALAR >( \ 626 const Teuchos::Comm<index_type> *comm, \ 627 const RTOpT<SCALAR > &op, \ 628 const int num_cols, \ 629 const int num_multi_vecs, \ 630 const RTOpPack::ConstSubMultiVectorView<SCALAR > sub_multi_vecs[], \ 631 const int num_targ_multi_vecs, \ 632 const RTOpPack::SubMultiVectorView<SCALAR > targ_sub_multi_vecs[], \ 633 RTOpPack::ReductTarget*const reduct_objs[] \ 636 template void SPMD_apply_op<SCALAR >( \ 637 const Teuchos::Comm<index_type> *comm, \ 638 const RTOpT<SCALAR > &op, \ 639 const int num_cols, \ 640 const int num_vecs, \ 641 const ConstSubVectorView<SCALAR > sub_vecs[], \ 642 const int num_targ_vecs, \ 643 const SubVectorView<SCALAR > sub_targ_vecs[], \ 644 ReductTarget*const reduct_objs[] \ 648 #endif // RTOPPACK_SPMD_APPLY_OP_DEF_HPP void deserialize(const index_type bytes, const char charBuffer[], const index_type count, ReductTarget *const reduct_objs[]) const
ReductionOp subclass for ReductTarget objects.
Serializer subclass for ReductTarget objects.
Teuchos::RCP< ReductTarget > createObj() const
void serialize(const index_type count, const ReductTarget *const reduct_objs[], const index_type bytes, char charBuffer[]) const
void initialize(Ordinal globalOffset_in, Ordinal subDim_in, Ordinal colOffset_in, Ordinal numSubCols_in, const ArrayRCP< Scalar > &values_in, Ordinal leadingDim_in)
PrimitiveTypeTraits< Scalar, Scalar >::primitiveType primitive_value_type
void reduce(const Ordinal count, const ReductTarget *const inBuffer[], ReductTarget *const inoutBuffer[]) const
void initialize(Ordinal globalOffset_in, Ordinal subDim_in, Ordinal colOffset_in, Ordinal numSubCols_in, const ArrayRCP< const Scalar > &values_in, Ordinal leadingDim_in)
index_type getBufferSize(const index_type count) const