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