RTOp Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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
56namespace RTOpPack {
57
58
59RCP<FancyOStream>& spmdApplyOpDumpOut();
60
61
62template<class Scalar>
63void print( const ConstSubVectorView<Scalar> &v, Teuchos::FancyOStream &out_arg )
64{
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";
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
89template<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
103template<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;
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;
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]);
132 op.extract_reduct_obj_state(
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
142template<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;
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;
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);
173 TEUCHOS_TEST_FOR_EXCEPTION(
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
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)
189 );
190 // ToDo: Change above implementation to only require indirect serialization!
191}
192
193
194namespace RTOpPack {
195
196
197//
198// ReductTargetSerializer
199//
200
201
202template<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
217template<class Scalar>
220{
221 return reduct_obj_ext_size_ * count;
222}
223
224
225template<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
251template<class Scalar>
252Teuchos::RCP<ReductTarget>
254{
255 return op_->reduct_obj_create();
256}
257
258template<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
289template<class Scalar>
291 const Teuchos::RCP<const RTOpT<Scalar> > &op
292 )
293 :op_(op)
294{}
295
296
297template<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
312template<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;
323 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
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 }
332 ReductTargetSerializer<Scalar>
333 serializer(Teuchos::rcpFromRef(op));
334 ReductTargetReductionOp<Scalar>
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
345template<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
365template<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;
379 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
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];
402 ArrayRCP<Scalar> mv_j = Teuchos::null;
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
417template<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;
430 Teuchos::RCP<Teuchos::FancyOStream> out = spmdApplyOpDumpOut();
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;
472 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
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.
497 TEUCHOS_TEST_FOR_EXCEPTION(
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
PrimitiveTypeTraits< Scalar, Scalar >::primitiveType primitive_value_type
ReductionOp subclass for ReductTarget objects.
void reduce(const Ordinal count, const ReductTarget *const inBuffer[], ReductTarget *const inoutBuffer[]) const
Serializer subclass for ReductTarget objects.
index_type getBufferSize(const index_type count) const
Teuchos::RCP< const RTOpT< Scalar > > op_
Abstract base class for all reduction objects.
Teuchos_Ordinal index_type
Teuchos_Ordinal Ordinal
RCP< FancyOStream > & spmdApplyOpDumpOut()
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.
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.
void print(const ConstSubVectorView< Scalar > &v, Teuchos::FancyOStream &out_arg)
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.
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.