|
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_RTOP_T_HELPERS_DECL_HPP 00044 #define RTOPPACK_RTOP_T_HELPERS_DECL_HPP 00045 00046 00047 //#define RTOPPACK_RTOPT_HELPER_DUMP_OUTPUT 00048 00049 00050 #include <typeinfo> 00051 00052 00053 #include "RTOpPack_RTOpT.hpp" 00054 #include "Teuchos_StandardMemberCompositionMacros.hpp" 00055 #include "Teuchos_ScalarTraits.hpp" 00056 #include "Teuchos_dyn_cast.hpp" 00057 #include "Teuchos_TypeNameTraits.hpp" 00058 00059 00060 #ifdef RTOPPACK_RTOPT_HELPER_DUMP_OUTPUT 00061 # include "Teuchos_VerboseObject.hpp" 00062 namespace RTOpPack { extern bool rtop_helpers_dump_all; } 00063 #endif // RTOPPACK_RTOPT_HELPER_DUMP_OUTPUT 00064 00065 00066 namespace RTOpPack { 00067 00068 00073 template<class Scalar> 00074 struct ScalarIndex { 00076 Scalar scalar; 00078 Ordinal index; 00080 ScalarIndex( const Scalar &_scalar, const Ordinal &_index ) 00081 : scalar(_scalar), index(_index) 00082 {} 00084 ScalarIndex() 00085 : scalar(ScalarTraits<Scalar>::zero()), index(-1) 00086 {} 00087 }; 00088 00089 00094 template<class Scalar> 00095 std::ostream& operator<<(std::ostream &out, const ScalarIndex<Scalar> &scalarIndex) 00096 { 00097 out << "{"<<scalarIndex.scalar<<","<<scalarIndex.index<<"}"; 00098 return out; 00099 } 00100 00101 00105 template <class Scalar> 00106 class PrimitiveTypeTraits<Scalar, ScalarIndex<Scalar> > { 00107 public: 00109 typedef PrimitiveTypeTraits<Scalar,Scalar> ScalarPrimitiveTypeTraits; 00111 typedef typename ScalarPrimitiveTypeTraits::primitiveType primitiveType; 00113 static int numPrimitiveObjs() { return ScalarPrimitiveTypeTraits::numPrimitiveObjs(); } 00115 static int numIndexObjs() { return 1; } 00117 static int numCharObjs() { return 0; } 00119 static void extractPrimitiveObjs( 00120 const ScalarIndex<Scalar> &obj, 00121 const ArrayView<primitiveType> &primitiveObjs, 00122 const ArrayView<index_type> &indexObjs, 00123 const ArrayView<char> &charObjs 00124 ) 00125 { 00126 assertInput(primitiveObjs, indexObjs, charObjs); 00127 ScalarPrimitiveTypeTraits::extractPrimitiveObjs( 00128 obj.scalar, primitiveObjs, Teuchos::null, Teuchos::null ); 00129 indexObjs[0] = obj.index; 00130 } 00132 static void loadPrimitiveObjs( 00133 const ArrayView<const primitiveType> &primitiveObjs, 00134 const ArrayView<const index_type> &indexObjs, 00135 const ArrayView<const char> &charObjs, 00136 const Ptr<ScalarIndex<Scalar> > &obj 00137 ) 00138 { 00139 assertInput(primitiveObjs, indexObjs, charObjs); 00140 ScalarPrimitiveTypeTraits::loadPrimitiveObjs( 00141 primitiveObjs, Teuchos::null, Teuchos::null, 00142 Teuchos::outArg(obj->scalar) ); 00143 obj->index = indexObjs[0]; 00144 } 00145 private: 00146 static void assertInput( 00147 const ArrayView<const primitiveType> &primitiveObjs, 00148 const ArrayView<const index_type> &indexObjs, 00149 const ArrayView<const char> &charObjs 00150 ) 00151 { 00152 #ifdef TEUCHOS_DEBUG 00153 TEUCHOS_TEST_FOR_EXCEPT( 00154 primitiveObjs.size()!=ScalarPrimitiveTypeTraits::numPrimitiveObjs() 00155 || indexObjs.size()!=1 00156 || charObjs.size()!=0 ); 00157 #endif 00158 } 00159 }; 00160 00161 00166 template<class ConcreteReductObj> 00167 class DefaultReductTarget : public ReductTarget { 00168 public: 00170 DefaultReductTarget( const ConcreteReductObj &concreteReductObj ) 00171 : concreteReductObj_(concreteReductObj) 00172 {} 00174 void set( const ConcreteReductObj &concreteReductObj ) 00175 { concreteReductObj_ = concreteReductObj; } 00177 const ConcreteReductObj& get() const 00178 { return concreteReductObj_; } 00180 std::string description() const; 00181 private: 00182 ConcreteReductObj concreteReductObj_; 00183 }; 00184 00185 00190 template<class ConcreteReductObj> 00191 const RCP<DefaultReductTarget<ConcreteReductObj> > 00192 defaultReductTarget( const ConcreteReductObj &concreteReductObj ) 00193 { 00194 return Teuchos::rcp( 00195 new DefaultReductTarget<ConcreteReductObj>(concreteReductObj)); 00196 } 00197 00198 00221 template<class Scalar> 00222 void validate_apply_op( 00223 const RTOpT<Scalar> &op, 00224 const int allowed_num_sub_vecs, 00225 const int allowed_num_targ_sub_vecs, 00226 const bool expect_reduct_obj, 00227 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00228 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00229 const Ptr<const ReductTarget> &reduct_obj 00230 ); 00231 00232 00233 // 00234 // Reduction object operator support 00235 // 00236 00237 00239 enum EBasicReductTypes { REDUCT_TYPE_SUM, REDUCT_TYPE_MAX, REDUCT_TYPE_MIN }; 00240 00241 00243 template<class ConcreteReductObj, int ReductionType> 00244 class BasicReductObjReductionOp { 00245 public: 00247 inline void operator()(const ConcreteReductObj& in_reduct, ConcreteReductObj& inout_reduct) const 00248 { 00249 return in_reduct.this_reduction_type_needs_a_specialization(); 00250 } 00251 }; 00252 00253 00255 template<class ConcreteReductObj> 00256 class BasicReductObjReductionOp<ConcreteReductObj, REDUCT_TYPE_SUM> { 00257 public: 00259 inline void operator()(const ConcreteReductObj& in_reduct, ConcreteReductObj& inout_reduct) const 00260 { 00261 inout_reduct += in_reduct; 00262 } 00263 }; 00264 00265 00267 template<class ConcreteReductObj> 00268 class BasicReductObjReductionOp<ConcreteReductObj, REDUCT_TYPE_MAX> { 00269 public: 00271 inline void operator()(const ConcreteReductObj& in_reduct, ConcreteReductObj& inout_reduct) const 00272 { 00273 inout_reduct = std::max(inout_reduct, in_reduct); 00274 } 00275 }; 00276 00277 00279 template<class ConcreteReductObj> 00280 class BasicReductObjReductionOp<ConcreteReductObj, REDUCT_TYPE_MIN> { 00281 public: 00283 inline void operator()(const ConcreteReductObj& in_reduct, ConcreteReductObj& inout_reduct) const 00284 { 00285 inout_reduct = std::min(inout_reduct, in_reduct); 00286 } 00287 }; 00288 00289 00291 template<class Scalar> 00292 class SumScalarReductObjReduction { 00293 public: 00295 inline void operator()(const Scalar& in_reduct, Scalar& inout_reduct) const 00296 { 00297 inout_reduct += in_reduct; 00298 } 00299 }; 00300 // 2008/07/03: rabart: Above: I have broken from the Thyra guideline of 00301 // passing in-out arguments as const Ptr<Type>& and used raw non-const 00302 // reference Type& instead to allow the user function to be more readable. 00303 00304 00306 template<class Scalar, class ConcreteReductObj, class ReductObjReduction> 00307 class ROpScalarReductionWithOpBase : public RTOpT<Scalar> 00308 { 00309 public: 00310 00312 using RTOpT<Scalar>::apply_op; 00313 00315 typedef typename RTOpT<Scalar>::primitive_value_type primitive_value_type; 00316 00318 ROpScalarReductionWithOpBase( 00319 const ConcreteReductObj &initReductObjValue_in = ScalarTraits<Scalar>::zero(), 00320 ReductObjReduction reductObjReduction_in = ReductObjReduction() 00321 ) 00322 : initReductObjValue_(initReductObjValue_in), 00323 reductObjReduction_(reductObjReduction_in) 00324 {} 00325 00327 const ConcreteReductObj& getRawVal( const ReductTarget &reduct_obj ) const 00328 { 00329 using Teuchos::dyn_cast; 00330 return dyn_cast<const DefaultReductTarget<ConcreteReductObj> >(reduct_obj).get(); 00331 } 00332 00334 void setRawVal( const ConcreteReductObj &rawVal, 00335 const Ptr<ReductTarget> &reduct_obj 00336 ) const 00337 { 00338 using Teuchos::dyn_cast; 00339 dyn_cast<DefaultReductTarget<ConcreteReductObj> >(*reduct_obj).set(rawVal); 00340 } 00341 00343 ConcreteReductObj operator()(const ReductTarget& reduct_obj ) const 00344 { 00345 return this->getRawVal(reduct_obj); 00346 } 00347 00350 00352 void get_reduct_type_num_entries_impl( 00353 const Ptr<int> &num_values, 00354 const Ptr<int> &num_indexes, 00355 const Ptr<int> &num_chars 00356 ) const 00357 { 00358 typedef PrimitiveTypeTraits<Scalar, ConcreteReductObj> PTT; 00359 *num_values = PTT::numPrimitiveObjs(); 00360 *num_indexes = PTT::numIndexObjs(); 00361 *num_chars = PTT::numCharObjs(); 00362 } 00363 00365 Teuchos::RCP<ReductTarget> reduct_obj_create_impl() const 00366 { 00367 return Teuchos::rcp( 00368 new DefaultReductTarget<ConcreteReductObj>(initReductObjValue())); 00369 } 00370 00372 virtual void reduce_reduct_objs_impl( 00373 const ReductTarget& in_reduct_obj, const Ptr<ReductTarget>& inout_reduct_obj 00374 ) const 00375 { 00376 const ConcreteReductObj scalar_in_reduct_obj = this->getRawVal(in_reduct_obj); 00377 ConcreteReductObj scalar_inout_reduct_obj = this->getRawVal(*inout_reduct_obj); 00378 reductObjReduction_(scalar_in_reduct_obj, scalar_inout_reduct_obj); 00379 this->setRawVal( scalar_inout_reduct_obj, inout_reduct_obj ); 00380 } 00381 00383 void reduct_obj_reinit_impl( const Ptr<ReductTarget> &reduct_obj ) const 00384 { 00385 setRawVal( initReductObjValue(), reduct_obj ); 00386 } 00387 00389 void extract_reduct_obj_state_impl( 00390 const ReductTarget &reduct_obj, 00391 const ArrayView<primitive_value_type> &value_data, 00392 const ArrayView<index_type> &index_data, 00393 const ArrayView<char_type> &char_data 00394 ) const 00395 { 00396 typedef PrimitiveTypeTraits<Scalar, ConcreteReductObj> PTT; 00397 PTT::extractPrimitiveObjs( getRawVal(reduct_obj), 00398 value_data, index_data, char_data ); 00399 } 00400 00402 void load_reduct_obj_state_impl( 00403 const ArrayView<const primitive_value_type> &value_data, 00404 const ArrayView<const index_type> &index_data, 00405 const ArrayView<const char_type> &char_data, 00406 const Ptr<ReductTarget> &reduct_obj 00407 ) const 00408 { 00409 typedef PrimitiveTypeTraits<Scalar, ConcreteReductObj> PTT; 00410 ConcreteReductObj concrete_reduct_obj; 00411 PTT::loadPrimitiveObjs( value_data, index_data, char_data, 00412 Teuchos::outArg(concrete_reduct_obj) ); 00413 this->setRawVal( concrete_reduct_obj, reduct_obj ); 00414 } 00415 00417 00418 protected: 00419 00421 STANDARD_MEMBER_COMPOSITION_MEMBERS( ConcreteReductObj, initReductObjValue ); 00422 00423 private: 00424 00425 ReductObjReduction reductObjReduction_; 00426 00427 }; 00428 00429 00430 // 00431 // ROp 1 vector scalar reduction 00432 // 00433 00434 00436 template<class Scalar, class ConcreteReductObj, class EleWiseReduction, 00437 class ReductObjReduction = SumScalarReductObjReduction<ConcreteReductObj> > 00438 class ROp_1_ScalarReduction 00439 : public ROpScalarReductionWithOpBase<Scalar, ConcreteReductObj, ReductObjReduction> 00440 { 00441 public: 00442 00444 typedef ROpScalarReductionWithOpBase<Scalar, ConcreteReductObj, ReductObjReduction> base_t; 00445 00447 ROp_1_ScalarReduction( 00448 const ConcreteReductObj &initReductObjValue_in = ConcreteReductObj(), 00449 EleWiseReduction eleWiseReduction_in = EleWiseReduction(), 00450 ReductObjReduction reductObjReduction_in = ReductObjReduction() 00451 ) 00452 : base_t(initReductObjValue_in, reductObjReduction_in), 00453 eleWiseReduction_(eleWiseReduction_in) 00454 {} 00455 00458 00460 void apply_op_impl( 00461 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00462 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00463 const Ptr<ReductTarget> &reduct_obj_inout 00464 ) const 00465 { 00466 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 00467 using Teuchos::dyn_cast; 00468 00469 #ifdef TEUCHOS_DEBUG 00470 validate_apply_op<Scalar>(*this, 1, 0, true, 00471 sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst()); 00472 #endif 00473 00474 DefaultReductTarget<ConcreteReductObj> &reduct_obj = 00475 dyn_cast<DefaultReductTarget<ConcreteReductObj> >(*reduct_obj_inout); 00476 ConcreteReductObj reduct = reduct_obj.get(); 00477 00478 const RTOpPack::index_type subDim = sub_vecs[0].subDim(); 00479 00480 const_iter_t v0_val = sub_vecs[0].values().begin(); 00481 const ptrdiff_t v0_s = sub_vecs[0].stride(); 00482 00483 if ( v0_s == 1 ) { 00484 for( Teuchos_Ordinal i = 0; i < subDim; ++i ) 00485 eleWiseReduction_( *v0_val++, reduct); 00486 } 00487 else { 00488 for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s ) 00489 eleWiseReduction_( *v0_val, reduct); 00490 } 00491 00492 reduct_obj.set(reduct); 00493 00494 } 00495 00497 00498 private: 00499 00500 EleWiseReduction eleWiseReduction_; 00501 00502 }; 00503 00504 00506 #define RTOP_ROP_1_REDUCT_SCALAR_CUSTOM_DEFAULT( ROP_CLASS_NAME, REDUCT_SCALAR, \ 00507 BASIC_REDUCT_TYPE_ENUM, CUSTOM_DEFAULT \ 00508 ) \ 00509 \ 00510 template<class Scalar, class ReductScalar> \ 00511 class ROP_CLASS_NAME ## EleWiseReduction \ 00512 { \ 00513 public: \ 00514 inline void operator()( \ 00515 const Scalar &v0, \ 00516 ReductScalar &reduct \ 00517 ) const; \ 00518 }; \ 00519 \ 00520 \ 00521 template<class Scalar> \ 00522 class ROP_CLASS_NAME \ 00523 : public RTOpPack::ROp_1_ScalarReduction< \ 00524 Scalar, \ 00525 REDUCT_SCALAR, \ 00526 ROP_CLASS_NAME ## EleWiseReduction<Scalar, REDUCT_SCALAR >, \ 00527 RTOpPack::BasicReductObjReductionOp<REDUCT_SCALAR, BASIC_REDUCT_TYPE_ENUM> > \ 00528 { \ 00529 typedef RTOpPack::ROp_1_ScalarReduction< \ 00530 Scalar, \ 00531 REDUCT_SCALAR, \ 00532 ROP_CLASS_NAME ## EleWiseReduction<Scalar, REDUCT_SCALAR >, \ 00533 RTOpPack::BasicReductObjReductionOp<REDUCT_SCALAR, BASIC_REDUCT_TYPE_ENUM> > \ 00534 base_t; \ 00535 public: \ 00536 ROP_CLASS_NAME() \ 00537 : base_t(CUSTOM_DEFAULT) \ 00538 { \ 00539 this->setOpNameBase( #ROP_CLASS_NAME ); \ 00540 } \ 00541 }; \ 00542 \ 00543 \ 00544 template<class Scalar, class ReductScalar> \ 00545 void ROP_CLASS_NAME ## EleWiseReduction<Scalar, ReductScalar>::operator()( \ 00546 const Scalar &v0, ReductScalar &reduct \ 00547 ) const 00548 00549 00551 #define RTOP_ROP_1_REDUCT_SCALAR( ROP_CLASS_NAME, REDUCT_SCALAR, \ 00552 BASIC_REDUCT_TYPE_ENUM \ 00553 ) \ 00554 RTOP_ROP_1_REDUCT_SCALAR_CUSTOM_DEFAULT(ROP_CLASS_NAME, REDUCT_SCALAR, \ 00555 BASIC_REDUCT_TYPE_ENUM, Teuchos::ScalarTraits<REDUCT_SCALAR >::zero() ) 00556 00557 00558 // 00559 // ROp 1 coordinate-variant vector scalar reduction 00560 // 00561 00562 00565 template< 00566 class Scalar, 00567 class ReductScalar, 00568 class EleWiseReduction, 00569 class ReductObjReduction = SumScalarReductObjReduction<ReductScalar> 00570 > 00571 class ROp_1_CoordVariantScalarReduction 00572 : public ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction> 00573 { 00574 public: 00575 00578 00580 typedef ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction> base_t; 00581 00583 ROp_1_CoordVariantScalarReduction( 00584 const ReductScalar &initReductObjValue_in = ReductScalar(), 00585 EleWiseReduction eleWiseReduction_in = EleWiseReduction(), 00586 ReductObjReduction reductObjReduction_in = ReductObjReduction() 00587 ) 00588 : base_t(initReductObjValue_in, reductObjReduction_in), 00589 eleWiseReduction_(eleWiseReduction_in) 00590 {} 00591 00593 void setEleWiseReduction(EleWiseReduction eleWiseReduction_in) 00594 { eleWiseReduction_ = eleWiseReduction_in; } 00595 00597 const EleWiseReduction& getEleWiseReduction() const 00598 { return eleWiseReduction_; } 00599 00601 00604 00606 bool coord_invariant_impl() const { return false; } 00607 00609 void apply_op_impl( 00610 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00611 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00612 const Ptr<ReductTarget> &reduct_obj_inout 00613 ) const 00614 { 00615 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 00616 using Teuchos::dyn_cast; 00617 00618 #ifdef TEUCHOS_DEBUG 00619 validate_apply_op<Scalar>(*this, 1, 0, true, 00620 sub_vecs, targ_sub_vecs, reduct_obj_inout); 00621 #endif 00622 00623 DefaultReductTarget<ReductScalar> &reduct_obj = 00624 dyn_cast<DefaultReductTarget<ReductScalar> >(*reduct_obj_inout); 00625 ReductScalar reduct = reduct_obj.get(); 00626 00627 const RTOpPack::index_type subDim = sub_vecs[0].subDim(); 00628 00629 const_iter_t v0_val = sub_vecs[0].values().begin(); 00630 const ptrdiff_t v0_s = sub_vecs[0].stride(); 00631 00632 RTOpPack::index_type global_i = sub_vecs[0].globalOffset(); 00633 00634 if ( v0_s == 1 ) { 00635 for( Teuchos_Ordinal i = 0; i < subDim; ++i, ++global_i ) 00636 eleWiseReduction_( global_i, *v0_val++, reduct); 00637 } 00638 else { 00639 for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s, ++global_i ) 00640 eleWiseReduction_( global_i, *v0_val, reduct); 00641 } 00642 00643 reduct_obj.set(reduct); 00644 00645 } 00646 00648 00649 private: 00650 00651 EleWiseReduction eleWiseReduction_; 00652 00653 }; 00654 00655 00656 // 00657 // ROp 2 vector scalar reduction 00658 // 00659 00660 00662 template< 00663 class Scalar, 00664 class ReductScalar, 00665 class EleWiseReduction, 00666 class ReductObjReduction = SumScalarReductObjReduction<ReductScalar> 00667 > 00668 class ROp_2_ScalarReduction 00669 : public ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction> 00670 { 00671 public: 00672 00674 typedef ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction> 00675 base_t; 00676 00678 ROp_2_ScalarReduction( 00679 const ReductScalar &initReductObjValue_in = ReductScalar(), 00680 EleWiseReduction eleWiseReduction_in = EleWiseReduction(), 00681 ReductObjReduction reductObjReduction_in = ReductObjReduction() 00682 ) 00683 : base_t(initReductObjValue_in, reductObjReduction_in), 00684 eleWiseReduction_(eleWiseReduction_in) 00685 {} 00686 00689 00691 void apply_op_impl( 00692 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00693 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00694 const Ptr<ReductTarget> &reduct_obj_inout 00695 ) const 00696 { 00697 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 00698 using Teuchos::dyn_cast; 00699 00700 #ifdef TEUCHOS_DEBUG 00701 validate_apply_op<Scalar>(*this, 2, 0, true, 00702 sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst()); 00703 #endif 00704 00705 DefaultReductTarget<Scalar> &reduct_obj = 00706 dyn_cast<DefaultReductTarget<Scalar> >(*reduct_obj_inout); 00707 Scalar reduct = reduct_obj.get(); 00708 00709 const RTOpPack::index_type subDim = sub_vecs[0].subDim(); 00710 00711 const_iter_t v0_val = sub_vecs[0].values().begin(); 00712 const ptrdiff_t v0_s = sub_vecs[0].stride(); 00713 const_iter_t v1_val = sub_vecs[1].values().begin(); 00714 const ptrdiff_t v1_s = sub_vecs[1].stride(); 00715 00716 if( v0_s == 1 && v1_s == 1 ) { 00717 for( Teuchos_Ordinal i = 0; i < subDim; ++i ) 00718 eleWiseReduction_( *v0_val++, *v1_val++, reduct); 00719 } 00720 else { 00721 for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s, v1_val += v1_s ) 00722 eleWiseReduction_( *v0_val, *v1_val, reduct); 00723 } 00724 00725 reduct_obj.set(reduct); 00726 00727 } 00728 00730 00731 private: 00732 00733 EleWiseReduction eleWiseReduction_; 00734 00735 }; 00736 00737 00741 #define RTOP_ROP_2_REDUCT_SCALAR( ROP_CLASS_NAME, REDUCT_SCALAR, \ 00742 BASIC_REDUCT_TYPE_ENUM \ 00743 ) \ 00744 \ 00745 template<class Scalar, class ReductScalar> \ 00746 class ROP_CLASS_NAME ## EleWiseReduction \ 00747 { \ 00748 public: \ 00749 inline void operator()(const Scalar &v0, \ 00750 const Scalar &v1, \ 00751 ReductScalar &reduct \ 00752 ) const; \ 00753 }; \ 00754 \ 00755 \ 00756 template<class Scalar> \ 00757 class ROP_CLASS_NAME \ 00758 : public RTOpPack::ROp_2_ScalarReduction< \ 00759 Scalar, \ 00760 REDUCT_SCALAR, \ 00761 ROP_CLASS_NAME ## EleWiseReduction<Scalar, REDUCT_SCALAR >, \ 00762 RTOpPack::BasicReductObjReductionOp<REDUCT_SCALAR, BASIC_REDUCT_TYPE_ENUM> > \ 00763 { \ 00764 public: \ 00765 ROP_CLASS_NAME() \ 00766 { \ 00767 this->setOpNameBase( #ROP_CLASS_NAME ); \ 00768 this->initReductObjValue(ScalarTraits<REDUCT_SCALAR >::zero()); \ 00769 } \ 00770 }; \ 00771 \ 00772 template<class Scalar, class ReductScalar> \ 00773 void ROP_CLASS_NAME ## EleWiseReduction<Scalar, ReductScalar>::operator()( \ 00774 const Scalar &v0, const Scalar &v1, ReductScalar &reduct) const 00775 00776 00777 // 00778 // TOp 0 to 1 vector transformation 00779 // 00780 00781 00783 template<class Scalar, class EleWiseTransformation> 00784 class TOp_0_1_Base : public RTOpT<Scalar> 00785 { 00786 public: 00787 00789 TOp_0_1_Base( 00790 EleWiseTransformation eleWiseTransformation = EleWiseTransformation() 00791 ) 00792 : eleWiseTransformation_(eleWiseTransformation) 00793 {} 00794 00797 00799 void apply_op_impl( 00800 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00801 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00802 const Ptr<ReductTarget> &reduct_obj_inout 00803 ) const 00804 { 00805 typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t; 00806 00807 #ifdef TEUCHOS_DEBUG 00808 validate_apply_op<Scalar>(*this, 0, 1, false, 00809 sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst()); 00810 #endif 00811 00812 const RTOpPack::index_type subDim = targ_sub_vecs[0].subDim(); 00813 00814 iter_t z0_val = targ_sub_vecs[0].values().begin(); 00815 const ptrdiff_t z0_s = targ_sub_vecs[0].stride(); 00816 00817 if ( z0_s == 1 ) { 00818 for( Teuchos_Ordinal i = 0; i < subDim; ++i ) 00819 eleWiseTransformation_( *z0_val++); 00820 } 00821 else { 00822 for( Teuchos_Ordinal i = 0; i < subDim; ++i, z0_val += z0_s ) 00823 eleWiseTransformation_( *z0_val); 00824 } 00825 00826 } 00827 00829 00830 private: 00831 00832 EleWiseTransformation eleWiseTransformation_; 00833 00834 }; 00835 00836 00839 template<class Scalar, class EleWiseTransformation> 00840 class TOp_0_1_CoordVariantBase : public RTOpT<Scalar> 00841 { 00842 public: 00843 00845 TOp_0_1_CoordVariantBase( 00846 EleWiseTransformation eleWiseTransformation = EleWiseTransformation() 00847 ) 00848 : eleWiseTransformation_(eleWiseTransformation) 00849 {} 00850 00852 void setEleWiseTransformation(EleWiseTransformation eleWiseTransformation) 00853 { 00854 eleWiseTransformation_ = eleWiseTransformation; 00855 } 00856 00858 const EleWiseTransformation& getEleWiseTransformation() const 00859 { 00860 return eleWiseTransformation_; 00861 } 00862 00865 00867 bool coord_invariant_impl() const { return false; } 00868 00870 void apply_op_impl( 00871 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00872 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00873 const Ptr<ReductTarget> &reduct_obj_inout 00874 ) const 00875 { 00876 typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t; 00877 00878 #ifdef TEUCHOS_DEBUG 00879 validate_apply_op<Scalar>(*this, 0, 1, false, 00880 sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst()); 00881 #endif 00882 00883 const RTOpPack::index_type subDim = targ_sub_vecs[0].subDim(); 00884 00885 iter_t z0_val = targ_sub_vecs[0].values().begin(); 00886 const ptrdiff_t z0_s = targ_sub_vecs[0].stride(); 00887 00888 RTOpPack::index_type global_i = targ_sub_vecs[0].globalOffset(); 00889 00890 if ( z0_s == 1 ) { 00891 for( Teuchos_Ordinal i = 0; i < subDim; ++i, ++global_i ) 00892 eleWiseTransformation_(global_i, *z0_val++); 00893 } 00894 else { 00895 for( Teuchos_Ordinal i = 0; i < subDim; ++i, z0_val += z0_s, ++global_i ) 00896 eleWiseTransformation_(global_i, *z0_val); 00897 } 00898 00899 } 00900 00902 00903 private: 00904 00905 EleWiseTransformation eleWiseTransformation_; 00906 00907 }; 00908 00909 00910 // 00911 // TOp 1 to 1 vector transformation 00912 // 00913 00914 00916 template<class Scalar, class EleWiseTransformation> 00917 class TOp_1_1_Base : public RTOpT<Scalar> 00918 { 00919 public: 00920 00922 TOp_1_1_Base( 00923 EleWiseTransformation eleWiseTransformation = EleWiseTransformation() 00924 ) 00925 : eleWiseTransformation_(eleWiseTransformation) 00926 {} 00927 00930 00932 void apply_op_impl( 00933 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00934 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00935 const Ptr<ReductTarget> &reduct_obj_inout 00936 ) const 00937 { 00938 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 00939 typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t; 00940 00941 #ifdef TEUCHOS_DEBUG 00942 validate_apply_op<Scalar>(*this, 1, 1, false, 00943 sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst()); 00944 #endif 00945 00946 const RTOpPack::index_type subDim = sub_vecs[0].subDim(); 00947 00948 const_iter_t v0_val = sub_vecs[0].values().begin(); 00949 const ptrdiff_t v0_s = sub_vecs[0].stride(); 00950 00951 iter_t z0_val = targ_sub_vecs[0].values().begin(); 00952 const ptrdiff_t z0_s = targ_sub_vecs[0].stride(); 00953 00954 if ( v0_s == 1 && z0_s == 1 ) { 00955 for( Teuchos_Ordinal i = 0; i < subDim; ++i ) 00956 eleWiseTransformation_( *v0_val++, *z0_val++); 00957 } 00958 else { 00959 for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s, z0_val += z0_s ) 00960 eleWiseTransformation_( *v0_val, *z0_val); 00961 } 00962 00963 } 00964 00966 00967 private: 00968 00969 EleWiseTransformation eleWiseTransformation_; 00970 00971 }; 00972 00973 00975 #define RTOP_TOP_1_1( TOP_CLASS_NAME ) \ 00976 \ 00977 template<class Scalar> \ 00978 class TOP_CLASS_NAME ## EleWiseTransformation \ 00979 { \ 00980 public: \ 00981 inline void operator()( const Scalar &v0, Scalar &z0 ) const; \ 00982 }; \ 00983 \ 00984 \ 00985 template<class Scalar> \ 00986 class TOP_CLASS_NAME \ 00987 : public RTOpPack::TOp_1_1_Base< Scalar, \ 00988 TOP_CLASS_NAME ## EleWiseTransformation<Scalar> > \ 00989 { \ 00990 public: \ 00991 TOP_CLASS_NAME() \ 00992 { \ 00993 this->setOpNameBase( #TOP_CLASS_NAME ); \ 00994 } \ 00995 }; \ 00996 \ 00997 \ 00998 template<class Scalar> \ 00999 void TOP_CLASS_NAME ## EleWiseTransformation<Scalar>::operator()( \ 01000 const Scalar &v0, Scalar &z0 \ 01001 ) const 01002 01003 01004 // 01005 // TOp 2 to 1 vector transformation 01006 // 01007 01008 01010 template<class Scalar, class EleWiseTransformation> 01011 class TOp_2_1_Base : public RTOpT<Scalar> 01012 { 01013 public: 01014 01016 TOp_2_1_Base( 01017 EleWiseTransformation eleWiseTransformation = EleWiseTransformation() 01018 ) 01019 : eleWiseTransformation_(eleWiseTransformation) 01020 {} 01021 01024 01026 void apply_op_impl( 01027 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 01028 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 01029 const Ptr<ReductTarget> &reduct_obj_inout 01030 ) const 01031 { 01032 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 01033 typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t; 01034 01035 #ifdef TEUCHOS_DEBUG 01036 validate_apply_op<Scalar>(*this, 2, 1, false, 01037 sub_vecs, targ_sub_vecs, reduct_obj_inout); 01038 #endif 01039 01040 const RTOpPack::index_type subDim = sub_vecs[0].subDim(); 01041 01042 const_iter_t v0_val = sub_vecs[0].values().begin(); 01043 const ptrdiff_t v0_s = sub_vecs[0].stride(); 01044 01045 const_iter_t v1_val = sub_vecs[1].values().begin(); 01046 const ptrdiff_t v1_s = sub_vecs[1].stride(); 01047 01048 iter_t z0_val = targ_sub_vecs[0].values().begin(); 01049 const ptrdiff_t z0_s = targ_sub_vecs[0].stride(); 01050 01051 if ( v0_s == 1 && v1_s == 1 && z0_s == 1 ) { 01052 for( Teuchos_Ordinal i = 0; i < subDim; ++i ) 01053 eleWiseTransformation_( *v0_val++, *v1_val++, *z0_val++ ); 01054 } 01055 else { 01056 for( 01057 Teuchos_Ordinal i = 0; 01058 i < subDim; 01059 ++i, v0_val += v0_s, v1_val += v1_s, z0_val += z0_s 01060 ) 01061 { 01062 eleWiseTransformation_( *v0_val, *v1_val, *z0_val ); 01063 } 01064 } 01065 01066 } 01067 01069 01070 private: 01071 01072 EleWiseTransformation eleWiseTransformation_; 01073 01074 }; 01075 01076 01077 } // namespace RTOpPack 01078 01079 01080 #endif // RTOPPACK_RTOP_T_HELPERS_DECL_HPP
1.7.6.1