RTOp Package Browser (Single Doxygen Collection) Version of the Day
RTOpPack_SPMD_apply_op_def.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // RTOp: Interfaces and Support Software for Vector Reduction Transformation
00005 //       Operations
00006 //                Copyright (2006) Sandia Corporation
00007 // 
00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00009 // license for use of this work by or on behalf of the U.S. Government.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //  
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA
00025 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00026 // 
00027 // ***********************************************************************
00028 // @HEADER
00029 
00030 #ifndef RTOPPACK_SPMD_APPLY_OP_DEF_HPP
00031 #define RTOPPACK_SPMD_APPLY_OP_DEF_HPP
00032 
00033 #include "RTOpPack_SPMD_apply_op_decl.hpp"
00034 #include "Teuchos_Workspace.hpp"
00035 #include "Teuchos_CommHelpers.hpp"
00036 
00037 #ifdef RTOPPACK_ENABLE_SHOW_DUMP
00038 #  include "Teuchos_VerboseObject.hpp"
00039 #endif // RTOPPACK_ENABLE_SHOW_DUMP
00040 
00041 
00042 namespace RTOpPack {
00043 
00044 
00045 #ifdef RTOPPACK_ENABLE_SHOW_DUMP
00046 
00047 
00048 template<class Scalar>
00049 void print( const ConstSubVectorView<Scalar> &v, Teuchos::FancyOStream &out_arg )
00050 {
00051   Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::rcp(&out_arg,false);
00052   Teuchos::OSTab tab(out);
00053   *out << "globalOffset="<<v.globalOffset()<<"\n";
00054   *out << "subDim="<<v.subDim()<<"\n";
00055   *out << "values:\n";
00056   tab.incrTab();
00057   for( int i = 0; i < v.subDim(); ++i )
00058     *out << " " << v(i) << ":" << (v.globalOffset()+i);
00059   *out << "\n";
00060 }
00061 
00062 # include "Teuchos_VerboseObject.hpp"
00063 
00064 
00065 #endif // RTOPPACK_ENABLE_SHOW_DUMP
00066 
00067 
00068 } // namespace RTOpPack
00069 
00070 
00071 // ///////////////////////////
00072 // Template implementations
00073 
00074 
00075 //
00076 // Misc Helper functions
00077 //
00078 
00079 
00080 template<class PrimitiveScalar>
00081 int RTOpPack::serializedSize(
00082   int num_values,
00083   int num_indexes,
00084   int num_chars
00085   )
00086 {
00087   return 3 * sizeof(index_type)
00088     + num_values * sizeof(PrimitiveScalar)
00089     + num_indexes * sizeof(index_type)
00090     + num_chars * sizeof(char_type);
00091 }
00092 
00093 
00094 template<class Scalar>
00095 void RTOpPack::serialize(
00096   const RTOpT<Scalar> &op,
00097   Ordinal num_values,
00098   Ordinal num_indexes,
00099   Ordinal num_chars,
00100   const ReductTarget &reduct_obj,
00101   char reduct_obj_ext[]
00102   )
00103 {
00104   using Teuchos::arrayView;
00105   typedef typename RTOpT<Scalar>::primitive_value_type primitive_value_type;
00106   typedef Teuchos::SerializationTraits<Ordinal, primitive_value_type> PVTST;
00107   typedef Teuchos::SerializationTraits<Ordinal, index_type> ITST;
00108   typedef Teuchos::SerializationTraits<Ordinal, char_type> CTST;
00109   const Ordinal
00110     prim_value_type_size = PVTST::fromCountToIndirectBytes(1),
00111     index_type_size = ITST::fromCountToIndirectBytes(1);
00112   //char_type_size = CTST::fromCountToIndirectBytes(1);
00113   const Ordinal
00114     num_values_off = 0,
00115     num_indexes_off = num_values_off + index_type_size,
00116     num_chars_off = num_indexes_off + index_type_size,
00117     values_off = num_chars_off + index_type_size,
00118     indexes_off = values_off + num_values * prim_value_type_size,
00119     chars_off = indexes_off + num_indexes * index_type_size;
00120   ITST::serialize(1, &num_values, index_type_size, &reduct_obj_ext[num_values_off]);
00121   ITST::serialize(1, &num_indexes, index_type_size, &reduct_obj_ext[num_indexes_off]);
00122   ITST::serialize(1, &num_chars, index_type_size, &reduct_obj_ext[num_chars_off]);
00123   op.extract_reduct_obj_state(
00124     reduct_obj,
00125     arrayView(PVTST::convertFromCharPtr(&reduct_obj_ext[values_off]), num_values),
00126     arrayView(ITST::convertFromCharPtr(&reduct_obj_ext[indexes_off]), num_indexes),
00127     arrayView(CTST::convertFromCharPtr(&reduct_obj_ext[chars_off]), num_chars)
00128     );
00129   // ToDo: Change above implementation to only require indirect serialization!
00130 }
00131 
00132 
00133 template<class Scalar>
00134 void RTOpPack::deserialize(
00135   const RTOpT<Scalar> &op,
00136   int num_values_in,
00137   int num_indexes_in,
00138   int num_chars_in,
00139   const char reduct_obj_ext[],
00140   ReductTarget *reduct_obj
00141   )
00142 {
00143   using Teuchos::arrayView;
00144   typedef typename RTOpT<Scalar>::primitive_value_type primitive_value_type;
00145   typedef Teuchos::SerializationTraits<int,primitive_value_type> PVTST;
00146   typedef Teuchos::SerializationTraits<int,index_type> ITST;
00147   typedef Teuchos::SerializationTraits<int,char_type> CTST;
00148   const Ordinal
00149     prim_value_type_size = PVTST::fromCountToIndirectBytes(1),
00150     index_type_size = ITST::fromCountToIndirectBytes(1);
00151   //char_type_size = CTST::fromCountToIndirectBytes(1);
00152   const Ordinal
00153     num_values_off = 0,
00154     num_indexes_off = num_values_off + index_type_size,
00155     num_chars_off = num_indexes_off + index_type_size,
00156     values_off = num_chars_off + index_type_size,
00157     indexes_off = values_off + num_values_in * prim_value_type_size,
00158     chars_off = indexes_off + num_indexes_in * index_type_size;
00159 #ifdef RTOP_DEBUG
00160   Ordinal num_values = -1, num_indexes = -1, num_chars = -1;
00161   ITST::deserialize(index_type_size, &reduct_obj_ext[num_values_off], 1, &num_values);
00162   ITST::deserialize(index_type_size, &reduct_obj_ext[num_indexes_off], 1, &num_indexes);
00163   ITST::deserialize(index_type_size, &reduct_obj_ext[num_chars_off], 1, &num_chars);
00164   TEST_FOR_EXCEPT(
00165     !(
00166       num_values==num_values_in && num_indexes==num_indexes_in
00167       && num_chars==num_chars_in )
00168     );
00169 #endif
00170   op.load_reduct_obj_state(
00171     arrayView(PVTST::convertFromCharPtr(&reduct_obj_ext[values_off]), num_values_in),
00172     arrayView(ITST::convertFromCharPtr(&reduct_obj_ext[indexes_off]), num_indexes_in),
00173     arrayView(CTST::convertFromCharPtr(&reduct_obj_ext[chars_off]), num_chars_in),
00174     Teuchos::ptr(reduct_obj)
00175     );
00176   // ToDo: Change above implementation to only require indirect serialization!
00177 }
00178 
00179 
00180 namespace RTOpPack {
00181 
00182 
00183 //
00184 // ReductTargetSerializer
00185 //
00186 
00187 
00188 template<class Scalar>
00189 ReductTargetSerializer<Scalar>::ReductTargetSerializer(
00190   const Teuchos::RCP<const RTOpT<Scalar> > &op
00191   )
00192   :op_(op.assert_not_null())
00193 {
00194   using Teuchos::outArg;
00195   typedef typename RTOpT<Scalar>::primitive_value_type PrimitiveScalar;
00196   op_->get_reduct_type_num_entries(
00197     outArg(num_values_), outArg(num_indexes_), outArg(num_chars_) );
00198   reduct_obj_ext_size_ =
00199     serializedSize<PrimitiveScalar>(num_values_,num_indexes_,num_chars_);
00200 }
00201 
00202 
00203 template<class Scalar>
00204 index_type
00205 ReductTargetSerializer<Scalar>::getBufferSize(const index_type count) const
00206 {
00207   return reduct_obj_ext_size_ * count;
00208 }
00209 
00210 
00211 template<class Scalar>
00212 void ReductTargetSerializer<Scalar>::serialize(
00213   const index_type count
00214   ,const ReductTarget * const reduct_objs[]
00215   ,const index_type bytes
00216   ,char charBuffer[]
00217   ) const
00218 {
00219 #ifdef RTOP_DEBUG
00220   TEST_FOR_EXCEPT( !(count > 0) );
00221   TEST_FOR_EXCEPT( !reduct_objs );
00222   TEST_FOR_EXCEPT( !(bytes==this->getBufferSize(count)) );
00223   TEST_FOR_EXCEPT( !charBuffer );
00224 #endif
00225   Ordinal offset = 0;
00226   for( Ordinal i = 0; i < count; ++i, offset += reduct_obj_ext_size_ ) {
00227     RTOpPack::serialize(
00228       *op_,num_values_,num_indexes_,num_chars_
00229       ,*reduct_objs[i],&charBuffer[offset]
00230       );
00231   }
00232 }
00233 
00234 
00235 template<class Scalar>
00236 Teuchos::RCP<ReductTarget>
00237 ReductTargetSerializer<Scalar>::createObj() const
00238 {
00239   return op_->reduct_obj_create();
00240 }
00241 
00242 template<class Scalar>
00243 void ReductTargetSerializer<Scalar>::deserialize(
00244   const index_type bytes
00245   ,const char charBuffer[]
00246   ,const index_type count
00247   ,ReductTarget * const reduct_objs[]
00248   ) const
00249 {
00250 #ifdef RTOP_DEBUG
00251   TEST_FOR_EXCEPT( !(bytes > 0) );
00252   TEST_FOR_EXCEPT( !charBuffer );
00253   TEST_FOR_EXCEPT( !(bytes==getBufferSize(count)) );
00254   TEST_FOR_EXCEPT( !reduct_objs );
00255 #endif
00256   Ordinal offset = 0;
00257   for( Ordinal i = 0; i < count; ++i, offset += reduct_obj_ext_size_ ) {
00258     RTOpPack::deserialize(
00259       *op_,num_values_,num_indexes_,num_chars_
00260       ,&charBuffer[offset],reduct_objs[i]
00261       );
00262   }
00263 }
00264 
00265 
00266 //
00267 // ReductTargetReductionOp
00268 //
00269 
00270 
00271 template<class Scalar>
00272 ReductTargetReductionOp<Scalar>::ReductTargetReductionOp(
00273   const Teuchos::RCP<const RTOpT<Scalar> > &op
00274   )
00275   :op_(op)
00276 {}
00277 
00278  
00279 template<class Scalar>
00280 void ReductTargetReductionOp<Scalar>::reduce(
00281   const Ordinal count,
00282   const ReductTarget*const inBuffer[],
00283   ReductTarget*const inoutBuffer[]
00284   ) const
00285 {
00286   for( Ordinal i = 0; i < count; ++i )
00287     op_->reduce_reduct_objs( *inBuffer[i], Teuchos::ptr(inoutBuffer[i]) );
00288 }
00289 
00290 
00291 } // namespace RTOpPack
00292 
00293 
00294 template<class Scalar>
00295 void RTOpPack::SPMD_all_reduce(
00296   const Teuchos::Comm<index_type> *comm,
00297   const RTOpT<Scalar> &op,
00298   const int num_cols,
00299   const ReductTarget*const i_reduct_objs[],
00300   ReductTarget*const reduct_objs[]
00301   )
00302 {
00303   using Teuchos::Workspace;
00304   using Teuchos::reduceAll;
00305   Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00306   Workspace<Teuchos::RCP<ReductTarget> >
00307     i_i_reduct_objs( wss, num_cols );
00308   Workspace<ReductTarget*>
00309     _i_i_reduct_objs( wss, num_cols );
00310   for( int kc = 0; kc < num_cols; ++kc ) {
00311     i_i_reduct_objs[kc] = op.reduct_obj_create();
00312     _i_i_reduct_objs[kc] = &*i_i_reduct_objs[kc];
00313   }
00314   ReductTargetSerializer<Scalar>
00315     serializer(Teuchos::rcpFromRef(op));
00316   ReductTargetReductionOp<Scalar>
00317     reductOp(Teuchos::rcpFromRef(op));
00318   reduceAll<Ordinal>(
00319     *comm, serializer, reductOp,
00320     num_cols, &i_reduct_objs[0], &_i_i_reduct_objs[0]);
00321   for( int kc = 0; kc < num_cols; ++kc ) {
00322     op.reduce_reduct_objs(*_i_i_reduct_objs[kc], Teuchos::ptr(reduct_objs[kc]));
00323   }
00324 }
00325 
00326 
00327 template<class Scalar>
00328 void RTOpPack::SPMD_apply_op(
00329   const Teuchos::Comm<index_type> *comm,
00330   const RTOpT<Scalar> &op,
00331   const int num_vecs,
00332   const RTOpPack::ConstSubVectorView<Scalar> sub_vecs[],
00333   const int num_targ_vecs,
00334   const RTOpPack::SubVectorView<Scalar> targ_sub_vecs[],
00335   ReductTarget *reduct_obj
00336   )
00337 {
00338   ReductTarget* reduct_objs[] = { reduct_obj };
00339   SPMD_apply_op(
00340     comm,op,1,num_vecs,sub_vecs,num_targ_vecs,targ_sub_vecs
00341     ,reduct_obj ? reduct_objs : NULL
00342     );
00343 }
00344 
00345 
00347 template<class Scalar>
00348 void RTOpPack::SPMD_apply_op(
00349   const Teuchos::Comm<index_type> *comm,
00350   const RTOpT<Scalar> &op,
00351   const int num_cols,
00352   const int num_multi_vecs,
00353   const RTOpPack::ConstSubMultiVectorView<Scalar> sub_multi_vecs[],
00354   const int num_targ_multi_vecs,
00355   const RTOpPack::SubMultiVectorView<Scalar> targ_sub_multi_vecs[],
00356   RTOpPack::ReductTarget*const reduct_objs[]
00357   )
00358 {
00359   using Teuchos::arcp;
00360   using Teuchos::Workspace;
00361   Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00362   int k, j, off;
00363   Workspace<ConstSubVectorView<Scalar> > c_sub_vecs(wss,num_multi_vecs*num_cols);
00364   if(sub_multi_vecs) {
00365     for( off = 0, j = 0; j < num_cols; ++j ) {
00366       for( k = 0; k < num_multi_vecs; ++k ) {
00367         const ConstSubMultiVectorView<Scalar> &mv = sub_multi_vecs[k];
00368         c_sub_vecs[off++].initialize(mv.globalOffset(), mv.subDim(),
00369           arcp(&mv(0,j), 0, mv.subDim(), false), 1);
00370       }
00371     }
00372   }
00373   Workspace<SubVectorView<Scalar> > c_targ_sub_vecs(wss,num_targ_multi_vecs*num_cols);
00374   if(targ_sub_multi_vecs) {
00375     for( off = 0, j = 0; j < num_cols; ++j ) {
00376       for( k = 0; k < num_targ_multi_vecs; ++k ) {
00377         const SubMultiVectorView<Scalar> &mv = targ_sub_multi_vecs[k];
00378         c_targ_sub_vecs[off++].initialize(mv.globalOffset(), mv.subDim(),
00379           arcp(&mv(0,j), 0, mv.subDim(), false), 1);
00380       }
00381     }
00382   }
00383   SPMD_apply_op(
00384     comm,op,num_cols
00385     ,num_multi_vecs, num_multi_vecs && sub_multi_vecs ? &c_sub_vecs[0] : NULL
00386     ,num_targ_multi_vecs, num_targ_multi_vecs && targ_sub_multi_vecs ? &c_targ_sub_vecs[0] : NULL
00387     ,reduct_objs
00388     );
00389 }
00390 
00391 
00392 template<class Scalar>
00393 void RTOpPack::SPMD_apply_op(
00394   const Teuchos::Comm<index_type> *comm,
00395   const RTOpT<Scalar> &op,
00396   const int num_cols,
00397   const int num_vecs,
00398   const ConstSubVectorView<Scalar> sub_vecs[],
00399   const int num_targ_vecs,
00400   const SubVectorView<Scalar> sub_targ_vecs[],
00401   ReductTarget*const reduct_objs[]
00402   )
00403 {
00404   using Teuchos::arrayView;
00405 #ifdef RTOPPACK_ENABLE_SHOW_DUMP
00406   Teuchos::RCP<Teuchos::FancyOStream>
00407     out = Teuchos::VerboseObjectBase::getDefaultOStream();
00408   Teuchos::OSTab tab(out);
00409   if(show_spmd_apply_op_dump) {
00410     *out << "\nEntering RTOpPack::SPMD_apply_op(...) ...\n";
00411     *out
00412       << "\ncomm = " << (comm?comm->description():"NULL")
00413       << "\nop = " << op.description()
00414       << "\nnum_cols = " << num_cols
00415       << "\nnum_vecs = " << num_vecs
00416       << "\nnum_targ_vecs = " << num_targ_vecs
00417       << "\n";
00418     if( num_vecs && sub_vecs ) {
00419       *out << "\nInput vectors:\n";
00420       Teuchos::OSTab tab2(out);
00421       for( int kc = 0; kc < num_cols; ++kc ) {
00422         for( int k = 0; k < num_vecs; ++k ) {
00423           *out << "\nvecs["<<kc<<","<<k<<"] =\n";
00424           print(sub_vecs[kc*num_vecs+k],*out);
00425         }
00426       }
00427     }
00428     if( num_targ_vecs && sub_targ_vecs ) {
00429       *out << "\nInput/output vectors *before* transforamtion:\n";
00430       Teuchos::OSTab tab2(out);
00431       for( int kc = 0; kc < num_cols; ++kc ) {
00432         for( int k = 0; k < num_targ_vecs; ++k ) {
00433           *out << "\nvecs["<<kc<<","<<k<<"] =\n";
00434           print(sub_targ_vecs[kc*num_targ_vecs+k],*out);
00435         }
00436       }
00437     }
00438     if(reduct_objs) {
00439       *out << "\nInput/output reduction objects *before* reduction:\n";
00440       Teuchos::OSTab tab2(out);
00441       for( int kc = 0; kc < num_cols; ++kc ) {
00442         *out
00443           << "\nreduct_objs["<<kc<<"] =\n"
00444           << describe(*reduct_objs[kc],Teuchos::VERB_EXTREME);
00445       }
00446     }
00447   }
00448 #endif // RTOPPACK_ENABLE_SHOW_DUMP
00449   using Teuchos::Workspace;
00450   Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00451   if( reduct_objs == NULL && sub_vecs == NULL && sub_targ_vecs == NULL ) {
00452     // This is a transformation operation with no data on this processor.
00453     // Therefore, we can just exist!
00454   }
00455   else {
00456     const int localSubDim =
00457       ( num_vecs
00458         ? ( sub_vecs ? sub_vecs[0].subDim() : 0 )
00459         : ( sub_targ_vecs ? sub_targ_vecs[0].subDim() : 0 )
00460         );
00461     // See if we need to do any global communication at all?
00462     if( comm==NULL || reduct_objs == NULL ) {
00463       if( ( sub_vecs || sub_targ_vecs ) && localSubDim ) {
00464         for( int kc = 0; kc < num_cols; ++kc ) {
00465           op.apply_op(
00466             arrayView(sub_vecs+kc*num_vecs, num_vecs),
00467             arrayView(sub_targ_vecs+kc*num_targ_vecs, num_targ_vecs),
00468             reduct_objs ? Teuchos::ptr(reduct_objs[kc]) : Teuchos::null
00469             );
00470         }
00471       }
00472     }
00473     else {
00474       // Check the preconditions for excluding empty target vectors.
00475       TEST_FOR_EXCEPTION(
00476         ( ( num_vecs && !sub_vecs) || ( num_targ_vecs && !sub_targ_vecs) ) && !( !sub_vecs && !sub_targ_vecs )
00477         ,std::logic_error
00478         ,"SPMD_apply_op(...): Error, invalid arguments num_vecs = " << num_vecs
00479         << ", sub_vecs = " << sub_vecs << ", num_targ_vecs = " << num_targ_vecs
00480         << ", sub_targ_vecs = " << sub_targ_vecs
00481         );
00482       //
00483       // There is a non-null reduction target object and we are using
00484       // SPMD so we need to reduce it across processors
00485       //
00486       // Allocate the intermediate target object and perform the
00487       // reduction for the vector elements on this processor.
00488       //
00489       Workspace<Teuchos::RCP<ReductTarget> >
00490         i_reduct_objs( wss, num_cols );
00491       for( int kc = 0; kc < num_cols; ++kc ) {
00492         i_reduct_objs[kc] = op.reduct_obj_create();
00493         if( ( sub_vecs || sub_targ_vecs ) && localSubDim ) {
00494           op.apply_op(
00495             arrayView(sub_vecs+kc*num_vecs, num_vecs),
00496             arrayView(sub_targ_vecs+kc*num_targ_vecs, num_targ_vecs),
00497             i_reduct_objs[kc].ptr()
00498             );
00499         }
00500       }
00501 #ifdef RTOPPACK_ENABLE_SHOW_DUMP
00502       if(show_spmd_apply_op_dump) {
00503         if(reduct_objs) {
00504           *out << "\nIntermediate reduction objects in this process before global reduction:\n";
00505           Teuchos::OSTab tab2(out);
00506           for( int kc = 0; kc < num_cols; ++kc ) {
00507             *out
00508               << "\ni_reduct_objs["<<kc<<"] =\n"
00509               << describe(*i_reduct_objs[kc],Teuchos::VERB_EXTREME);
00510           }
00511         }
00512       }
00513 #endif // RTOPPACK_ENABLE_SHOW_DUMP
00514       //
00515       // Reduce the local intermediate reduction objects into the global reduction objects
00516       //
00517       Workspace<const ReductTarget*>
00518         _i_reduct_objs( wss, num_cols );
00519       for( int kc = 0; kc < num_cols; ++kc ) {
00520         _i_reduct_objs[kc] = &*i_reduct_objs[kc];
00521       }
00522 #ifdef RTOPPACK_ENABLE_SHOW_DUMP
00523       if(show_spmd_apply_op_dump) {
00524         if(reduct_objs) {
00525           *out << "\nPerforming global reduction ...\n";
00526         }
00527       }
00528 #endif // RTOPPACK_ENABLE_SHOW_DUMP
00529       SPMD_all_reduce(comm,op,num_cols,&_i_reduct_objs[0],reduct_objs);
00530     }
00531   }
00532 #ifdef RTOPPACK_ENABLE_SHOW_DUMP
00533   if(show_spmd_apply_op_dump) {
00534     if( num_targ_vecs && sub_targ_vecs ) {
00535       *out << "\nInput/output vectors *after* transforamtion:\n";
00536       Teuchos::OSTab tab2(out);
00537       for( int kc = 0; kc < num_cols; ++kc ) {
00538         for( int k = 0; k < num_targ_vecs; ++k ) {
00539           *out << "\nvecs["<<kc<<","<<k<<"] =\n";
00540           print(sub_targ_vecs[kc*num_targ_vecs+k],*out);
00541         }
00542       }
00543     }
00544     if(reduct_objs) {
00545       *out << "\nInput/output reduction objects *after* reduction:\n";
00546       Teuchos::OSTab tab2(out);
00547       for( int kc = 0; kc < num_cols; ++kc ) {
00548         *out
00549           << "\nreduct_objs["<<kc<<"] =\n"
00550           << describe(*reduct_objs[kc],Teuchos::VERB_EXTREME);
00551       }
00552     }
00553     *out << "\nLeaving RTOpPack::SPMD_apply_op(...) ...\n";
00554   }
00555 #endif // RTOPPACK_ENABLE_SHOW_DUMP
00556 }
00557 
00558 
00559 //
00560 // Explicit Template Instaniation Macros
00561 //
00562 
00563 
00564 #define RTOPPACK_SPMD_APPLY_OP_INSTANT_SCALAR(SCALAR) \
00565   \
00566   template int serializedSize<SCALAR >( \
00567     int num_values, \
00568     int num_indexes, \
00569     int num_chars \
00570     ); \
00571   \
00572   template void serialize<SCALAR >( \
00573     const RTOpT<SCALAR > &op, \
00574     Ordinal num_values, \
00575     Ordinal num_indexes, \
00576     Ordinal num_chars, \
00577     const ReductTarget &reduct_obj, \
00578     char reduct_obj_ext[] \
00579     ); \
00580   \
00581   template void deserialize<SCALAR >( \
00582     const RTOpT<SCALAR > &op, \
00583     int num_values_in, \
00584     int num_indexes_in, \
00585     int num_chars_in, \
00586     const char reduct_obj_ext[], \
00587     ReductTarget *reduct_obj \
00588     ); \
00589   \
00590   template class ReductTargetSerializer<SCALAR >; \
00591   \
00592   template class ReductTargetReductionOp<SCALAR >; \
00593   \
00594   template void SPMD_all_reduce<SCALAR >( \
00595     const Teuchos::Comm<index_type> *comm, \
00596     const RTOpT<SCALAR > &op, \
00597     const int num_cols, \
00598     const ReductTarget*const i_reduct_objs[], \
00599     ReductTarget*const reduct_objs[] \
00600     ); \
00601   \
00602   template void SPMD_apply_op<SCALAR >( \
00603     const Teuchos::Comm<index_type> *comm, \
00604     const RTOpT<SCALAR > &op, \
00605     const int num_vecs, \
00606     const RTOpPack::ConstSubVectorView<SCALAR > sub_vecs[], \
00607     const int num_targ_vecs, \
00608     const RTOpPack::SubVectorView<SCALAR > targ_sub_vecs[], \
00609     ReductTarget *reduct_obj \
00610     ); \
00611   \
00612   template void SPMD_apply_op<SCALAR >( \
00613     const Teuchos::Comm<index_type> *comm, \
00614     const RTOpT<SCALAR > &op, \
00615     const int num_cols, \
00616     const int num_multi_vecs, \
00617     const RTOpPack::ConstSubMultiVectorView<SCALAR > sub_multi_vecs[], \
00618     const int num_targ_multi_vecs, \
00619     const RTOpPack::SubMultiVectorView<SCALAR > targ_sub_multi_vecs[], \
00620     RTOpPack::ReductTarget*const reduct_objs[] \
00621     ); \
00622   \
00623   template void SPMD_apply_op<SCALAR >( \
00624     const Teuchos::Comm<index_type> *comm, \
00625     const RTOpT<SCALAR > &op, \
00626     const int num_cols, \
00627     const int num_vecs, \
00628     const ConstSubVectorView<SCALAR > sub_vecs[], \
00629     const int num_targ_vecs, \
00630     const SubVectorView<SCALAR > sub_targ_vecs[], \
00631     ReductTarget*const reduct_objs[] \
00632     );
00633 
00634 
00635 #endif // RTOPPACK_SPMD_APPLY_OP_DEF_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines