|
Support Software for Vector Reduction/Transformation Operators
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 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
1.7.6.1