|
RTOp Package Browser (Single Doxygen Collection) Version of the Day
|
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
1.7.4