RTOp Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
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 
00051 //
00052 // Implementation-only utlities!
00053 //
00054 
00055 
00056 namespace RTOpPack {
00057 
00058 
00059 RCP<FancyOStream>& spmdApplyOpDumpOut();
00060 
00061 
00062 template<class Scalar>
00063 void print( const ConstSubVectorView<Scalar> &v, Teuchos::FancyOStream &out_arg )
00064 {
00065   Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::rcp(&out_arg,false);
00066   Teuchos::OSTab tab(out);
00067   *out << "globalOffset="<<v.globalOffset()<<"\n";
00068   *out << "subDim="<<v.subDim()<<"\n";
00069   *out << "values:\n";
00070   tab.incrTab();
00071   for( int i = 0; i < v.subDim(); ++i )
00072     *out << " " << v(i) << ":" << (v.globalOffset()+i);
00073   *out << "\n";
00074 }
00075 
00076 
00077 } // namespace RTOpPack
00078 
00079 
00080 // ///////////////////////////
00081 // Template implementations
00082 
00083 
00084 //
00085 // Misc Helper functions
00086 //
00087 
00088 
00089 template<class PrimitiveScalar>
00090 int RTOpPack::serializedSize(
00091   int num_values,
00092   int num_indexes,
00093   int num_chars
00094   )
00095 {
00096   return 3 * sizeof(index_type)
00097     + num_values * sizeof(PrimitiveScalar)
00098     + num_indexes * sizeof(index_type)
00099     + num_chars * sizeof(char_type);
00100 }
00101 
00102 
00103 template<class Scalar>
00104 void RTOpPack::serialize(
00105   const RTOpT<Scalar> &op,
00106   Ordinal num_values,
00107   Ordinal num_indexes,
00108   Ordinal num_chars,
00109   const ReductTarget &reduct_obj,
00110   char reduct_obj_ext[]
00111   )
00112 {
00113   using Teuchos::arrayView;
00114   typedef typename RTOpT<Scalar>::primitive_value_type primitive_value_type;
00115   typedef Teuchos::SerializationTraits<Ordinal, primitive_value_type> PVTST;
00116   typedef Teuchos::SerializationTraits<Ordinal, index_type> ITST;
00117   typedef Teuchos::SerializationTraits<Ordinal, char_type> CTST;
00118   const Ordinal
00119     prim_value_type_size = PVTST::fromCountToDirectBytes(1),
00120     index_type_size = ITST::fromCountToDirectBytes(1);
00121   //char_type_size = CTST::fromCountToDirectBytes(1);
00122   const Ordinal
00123     num_values_off = 0,
00124     num_indexes_off = num_values_off + index_type_size,
00125     num_chars_off = num_indexes_off + index_type_size,
00126     values_off = num_chars_off + index_type_size,
00127     indexes_off = values_off + num_values * prim_value_type_size,
00128     chars_off = indexes_off + num_indexes * index_type_size;
00129   ITST::serialize(1, &num_values, index_type_size, &reduct_obj_ext[num_values_off]);
00130   ITST::serialize(1, &num_indexes, index_type_size, &reduct_obj_ext[num_indexes_off]);
00131   ITST::serialize(1, &num_chars, index_type_size, &reduct_obj_ext[num_chars_off]);
00132   op.extract_reduct_obj_state(
00133     reduct_obj,
00134     arrayView(PVTST::convertFromCharPtr(&reduct_obj_ext[values_off]), num_values),
00135     arrayView(ITST::convertFromCharPtr(&reduct_obj_ext[indexes_off]), num_indexes),
00136     arrayView(CTST::convertFromCharPtr(&reduct_obj_ext[chars_off]), num_chars)
00137     );
00138   // ToDo: Change above implementation to only require indirect serialization!
00139 }
00140 
00141 
00142 template<class Scalar>
00143 void RTOpPack::deserialize(
00144   const RTOpT<Scalar> &op,
00145   int num_values_in,
00146   int num_indexes_in,
00147   int num_chars_in,
00148   const char reduct_obj_ext[],
00149   ReductTarget *reduct_obj
00150   )
00151 {
00152   using Teuchos::arrayView;
00153   typedef typename RTOpT<Scalar>::primitive_value_type primitive_value_type;
00154   typedef Teuchos::SerializationTraits<int,primitive_value_type> PVTST;
00155   typedef Teuchos::SerializationTraits<int,index_type> ITST;
00156   typedef Teuchos::SerializationTraits<int,char_type> CTST;
00157   const Ordinal
00158     prim_value_type_size = PVTST::fromCountToDirectBytes(1),
00159     index_type_size = ITST::fromCountToDirectBytes(1);
00160   //char_type_size = CTST::fromCountToDirectBytes(1);
00161   const Ordinal
00162     num_values_off = 0,
00163     num_indexes_off = num_values_off + index_type_size,
00164     num_chars_off = num_indexes_off + index_type_size,
00165     values_off = num_chars_off + index_type_size,
00166     indexes_off = values_off + num_values_in * prim_value_type_size,
00167     chars_off = indexes_off + num_indexes_in * index_type_size;
00168 #ifdef RTOP_DEBUG
00169   Ordinal num_values = -1, num_indexes = -1, num_chars = -1;
00170   ITST::deserialize(index_type_size, &reduct_obj_ext[num_values_off], 1, &num_values);
00171   ITST::deserialize(index_type_size, &reduct_obj_ext[num_indexes_off], 1, &num_indexes);
00172   ITST::deserialize(index_type_size, &reduct_obj_ext[num_chars_off], 1, &num_chars);
00173   TEUCHOS_TEST_FOR_EXCEPTION(
00174     !(
00175       num_values==num_values_in && num_indexes==num_indexes_in
00176       && num_chars==num_chars_in ),
00177     std::logic_error,
00178     "Error: RTOp="<<op.op_name()
00179     << ", num_values="<<num_values<<", num_values_in="<<num_values_in
00180     << ", num_indexes="<<num_indexes<<", num_indexes_in="<<num_indexes_in
00181     << ", num_chars="<<num_chars<<", num_chars_in="<<num_chars_in
00182     );
00183 #endif
00184   op.load_reduct_obj_state(
00185     arrayView(PVTST::convertFromCharPtr(&reduct_obj_ext[values_off]), num_values_in),
00186     arrayView(ITST::convertFromCharPtr(&reduct_obj_ext[indexes_off]), num_indexes_in),
00187     arrayView(CTST::convertFromCharPtr(&reduct_obj_ext[chars_off]), num_chars_in),
00188     Teuchos::ptr(reduct_obj)
00189     );
00190   // ToDo: Change above implementation to only require indirect serialization!
00191 }
00192 
00193 
00194 namespace RTOpPack {
00195 
00196 
00197 //
00198 // ReductTargetSerializer
00199 //
00200 
00201 
00202 template<class Scalar>
00203 ReductTargetSerializer<Scalar>::ReductTargetSerializer(
00204   const Teuchos::RCP<const RTOpT<Scalar> > &op
00205   )
00206   :op_(op.assert_not_null())
00207 {
00208   using Teuchos::outArg;
00209   typedef typename RTOpT<Scalar>::primitive_value_type PrimitiveScalar;
00210   op_->get_reduct_type_num_entries(
00211     outArg(num_values_), outArg(num_indexes_), outArg(num_chars_) );
00212   reduct_obj_ext_size_ =
00213     serializedSize<PrimitiveScalar>(num_values_,num_indexes_,num_chars_);
00214 }
00215 
00216 
00217 template<class Scalar>
00218 index_type
00219 ReductTargetSerializer<Scalar>::getBufferSize(const index_type count) const
00220 {
00221   return reduct_obj_ext_size_ * count;
00222 }
00223 
00224 
00225 template<class Scalar>
00226 void ReductTargetSerializer<Scalar>::serialize(
00227   const index_type count
00228   ,const ReductTarget * const reduct_objs[]
00229   ,const index_type bytes
00230   ,char charBuffer[]
00231   ) const
00232 {
00233 #ifdef RTOP_DEBUG
00234   TEUCHOS_TEST_FOR_EXCEPT( !(count > 0) );
00235   TEUCHOS_TEST_FOR_EXCEPT( !reduct_objs );
00236   TEUCHOS_TEST_FOR_EXCEPT( !(bytes==this->getBufferSize(count)) );
00237   TEUCHOS_TEST_FOR_EXCEPT( !charBuffer );
00238 #endif
00239   Ordinal offset = 0;
00240   for( Ordinal i = 0; i < count; ++i, offset += reduct_obj_ext_size_ ) {
00241     RTOpPack::serialize(
00242       *op_,num_values_,num_indexes_,num_chars_
00243       ,*reduct_objs[i],&charBuffer[offset]
00244       );
00245   }
00246 }
00247 
00248 
00249 template<class Scalar>
00250 Teuchos::RCP<ReductTarget>
00251 ReductTargetSerializer<Scalar>::createObj() const
00252 {
00253   return op_->reduct_obj_create();
00254 }
00255 
00256 template<class Scalar>
00257 void ReductTargetSerializer<Scalar>::deserialize(
00258   const index_type bytes
00259   ,const char charBuffer[]
00260   ,const index_type count
00261   ,ReductTarget * const reduct_objs[]
00262   ) const
00263 {
00264 #ifdef RTOP_DEBUG
00265   TEUCHOS_TEST_FOR_EXCEPT( !(bytes > 0) );
00266   TEUCHOS_TEST_FOR_EXCEPT( !charBuffer );
00267   TEUCHOS_TEST_FOR_EXCEPT( !(bytes==getBufferSize(count)) );
00268   TEUCHOS_TEST_FOR_EXCEPT( !reduct_objs );
00269 #endif
00270   Ordinal offset = 0;
00271   for( Ordinal i = 0; i < count; ++i, offset += reduct_obj_ext_size_ ) {
00272     RTOpPack::deserialize(
00273       *op_,num_values_,num_indexes_,num_chars_
00274       ,&charBuffer[offset],reduct_objs[i]
00275       );
00276   }
00277 }
00278 
00279 
00280 //
00281 // ReductTargetReductionOp
00282 //
00283 
00284 
00285 template<class Scalar>
00286 ReductTargetReductionOp<Scalar>::ReductTargetReductionOp(
00287   const Teuchos::RCP<const RTOpT<Scalar> > &op
00288   )
00289   :op_(op)
00290 {}
00291 
00292  
00293 template<class Scalar>
00294 void ReductTargetReductionOp<Scalar>::reduce(
00295   const Ordinal count,
00296   const ReductTarget*const inBuffer[],
00297   ReductTarget*const inoutBuffer[]
00298   ) const
00299 {
00300   for( Ordinal i = 0; i < count; ++i )
00301     op_->reduce_reduct_objs( *inBuffer[i], Teuchos::ptr(inoutBuffer[i]) );
00302 }
00303 
00304 
00305 } // namespace RTOpPack
00306 
00307 
00308 template<class Scalar>
00309 void RTOpPack::SPMD_all_reduce(
00310   const Teuchos::Comm<index_type> *comm,
00311   const RTOpT<Scalar> &op,
00312   const int num_cols,
00313   const ReductTarget*const i_reduct_objs[],
00314   ReductTarget*const reduct_objs[]
00315   )
00316 {
00317   using Teuchos::Workspace;
00318   using Teuchos::reduceAll;
00319   Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00320   Workspace<Teuchos::RCP<ReductTarget> >
00321     i_i_reduct_objs( wss, num_cols );
00322   Workspace<ReductTarget*>
00323     _i_i_reduct_objs( wss, num_cols );
00324   for( int kc = 0; kc < num_cols; ++kc ) {
00325     i_i_reduct_objs[kc] = op.reduct_obj_create();
00326     _i_i_reduct_objs[kc] = &*i_i_reduct_objs[kc];
00327   }
00328   ReductTargetSerializer<Scalar>
00329     serializer(Teuchos::rcpFromRef(op));
00330   ReductTargetReductionOp<Scalar>
00331     reductOp(Teuchos::rcpFromRef(op));
00332   reduceAll<Ordinal>(
00333     *comm, serializer, reductOp,
00334     num_cols, &i_reduct_objs[0], &_i_i_reduct_objs[0]);
00335   for( int kc = 0; kc < num_cols; ++kc ) {
00336     op.reduce_reduct_objs(*_i_i_reduct_objs[kc], Teuchos::ptr(reduct_objs[kc]));
00337   }
00338 }
00339 
00340 
00341 template<class Scalar>
00342 void RTOpPack::SPMD_apply_op(
00343   const Teuchos::Comm<index_type> *comm,
00344   const RTOpT<Scalar> &op,
00345   const int num_vecs,
00346   const RTOpPack::ConstSubVectorView<Scalar> sub_vecs[],
00347   const int num_targ_vecs,
00348   const RTOpPack::SubVectorView<Scalar> targ_sub_vecs[],
00349   ReductTarget *reduct_obj
00350   )
00351 {
00352   ReductTarget* reduct_objs[] = { reduct_obj };
00353   SPMD_apply_op(
00354     comm,op,1,num_vecs,sub_vecs,num_targ_vecs,targ_sub_vecs
00355     ,reduct_obj ? reduct_objs : NULL
00356     );
00357 }
00358 
00359 
00361 template<class Scalar>
00362 void RTOpPack::SPMD_apply_op(
00363   const Teuchos::Comm<index_type> *comm,
00364   const RTOpT<Scalar> &op,
00365   const int num_cols,
00366   const int num_multi_vecs,
00367   const RTOpPack::ConstSubMultiVectorView<Scalar> sub_multi_vecs[],
00368   const int num_targ_multi_vecs,
00369   const RTOpPack::SubMultiVectorView<Scalar> targ_sub_multi_vecs[],
00370   RTOpPack::ReductTarget*const reduct_objs[]
00371   )
00372 {
00373   using Teuchos::arcp;
00374   using Teuchos::Workspace;
00375   Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00376   int k, j, off;
00377   Workspace<ConstSubVectorView<Scalar> > c_sub_vecs(wss,num_multi_vecs*num_cols);
00378   if(sub_multi_vecs) {
00379     for( off = 0, j = 0; j < num_cols; ++j ) {
00380       for( k = 0; k < num_multi_vecs; ++k ) {
00381         const ConstSubMultiVectorView<Scalar> &mv = sub_multi_vecs[k];
00382         if (mv.subDim()) {
00383           c_sub_vecs[off++].initialize(mv.globalOffset(), mv.subDim(),
00384             arcp(&mv(0,j), 0, mv.subDim(), false), 1);
00385         }
00386         else {
00387           c_sub_vecs[off++].initialize(mv.globalOffset(), mv.subDim(),
00388             Teuchos::null, 1);
00389         }
00390       }
00391     }
00392   }
00393   Workspace<SubVectorView<Scalar> > c_targ_sub_vecs(wss,num_targ_multi_vecs*num_cols);
00394   if(targ_sub_multi_vecs) {
00395     for( off = 0, j = 0; j < num_cols; ++j ) {
00396       for( k = 0; k < num_targ_multi_vecs; ++k ) {
00397         const SubMultiVectorView<Scalar> &mv = targ_sub_multi_vecs[k];
00398         ArrayRCP<Scalar> mv_j = Teuchos::null;
00399         if (mv.subDim()) { mv_j = arcp(&mv(0,j), 0, mv.subDim(), false); }
00400         c_targ_sub_vecs[off++].initialize(mv.globalOffset(), mv.subDim(), mv_j, 1);
00401       }
00402     }
00403   }
00404   SPMD_apply_op(
00405     comm,op,num_cols
00406     ,num_multi_vecs, num_multi_vecs && sub_multi_vecs ? &c_sub_vecs[0] : NULL
00407     ,num_targ_multi_vecs, num_targ_multi_vecs && targ_sub_multi_vecs ? &c_targ_sub_vecs[0] : NULL
00408     ,reduct_objs
00409     );
00410 }
00411 
00412 
00413 template<class Scalar>
00414 void RTOpPack::SPMD_apply_op(
00415   const Teuchos::Comm<index_type> *comm,
00416   const RTOpT<Scalar> &op,
00417   const int num_cols,
00418   const int num_vecs,
00419   const ConstSubVectorView<Scalar> sub_vecs[],
00420   const int num_targ_vecs,
00421   const SubVectorView<Scalar> sub_targ_vecs[],
00422   ReductTarget*const reduct_objs[]
00423   )
00424 {
00425   using Teuchos::arrayView;
00426   Teuchos::RCP<Teuchos::FancyOStream> out = spmdApplyOpDumpOut();
00427   Teuchos::OSTab tab(out);
00428   if (nonnull(out)) {
00429     *out << "\nEntering RTOpPack::SPMD_apply_op(...) ...\n";
00430     *out
00431       << "\ncomm = " << (comm?comm->description():"NULL")
00432       << "\nop = " << op.description()
00433       << "\nnum_cols = " << num_cols
00434       << "\nnum_vecs = " << num_vecs
00435       << "\nnum_targ_vecs = " << num_targ_vecs
00436       << "\n";
00437     if( num_vecs && sub_vecs ) {
00438       *out << "\nInput vectors:\n";
00439       Teuchos::OSTab tab2(out);
00440       for( int kc = 0; kc < num_cols; ++kc ) {
00441         for( int k = 0; k < num_vecs; ++k ) {
00442           *out << "\nvecs["<<kc<<","<<k<<"] =\n";
00443           print(sub_vecs[kc*num_vecs+k],*out);
00444         }
00445       }
00446     }
00447     if( num_targ_vecs && sub_targ_vecs ) {
00448       *out << "\nInput/output vectors *before* transforamtion:\n";
00449       Teuchos::OSTab tab2(out);
00450       for( int kc = 0; kc < num_cols; ++kc ) {
00451         for( int k = 0; k < num_targ_vecs; ++k ) {
00452           *out << "\nvecs["<<kc<<","<<k<<"] =\n";
00453           print(sub_targ_vecs[kc*num_targ_vecs+k],*out);
00454         }
00455       }
00456     }
00457     if(reduct_objs) {
00458       *out << "\nInput/output reduction objects *before* reduction:\n";
00459       Teuchos::OSTab tab2(out);
00460       for( int kc = 0; kc < num_cols; ++kc ) {
00461         *out
00462           << "\nreduct_objs["<<kc<<"] =\n"
00463           << describe(*reduct_objs[kc],Teuchos::VERB_EXTREME);
00464       }
00465     }
00466   }
00467   using Teuchos::Workspace;
00468   Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00469   if( reduct_objs == NULL && sub_vecs == NULL && sub_targ_vecs == NULL ) {
00470     // This is a transformation operation with no data on this processor.
00471     // Therefore, we can just exist!
00472   }
00473   else {
00474     const int localSubDim =
00475       ( num_vecs
00476         ? ( sub_vecs ? sub_vecs[0].subDim() : 0 )
00477         : ( sub_targ_vecs ? sub_targ_vecs[0].subDim() : 0 )
00478         );
00479     // See if we need to do any global communication at all?
00480     if( comm==NULL || reduct_objs == NULL ) {
00481       if( ( sub_vecs || sub_targ_vecs ) && localSubDim ) {
00482         for( int kc = 0; kc < num_cols; ++kc ) {
00483           op.apply_op(
00484             arrayView(sub_vecs+kc*num_vecs, num_vecs),
00485             arrayView(sub_targ_vecs+kc*num_targ_vecs, num_targ_vecs),
00486             reduct_objs ? Teuchos::ptr(reduct_objs[kc]) : Teuchos::null
00487             );
00488         }
00489       }
00490     }
00491     else {
00492       // Check the preconditions for excluding empty target vectors.
00493       TEUCHOS_TEST_FOR_EXCEPTION(
00494         ( ( num_vecs && !sub_vecs) || ( num_targ_vecs && !sub_targ_vecs) ) && !( !sub_vecs && !sub_targ_vecs )
00495         ,std::logic_error
00496         ,"SPMD_apply_op(...): Error, invalid arguments num_vecs = " << num_vecs
00497         << ", sub_vecs = " << sub_vecs << ", num_targ_vecs = " << num_targ_vecs
00498         << ", sub_targ_vecs = " << sub_targ_vecs
00499         );
00500       //
00501       // There is a non-null reduction target object and we are using
00502       // SPMD so we need to reduce it across processors
00503       //
00504       // Allocate the intermediate target object and perform the
00505       // reduction for the vector elements on this processor.
00506       //
00507       Workspace<Teuchos::RCP<ReductTarget> >
00508         i_reduct_objs( wss, num_cols );
00509       for( int kc = 0; kc < num_cols; ++kc ) {
00510         i_reduct_objs[kc] = op.reduct_obj_create();
00511         if( ( sub_vecs || sub_targ_vecs ) && localSubDim ) {
00512           op.apply_op(
00513             arrayView(sub_vecs+kc*num_vecs, num_vecs),
00514             arrayView(sub_targ_vecs+kc*num_targ_vecs, num_targ_vecs),
00515             i_reduct_objs[kc].ptr()
00516             );
00517         }
00518       }
00519       if(nonnull(out)) {
00520         if(reduct_objs) {
00521           *out << "\nIntermediate reduction objects in this process before global reduction:\n";
00522           Teuchos::OSTab tab2(out);
00523           for( int kc = 0; kc < num_cols; ++kc ) {
00524             *out
00525               << "\ni_reduct_objs["<<kc<<"] =\n"
00526               << describe(*i_reduct_objs[kc],Teuchos::VERB_EXTREME);
00527           }
00528         }
00529       }
00530       //
00531       // Reduce the local intermediate reduction objects into the global reduction objects
00532       //
00533       Workspace<const ReductTarget*>
00534         _i_reduct_objs( wss, num_cols );
00535       for( int kc = 0; kc < num_cols; ++kc ) {
00536         _i_reduct_objs[kc] = &*i_reduct_objs[kc];
00537       }
00538       if(nonnull(out)) {
00539         if(reduct_objs) {
00540           *out << "\nPerforming global reduction ...\n";
00541         }
00542       }
00543       SPMD_all_reduce(comm,op,num_cols,&_i_reduct_objs[0],reduct_objs);
00544     }
00545   }
00546   if(nonnull(out)) {
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     *out << std::flush;
00568   }
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