RTOp Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RTOpPack_SPMD_apply_op_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // RTOp: Interfaces and Support Software for Vector Reduction Transformation
5 // Operations
6 // Copyright (2006) Sandia Corporation
7 //
8 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9 // license for use of this work by or on behalf of the U.S. Government.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
39 //
40 // ***********************************************************************
41 // @HEADER
42 
43 #ifndef RTOPPACK_SPMD_APPLY_OP_DEF_HPP
44 #define RTOPPACK_SPMD_APPLY_OP_DEF_HPP
45 
47 #include "Teuchos_Workspace.hpp"
48 #include "Teuchos_CommHelpers.hpp"
49 
50 
51 //
52 // Implementation-only utlities!
53 //
54 
55 
56 namespace RTOpPack {
57 
58 
59 RCP<FancyOStream>& spmdApplyOpDumpOut();
60 
61 
62 template<class Scalar>
64 {
66  Teuchos::OSTab tab(out);
67  *out << "globalOffset="<<v.globalOffset()<<"\n";
68  *out << "subDim="<<v.subDim()<<"\n";
69  *out << "values:\n";
70  tab.incrTab();
71  for( int i = 0; i < v.subDim(); ++i )
72  *out << " " << v(i) << ":" << (v.globalOffset()+i);
73  *out << "\n";
74 }
75 
76 
77 } // namespace RTOpPack
78 
79 
80 // ///////////////////////////
81 // Template implementations
82 
83 
84 //
85 // Misc Helper functions
86 //
87 
88 
89 template<class PrimitiveScalar>
91  int num_values,
92  int num_indexes,
93  int num_chars
94  )
95 {
96  return 3 * sizeof(index_type)
97  + num_values * sizeof(PrimitiveScalar)
98  + num_indexes * sizeof(index_type)
99  + num_chars * sizeof(char_type);
100 }
101 
102 
103 template<class Scalar>
105  const RTOpT<Scalar> &op,
106  Ordinal num_values,
107  Ordinal num_indexes,
108  Ordinal num_chars,
109  const ReductTarget &reduct_obj,
110  char reduct_obj_ext[]
111  )
112 {
113  using Teuchos::arrayView;
114  typedef typename RTOpT<Scalar>::primitive_value_type primitive_value_type;
118  const Ordinal
119  prim_value_type_size = PVTST::fromCountToDirectBytes(1),
120  index_type_size = ITST::fromCountToDirectBytes(1);
121  //char_type_size = CTST::fromCountToDirectBytes(1);
122  const Ordinal
123  num_values_off = 0,
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]);
133  reduct_obj,
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)
137  );
138  // ToDo: Change above implementation to only require indirect serialization!
139 }
140 
141 
142 template<class Scalar>
144  const RTOpT<Scalar> &op,
145  int num_values_in,
146  int num_indexes_in,
147  int num_chars_in,
148  const char reduct_obj_ext[],
149  ReductTarget *reduct_obj
150  )
151 {
152  using Teuchos::arrayView;
153  typedef typename RTOpT<Scalar>::primitive_value_type primitive_value_type;
157  const Ordinal
158  prim_value_type_size = PVTST::fromCountToDirectBytes(1),
159  index_type_size = ITST::fromCountToDirectBytes(1);
160  //char_type_size = CTST::fromCountToDirectBytes(1);
161  const Ordinal
162  num_values_off = 0,
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;
168 #ifdef RTOP_DEBUG
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);
174  !(
175  num_values==num_values_in && num_indexes==num_indexes_in
176  && num_chars==num_chars_in ),
177  std::logic_error,
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
182  );
183 #endif
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)
189  );
190  // ToDo: Change above implementation to only require indirect serialization!
191 }
192 
193 
194 namespace RTOpPack {
195 
196 
197 //
198 // ReductTargetSerializer
199 //
200 
201 
202 template<class Scalar>
204  const Teuchos::RCP<const RTOpT<Scalar> > &op
205  )
206  :op_(op.assert_not_null())
207 {
208  using Teuchos::outArg;
209  typedef typename RTOpT<Scalar>::primitive_value_type PrimitiveScalar;
210  op_->get_reduct_type_num_entries(
211  outArg(num_values_), outArg(num_indexes_), outArg(num_chars_) );
213  serializedSize<PrimitiveScalar>(num_values_,num_indexes_,num_chars_);
214 }
215 
216 
217 template<class Scalar>
220 {
221  return reduct_obj_ext_size_ * count;
222 }
223 
224 
225 template<class Scalar>
227  const index_type count
228  ,const ReductTarget * const reduct_objs[]
229  ,const index_type bytes
230  ,char charBuffer[]
231  ) const
232 {
233 #ifdef RTOP_DEBUG
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 );
238 #else
239  (void)bytes;
240 #endif
241  Ordinal offset = 0;
242  for( Ordinal i = 0; i < count; ++i, offset += reduct_obj_ext_size_ ) {
244  *op_,num_values_,num_indexes_,num_chars_
245  ,*reduct_objs[i],&charBuffer[offset]
246  );
247  }
248 }
249 
250 
251 template<class Scalar>
254 {
255  return op_->reduct_obj_create();
256 }
257 
258 template<class Scalar>
260  const index_type bytes
261  ,const char charBuffer[]
262  ,const index_type count
263  ,ReductTarget * const reduct_objs[]
264  ) const
265 {
266 #ifdef RTOP_DEBUG
267  TEUCHOS_TEST_FOR_EXCEPT( !(bytes > 0) );
268  TEUCHOS_TEST_FOR_EXCEPT( !charBuffer );
269  TEUCHOS_TEST_FOR_EXCEPT( !(bytes==getBufferSize(count)) );
270  TEUCHOS_TEST_FOR_EXCEPT( !reduct_objs );
271 #else
272  (void)bytes;
273 #endif
274  Ordinal offset = 0;
275  for( Ordinal i = 0; i < count; ++i, offset += reduct_obj_ext_size_ ) {
277  *op_,num_values_,num_indexes_,num_chars_
278  ,&charBuffer[offset],reduct_objs[i]
279  );
280  }
281 }
282 
283 
284 //
285 // ReductTargetReductionOp
286 //
287 
288 
289 template<class Scalar>
291  const Teuchos::RCP<const RTOpT<Scalar> > &op
292  )
293  :op_(op)
294 {}
295 
296 
297 template<class Scalar>
299  const Ordinal count,
300  const ReductTarget*const inBuffer[],
301  ReductTarget*const inoutBuffer[]
302  ) const
303 {
304  for( Ordinal i = 0; i < count; ++i )
305  op_->reduce_reduct_objs( *inBuffer[i], Teuchos::ptr(inoutBuffer[i]) );
306 }
307 
308 
309 } // namespace RTOpPack
310 
311 
312 template<class Scalar>
314  const Teuchos::Comm<index_type> *comm,
315  const RTOpT<Scalar> &op,
316  const int num_cols,
317  const ReductTarget*const i_reduct_objs[],
318  ReductTarget*const reduct_objs[]
319  )
320 {
321  using Teuchos::Workspace;
322  using Teuchos::reduceAll;
324  Workspace<Teuchos::RCP<ReductTarget> >
325  i_i_reduct_objs( wss, num_cols );
326  Workspace<ReductTarget*>
327  _i_i_reduct_objs( wss, num_cols );
328  for( int kc = 0; kc < num_cols; ++kc ) {
329  i_i_reduct_objs[kc] = op.reduct_obj_create();
330  _i_i_reduct_objs[kc] = &*i_i_reduct_objs[kc];
331  }
333  serializer(Teuchos::rcpFromRef(op));
335  reductOp(Teuchos::rcpFromRef(op));
336  reduceAll<Ordinal>(
337  *comm, serializer, reductOp,
338  num_cols, &i_reduct_objs[0], &_i_i_reduct_objs[0]);
339  for( int kc = 0; kc < num_cols; ++kc ) {
340  op.reduce_reduct_objs(*_i_i_reduct_objs[kc], Teuchos::ptr(reduct_objs[kc]));
341  }
342 }
343 
344 
345 template<class Scalar>
347  const Teuchos::Comm<index_type> *comm,
348  const RTOpT<Scalar> &op,
349  const int num_vecs,
350  const RTOpPack::ConstSubVectorView<Scalar> sub_vecs[],
351  const int num_targ_vecs,
352  const RTOpPack::SubVectorView<Scalar> targ_sub_vecs[],
353  ReductTarget *reduct_obj
354  )
355 {
356  ReductTarget* reduct_objs[] = { reduct_obj };
358  comm,op,1,num_vecs,sub_vecs,num_targ_vecs,targ_sub_vecs
359  ,reduct_obj ? reduct_objs : NULL
360  );
361 }
362 
363 
365 template<class Scalar>
367  const Teuchos::Comm<index_type> *comm,
368  const RTOpT<Scalar> &op,
369  const int num_cols,
370  const int num_multi_vecs,
371  const RTOpPack::ConstSubMultiVectorView<Scalar> sub_multi_vecs[],
372  const int num_targ_multi_vecs,
373  const RTOpPack::SubMultiVectorView<Scalar> targ_sub_multi_vecs[],
374  RTOpPack::ReductTarget*const reduct_objs[]
375  )
376 {
377  using Teuchos::arcp;
378  using Teuchos::Workspace;
380  int k, j, off;
381  Workspace<ConstSubVectorView<Scalar> > c_sub_vecs(wss,num_multi_vecs*num_cols);
382  if(sub_multi_vecs) {
383  for( off = 0, j = 0; j < num_cols; ++j ) {
384  for( k = 0; k < num_multi_vecs; ++k ) {
385  const ConstSubMultiVectorView<Scalar> &mv = sub_multi_vecs[k];
386  if (mv.subDim()) {
387  c_sub_vecs[off++].initialize(mv.globalOffset(), mv.subDim(),
388  arcp(&mv(0,j), 0, mv.subDim(), false), 1);
389  }
390  else {
391  c_sub_vecs[off++].initialize(mv.globalOffset(), mv.subDim(),
392  Teuchos::null, 1);
393  }
394  }
395  }
396  }
397  Workspace<SubVectorView<Scalar> > c_targ_sub_vecs(wss,num_targ_multi_vecs*num_cols);
398  if(targ_sub_multi_vecs) {
399  for( off = 0, j = 0; j < num_cols; ++j ) {
400  for( k = 0; k < num_targ_multi_vecs; ++k ) {
401  const SubMultiVectorView<Scalar> &mv = targ_sub_multi_vecs[k];
403  if (mv.subDim()) { mv_j = arcp(&mv(0,j), 0, mv.subDim(), false); }
404  c_targ_sub_vecs[off++].initialize(mv.globalOffset(), mv.subDim(), mv_j, 1);
405  }
406  }
407  }
409  comm,op,num_cols
410  ,num_multi_vecs, num_multi_vecs && sub_multi_vecs ? &c_sub_vecs[0] : NULL
411  ,num_targ_multi_vecs, num_targ_multi_vecs && targ_sub_multi_vecs ? &c_targ_sub_vecs[0] : NULL
412  ,reduct_objs
413  );
414 }
415 
416 
417 template<class Scalar>
419  const Teuchos::Comm<index_type> *comm,
420  const RTOpT<Scalar> &op,
421  const int num_cols,
422  const int num_vecs,
423  const ConstSubVectorView<Scalar> sub_vecs[],
424  const int num_targ_vecs,
425  const SubVectorView<Scalar> sub_targ_vecs[],
426  ReductTarget*const reduct_objs[]
427  )
428 {
429  using Teuchos::arrayView;
431  Teuchos::OSTab tab(out);
432  if (nonnull(out)) {
433  *out << "\nEntering RTOpPack::SPMD_apply_op(...) ...\n";
434  *out
435  << "\ncomm = " << (comm?comm->description():"NULL")
436  << "\nop = " << op.description()
437  << "\nnum_cols = " << num_cols
438  << "\nnum_vecs = " << num_vecs
439  << "\nnum_targ_vecs = " << num_targ_vecs
440  << "\n";
441  if( num_vecs && sub_vecs ) {
442  *out << "\nInput vectors:\n";
443  Teuchos::OSTab tab2(out);
444  for( int kc = 0; kc < num_cols; ++kc ) {
445  for( int k = 0; k < num_vecs; ++k ) {
446  *out << "\nvecs["<<kc<<","<<k<<"] =\n";
447  print(sub_vecs[kc*num_vecs+k],*out);
448  }
449  }
450  }
451  if( num_targ_vecs && sub_targ_vecs ) {
452  *out << "\nInput/output vectors *before* transforamtion:\n";
453  Teuchos::OSTab tab2(out);
454  for( int kc = 0; kc < num_cols; ++kc ) {
455  for( int k = 0; k < num_targ_vecs; ++k ) {
456  *out << "\nvecs["<<kc<<","<<k<<"] =\n";
457  print(sub_targ_vecs[kc*num_targ_vecs+k],*out);
458  }
459  }
460  }
461  if(reduct_objs) {
462  *out << "\nInput/output reduction objects *before* reduction:\n";
463  Teuchos::OSTab tab2(out);
464  for( int kc = 0; kc < num_cols; ++kc ) {
465  *out
466  << "\nreduct_objs["<<kc<<"] =\n"
467  << describe(*reduct_objs[kc],Teuchos::VERB_EXTREME);
468  }
469  }
470  }
471  using Teuchos::Workspace;
473  if( reduct_objs == NULL && sub_vecs == NULL && sub_targ_vecs == NULL ) {
474  // This is a transformation operation with no data on this processor.
475  // Therefore, we can just exist!
476  }
477  else {
478  const int localSubDim =
479  ( num_vecs
480  ? ( sub_vecs ? sub_vecs[0].subDim() : 0 )
481  : ( sub_targ_vecs ? sub_targ_vecs[0].subDim() : 0 )
482  );
483  // See if we need to do any global communication at all?
484  if( comm==NULL || reduct_objs == NULL ) {
485  if( ( sub_vecs || sub_targ_vecs ) && localSubDim ) {
486  for( int kc = 0; kc < num_cols; ++kc ) {
487  op.apply_op(
488  arrayView(sub_vecs+kc*num_vecs, num_vecs),
489  arrayView(sub_targ_vecs+kc*num_targ_vecs, num_targ_vecs),
490  reduct_objs ? Teuchos::ptr(reduct_objs[kc]) : Teuchos::null
491  );
492  }
493  }
494  }
495  else {
496  // Check the preconditions for excluding empty target vectors.
498  ( ( num_vecs && !sub_vecs) || ( num_targ_vecs && !sub_targ_vecs) ) && !( !sub_vecs && !sub_targ_vecs )
499  ,std::logic_error
500  ,"SPMD_apply_op(...): Error, invalid arguments num_vecs = " << num_vecs
501  << ", sub_vecs = " << sub_vecs << ", num_targ_vecs = " << num_targ_vecs
502  << ", sub_targ_vecs = " << sub_targ_vecs
503  );
504  //
505  // There is a non-null reduction target object and we are using
506  // SPMD so we need to reduce it across processors
507  //
508  // Allocate the intermediate target object and perform the
509  // reduction for the vector elements on this processor.
510  //
511  Workspace<Teuchos::RCP<ReductTarget> >
512  i_reduct_objs( wss, num_cols );
513  for( int kc = 0; kc < num_cols; ++kc ) {
514  i_reduct_objs[kc] = op.reduct_obj_create();
515  if( ( sub_vecs || sub_targ_vecs ) && localSubDim ) {
516  op.apply_op(
517  arrayView(sub_vecs+kc*num_vecs, num_vecs),
518  arrayView(sub_targ_vecs+kc*num_targ_vecs, num_targ_vecs),
519  i_reduct_objs[kc].ptr()
520  );
521  }
522  }
523  if(nonnull(out)) {
524  if(reduct_objs) {
525  *out << "\nIntermediate reduction objects in this process before global reduction:\n";
526  Teuchos::OSTab tab2(out);
527  for( int kc = 0; kc < num_cols; ++kc ) {
528  *out
529  << "\ni_reduct_objs["<<kc<<"] =\n"
530  << describe(*i_reduct_objs[kc],Teuchos::VERB_EXTREME);
531  }
532  }
533  }
534  //
535  // Reduce the local intermediate reduction objects into the global reduction objects
536  //
537  Workspace<const ReductTarget*>
538  _i_reduct_objs( wss, num_cols );
539  for( int kc = 0; kc < num_cols; ++kc ) {
540  _i_reduct_objs[kc] = &*i_reduct_objs[kc];
541  }
542  if(nonnull(out)) {
543  if(reduct_objs) {
544  *out << "\nPerforming global reduction ...\n";
545  }
546  }
547  SPMD_all_reduce(comm,op,num_cols,&_i_reduct_objs[0],reduct_objs);
548  }
549  }
550  if(nonnull(out)) {
551  if( num_targ_vecs && sub_targ_vecs ) {
552  *out << "\nInput/output vectors *after* transforamtion:\n";
553  Teuchos::OSTab tab2(out);
554  for( int kc = 0; kc < num_cols; ++kc ) {
555  for( int k = 0; k < num_targ_vecs; ++k ) {
556  *out << "\nvecs["<<kc<<","<<k<<"] =\n";
557  print(sub_targ_vecs[kc*num_targ_vecs+k],*out);
558  }
559  }
560  }
561  if(reduct_objs) {
562  *out << "\nInput/output reduction objects *after* reduction:\n";
563  Teuchos::OSTab tab2(out);
564  for( int kc = 0; kc < num_cols; ++kc ) {
565  *out
566  << "\nreduct_objs["<<kc<<"] =\n"
567  << describe(*reduct_objs[kc],Teuchos::VERB_EXTREME);
568  }
569  }
570  *out << "\nLeaving RTOpPack::SPMD_apply_op(...) ...\n";
571  *out << std::flush;
572  }
573 }
574 
575 
576 //
577 // Explicit Template Instaniation Macros
578 //
579 
580 
581 #define RTOPPACK_SPMD_APPLY_OP_INSTANT_SCALAR(SCALAR) \
582  \
583  template int serializedSize<SCALAR >( \
584  int num_values, \
585  int num_indexes, \
586  int num_chars \
587  ); \
588  \
589  template void serialize<SCALAR >( \
590  const RTOpT<SCALAR > &op, \
591  Ordinal num_values, \
592  Ordinal num_indexes, \
593  Ordinal num_chars, \
594  const ReductTarget &reduct_obj, \
595  char reduct_obj_ext[] \
596  ); \
597  \
598  template void deserialize<SCALAR >( \
599  const RTOpT<SCALAR > &op, \
600  int num_values_in, \
601  int num_indexes_in, \
602  int num_chars_in, \
603  const char reduct_obj_ext[], \
604  ReductTarget *reduct_obj \
605  ); \
606  \
607  template class ReductTargetSerializer<SCALAR >; \
608  \
609  template class ReductTargetReductionOp<SCALAR >; \
610  \
611  template void SPMD_all_reduce<SCALAR >( \
612  const Teuchos::Comm<index_type> *comm, \
613  const RTOpT<SCALAR > &op, \
614  const int num_cols, \
615  const ReductTarget*const i_reduct_objs[], \
616  ReductTarget*const reduct_objs[] \
617  ); \
618  \
619  template void SPMD_apply_op<SCALAR >( \
620  const Teuchos::Comm<index_type> *comm, \
621  const RTOpT<SCALAR > &op, \
622  const int num_vecs, \
623  const RTOpPack::ConstSubVectorView<SCALAR > sub_vecs[], \
624  const int num_targ_vecs, \
625  const RTOpPack::SubVectorView<SCALAR > targ_sub_vecs[], \
626  ReductTarget *reduct_obj \
627  ); \
628  \
629  template void SPMD_apply_op<SCALAR >( \
630  const Teuchos::Comm<index_type> *comm, \
631  const RTOpT<SCALAR > &op, \
632  const int num_cols, \
633  const int num_multi_vecs, \
634  const RTOpPack::ConstSubMultiVectorView<SCALAR > sub_multi_vecs[], \
635  const int num_targ_multi_vecs, \
636  const RTOpPack::SubMultiVectorView<SCALAR > targ_sub_multi_vecs[], \
637  RTOpPack::ReductTarget*const reduct_objs[] \
638  ); \
639  \
640  template void SPMD_apply_op<SCALAR >( \
641  const Teuchos::Comm<index_type> *comm, \
642  const RTOpT<SCALAR > &op, \
643  const int num_cols, \
644  const int num_vecs, \
645  const ConstSubVectorView<SCALAR > sub_vecs[], \
646  const int num_targ_vecs, \
647  const SubVectorView<SCALAR > sub_targ_vecs[], \
648  ReductTarget*const reduct_objs[] \
649  );
650 
651 
652 #endif // RTOPPACK_SPMD_APPLY_OP_DEF_HPP
std::string op_name() const
Return the name (as a null-terminated C-style string) of the operator.
int serializedSize(int num_values, int num_indexes, int num_chars)
Return the size in bytes of an external representation of a ReductTarget object.
void SPMD_all_reduce(const Teuchos::Comm< index_type > *comm, const RTOpT< Scalar > &op, const int num_cols, const ReductTarget *const i_reduct_objs[], ReductTarget *const reduct_objs[])
Reduce a set of reduction objects.
Teuchos::RCP< ReductTarget > createObj() const
Class for a changeable sub-vector.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void serialize(const index_type count, const ReductTarget *const reduct_objs[], const index_type bytes, char charBuffer[]) const
basic_OSTab< CharT, Traits > & incrTab(const int tabs=1)
Teuchos_Ordinal index_type
ReductionOp subclass for ReductTarget objects.
void serialize(const RTOpT< Scalar > &op, Ordinal num_values, Ordinal num_indexes, Ordinal num_chars, const ReductTarget &reduct_obj, char reduct_obj_ext[])
Serialize a ReductTarget object.
Class for a non-changeable sub-vector.
void deserialize(const RTOpT< Scalar > &op, int num_values, int num_indexes, int num_chars, const char reduct_obj_ext[], ReductTarget *reduct_obj)
Deserialize a ReductTarget object.
Serializer subclass for ReductTarget objects.
Templated interface to vector reduction/transformation operators {abstract}.
index_type getBufferSize(const index_type count) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class for a changeable sub-vector.
void extract_reduct_obj_state(const ReductTarget &reduct_obj, const ArrayView< primitive_value_type > &value_data, const ArrayView< index_type > &index_data, const ArrayView< char_type > &char_data) const
Extract the state of an already created reduction object.
void deserialize(const index_type bytes, const char charBuffer[], const index_type count, ReductTarget *const reduct_objs[]) const
void load_reduct_obj_state(const ArrayView< const primitive_value_type > &value_data, const ArrayView< const index_type > &index_data, const ArrayView< const char_type > &char_data, const Ptr< ReductTarget > &reduct_obj) const
Load the state of an already created reduction object given arrays of primitive objects.
virtual std::string description() const
PrimitiveTypeTraits< Scalar, Scalar >::primitiveType primitive_value_type
Abstract base class for all reduction objects.
void print(const ConstSubVectorView< Scalar > &v, Teuchos::FancyOStream &out_arg)
void reduce_reduct_objs(const ReductTarget &in_reduct_obj, const Ptr< ReductTarget > &inout_reduct_obj) const
Reduce intermediate reduction target objects.
Teuchos::RCP< ReductTarget > reduct_obj_create() const
Creates a new reduction target object initialized and ready to be used in a reduction.
bool nonnull(const boost::shared_ptr< T > &p)
Class for a non-changeable sub-multi-vector (submatrix).
void initialize(Ordinal globalOffset_in, Ordinal subDim_in, Ordinal colOffset_in, Ordinal numSubCols_in, const ArrayRCP< const Scalar > &values_in, Ordinal leadingDim_in)
Teuchos::RCP< const RTOpT< Scalar > > op_
void apply_op(const ArrayView< const ConstSubVectorView< Scalar > > &sub_vecs, const ArrayView< const SubVectorView< Scalar > > &targ_sub_vecs, const Ptr< ReductTarget > &reduct_obj) const
Apply the reduction/transformation operator to a set of sub-vectors.
Teuchos_Ordinal Ordinal
void SPMD_apply_op(const Teuchos::Comm< index_type > *comm, const RTOpT< Scalar > &op, const int num_vecs, const ConstSubVectorView< Scalar > sub_vecs[], const int num_targ_vecs, const SubVectorView< Scalar > targ_sub_vecs[], ReductTarget *reduct_obj)
Apply an RTOp in SMPD mode to a set of vectors with contiguous storage per process.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()
void reduce(const Ordinal count, const ReductTarget *const inBuffer[], ReductTarget *const inoutBuffer[]) const
RCP< FancyOStream > & spmdApplyOpDumpOut()