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