|
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 // 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::fromCountToDirectBytes(1), 00124 index_type_size = ITST::fromCountToDirectBytes(1); 00125 //char_type_size = CTST::fromCountToDirectBytes(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::fromCountToDirectBytes(1), 00163 index_type_size = ITST::fromCountToDirectBytes(1); 00164 //char_type_size = CTST::fromCountToDirectBytes(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 TEUCHOS_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 TEUCHOS_TEST_FOR_EXCEPT( !(count > 0) ); 00234 TEUCHOS_TEST_FOR_EXCEPT( !reduct_objs ); 00235 TEUCHOS_TEST_FOR_EXCEPT( !(bytes==this->getBufferSize(count)) ); 00236 TEUCHOS_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 TEUCHOS_TEST_FOR_EXCEPT( !(bytes > 0) ); 00265 TEUCHOS_TEST_FOR_EXCEPT( !charBuffer ); 00266 TEUCHOS_TEST_FOR_EXCEPT( !(bytes==getBufferSize(count)) ); 00267 TEUCHOS_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 TEUCHOS_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
1.7.6.1