|
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_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 ScalarTraits<Scalar> ST; 00410 typedef PrimitiveTypeTraits<Scalar, ConcreteReductObj> PTT; 00411 ConcreteReductObj concrete_reduct_obj; 00412 PTT::loadPrimitiveObjs( value_data, index_data, char_data, 00413 Teuchos::outArg(concrete_reduct_obj) ); 00414 this->setRawVal( concrete_reduct_obj, reduct_obj ); 00415 } 00416 00418 00419 protected: 00420 00422 STANDARD_MEMBER_COMPOSITION_MEMBERS( ConcreteReductObj, initReductObjValue ); 00423 00424 private: 00425 00426 ReductObjReduction reductObjReduction_; 00427 00428 }; 00429 00430 00431 // 00432 // ROp 1 vector scalar reduction 00433 // 00434 00435 00437 template<class Scalar, class ConcreteReductObj, class EleWiseReduction, 00438 class ReductObjReduction = SumScalarReductObjReduction<ConcreteReductObj> > 00439 class ROp_1_ScalarReduction 00440 : public ROpScalarReductionWithOpBase<Scalar, ConcreteReductObj, ReductObjReduction> 00441 { 00442 public: 00443 00445 typedef ROpScalarReductionWithOpBase<Scalar, ConcreteReductObj, ReductObjReduction> base_t; 00446 00448 ROp_1_ScalarReduction( 00449 const ConcreteReductObj &initReductObjValue_in = ConcreteReductObj(), 00450 EleWiseReduction eleWiseReduction_in = EleWiseReduction(), 00451 ReductObjReduction reductObjReduction_in = ReductObjReduction() 00452 ) 00453 : base_t(initReductObjValue_in, reductObjReduction_in), 00454 eleWiseReduction_(eleWiseReduction_in) 00455 {} 00456 00459 00461 void apply_op_impl( 00462 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00463 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00464 const Ptr<ReductTarget> &reduct_obj_inout 00465 ) const 00466 { 00467 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 00468 using Teuchos::dyn_cast; 00469 typedef ScalarTraits<Scalar> ST; 00470 00471 #ifdef TEUCHOS_DEBUG 00472 validate_apply_op<Scalar>(*this, 1, 0, true, 00473 sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst()); 00474 #endif 00475 00476 DefaultReductTarget<ConcreteReductObj> &reduct_obj = 00477 dyn_cast<DefaultReductTarget<ConcreteReductObj> >(*reduct_obj_inout); 00478 ConcreteReductObj reduct = reduct_obj.get(); 00479 00480 const RTOpPack::index_type subDim = sub_vecs[0].subDim(); 00481 00482 const_iter_t v0_val = sub_vecs[0].values().begin(); 00483 const ptrdiff_t v0_s = sub_vecs[0].stride(); 00484 00485 if ( v0_s == 1 ) { 00486 for( Teuchos_Ordinal i = 0; i < subDim; ++i ) 00487 eleWiseReduction_( *v0_val++, reduct); 00488 } 00489 else { 00490 for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s ) 00491 eleWiseReduction_( *v0_val, reduct); 00492 } 00493 00494 reduct_obj.set(reduct); 00495 00496 } 00497 00499 00500 private: 00501 00502 EleWiseReduction eleWiseReduction_; 00503 00504 }; 00505 00506 00508 #define RTOP_ROP_1_REDUCT_SCALAR_CUSTOM_DEFAULT( ROP_CLASS_NAME, REDUCT_SCALAR, \ 00509 BASIC_REDUCT_TYPE_ENUM, CUSTOM_DEFAULT \ 00510 ) \ 00511 \ 00512 template<class Scalar, class ReductScalar> \ 00513 class ROP_CLASS_NAME ## EleWiseReduction \ 00514 { \ 00515 public: \ 00516 inline void operator()( \ 00517 const Scalar &v0, \ 00518 ReductScalar &reduct \ 00519 ) const; \ 00520 }; \ 00521 \ 00522 \ 00523 template<class Scalar> \ 00524 class ROP_CLASS_NAME \ 00525 : public RTOpPack::ROp_1_ScalarReduction< \ 00526 Scalar, \ 00527 REDUCT_SCALAR, \ 00528 ROP_CLASS_NAME ## EleWiseReduction<Scalar, REDUCT_SCALAR >, \ 00529 RTOpPack::BasicReductObjReductionOp<REDUCT_SCALAR, BASIC_REDUCT_TYPE_ENUM> > \ 00530 { \ 00531 typedef RTOpPack::ROp_1_ScalarReduction< \ 00532 Scalar, \ 00533 REDUCT_SCALAR, \ 00534 ROP_CLASS_NAME ## EleWiseReduction<Scalar, REDUCT_SCALAR >, \ 00535 RTOpPack::BasicReductObjReductionOp<REDUCT_SCALAR, BASIC_REDUCT_TYPE_ENUM> > \ 00536 base_t; \ 00537 public: \ 00538 ROP_CLASS_NAME() \ 00539 : base_t(CUSTOM_DEFAULT) \ 00540 { \ 00541 this->setOpNameBase( #ROP_CLASS_NAME ); \ 00542 } \ 00543 }; \ 00544 \ 00545 \ 00546 template<class Scalar, class ReductScalar> \ 00547 void ROP_CLASS_NAME ## EleWiseReduction<Scalar, ReductScalar>::operator()( \ 00548 const Scalar &v0, ReductScalar &reduct \ 00549 ) const 00550 00551 00553 #define RTOP_ROP_1_REDUCT_SCALAR( ROP_CLASS_NAME, REDUCT_SCALAR, \ 00554 BASIC_REDUCT_TYPE_ENUM \ 00555 ) \ 00556 RTOP_ROP_1_REDUCT_SCALAR_CUSTOM_DEFAULT(ROP_CLASS_NAME, REDUCT_SCALAR, \ 00557 BASIC_REDUCT_TYPE_ENUM, Teuchos::ScalarTraits<REDUCT_SCALAR >::zero() ) 00558 00559 00560 // 00561 // ROp 1 coordinate-variant vector scalar reduction 00562 // 00563 00564 00567 template< 00568 class Scalar, 00569 class ReductScalar, 00570 class EleWiseReduction, 00571 class ReductObjReduction = SumScalarReductObjReduction<ReductScalar> 00572 > 00573 class ROp_1_CoordVariantScalarReduction 00574 : public ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction> 00575 { 00576 public: 00577 00580 00582 typedef ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction> base_t; 00583 00585 ROp_1_CoordVariantScalarReduction( 00586 const ReductScalar &initReductObjValue_in = ReductScalar(), 00587 EleWiseReduction eleWiseReduction_in = EleWiseReduction(), 00588 ReductObjReduction reductObjReduction_in = ReductObjReduction() 00589 ) 00590 : base_t(initReductObjValue_in, reductObjReduction_in), 00591 eleWiseReduction_(eleWiseReduction_in) 00592 {} 00593 00595 void setEleWiseReduction(EleWiseReduction eleWiseReduction_in) 00596 { eleWiseReduction_ = eleWiseReduction_in; } 00597 00599 const EleWiseReduction& getEleWiseReduction() const 00600 { return eleWiseReduction_; } 00601 00603 00606 00608 bool coord_invariant_impl() const { return false; } 00609 00611 void apply_op_impl( 00612 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00613 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00614 const Ptr<ReductTarget> &reduct_obj_inout 00615 ) const 00616 { 00617 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 00618 using Teuchos::dyn_cast; 00619 typedef ScalarTraits<Scalar> ST; 00620 00621 #ifdef TEUCHOS_DEBUG 00622 validate_apply_op<Scalar>(*this, 1, 0, true, 00623 sub_vecs, targ_sub_vecs, reduct_obj_inout); 00624 #endif 00625 00626 DefaultReductTarget<ReductScalar> &reduct_obj = 00627 dyn_cast<DefaultReductTarget<ReductScalar> >(*reduct_obj_inout); 00628 ReductScalar reduct = reduct_obj.get(); 00629 00630 const RTOpPack::index_type subDim = sub_vecs[0].subDim(); 00631 00632 const_iter_t v0_val = sub_vecs[0].values().begin(); 00633 const ptrdiff_t v0_s = sub_vecs[0].stride(); 00634 00635 RTOpPack::index_type global_i = sub_vecs[0].globalOffset(); 00636 00637 if ( v0_s == 1 ) { 00638 for( Teuchos_Ordinal i = 0; i < subDim; ++i, ++global_i ) 00639 eleWiseReduction_( global_i, *v0_val++, reduct); 00640 } 00641 else { 00642 for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s, ++global_i ) 00643 eleWiseReduction_( global_i, *v0_val, reduct); 00644 } 00645 00646 reduct_obj.set(reduct); 00647 00648 } 00649 00651 00652 private: 00653 00654 EleWiseReduction eleWiseReduction_; 00655 00656 }; 00657 00658 00659 // 00660 // ROp 2 vector scalar reduction 00661 // 00662 00663 00665 template< 00666 class Scalar, 00667 class ReductScalar, 00668 class EleWiseReduction, 00669 class ReductObjReduction = SumScalarReductObjReduction<ReductScalar> 00670 > 00671 class ROp_2_ScalarReduction 00672 : public ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction> 00673 { 00674 public: 00675 00677 typedef ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction> 00678 base_t; 00679 00681 ROp_2_ScalarReduction( 00682 const ReductScalar &initReductObjValue_in = ReductScalar(), 00683 EleWiseReduction eleWiseReduction_in = EleWiseReduction(), 00684 ReductObjReduction reductObjReduction_in = ReductObjReduction() 00685 ) 00686 : base_t(initReductObjValue_in, reductObjReduction_in), 00687 eleWiseReduction_(eleWiseReduction_in) 00688 {} 00689 00692 00694 void apply_op_impl( 00695 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00696 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00697 const Ptr<ReductTarget> &reduct_obj_inout 00698 ) const 00699 { 00700 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 00701 using Teuchos::dyn_cast; 00702 typedef ScalarTraits<Scalar> ST; 00703 00704 #ifdef TEUCHOS_DEBUG 00705 validate_apply_op<Scalar>(*this, 2, 0, true, 00706 sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst()); 00707 #endif 00708 00709 DefaultReductTarget<Scalar> &reduct_obj = 00710 dyn_cast<DefaultReductTarget<Scalar> >(*reduct_obj_inout); 00711 Scalar reduct = reduct_obj.get(); 00712 00713 const RTOpPack::index_type subDim = sub_vecs[0].subDim(); 00714 00715 const_iter_t v0_val = sub_vecs[0].values().begin(); 00716 const ptrdiff_t v0_s = sub_vecs[0].stride(); 00717 const_iter_t v1_val = sub_vecs[1].values().begin(); 00718 const ptrdiff_t v1_s = sub_vecs[1].stride(); 00719 00720 if( v0_s == 1 && v1_s == 1 ) { 00721 for( Teuchos_Ordinal i = 0; i < subDim; ++i ) 00722 eleWiseReduction_( *v0_val++, *v1_val++, reduct); 00723 } 00724 else { 00725 for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s, v1_val += v1_s ) 00726 eleWiseReduction_( *v0_val, *v1_val, reduct); 00727 } 00728 00729 reduct_obj.set(reduct); 00730 00731 } 00732 00734 00735 private: 00736 00737 EleWiseReduction eleWiseReduction_; 00738 00739 }; 00740 00741 00745 #define RTOP_ROP_2_REDUCT_SCALAR( ROP_CLASS_NAME, REDUCT_SCALAR, \ 00746 BASIC_REDUCT_TYPE_ENUM \ 00747 ) \ 00748 \ 00749 template<class Scalar, class ReductScalar> \ 00750 class ROP_CLASS_NAME ## EleWiseReduction \ 00751 { \ 00752 public: \ 00753 inline void operator()(const Scalar &v0, \ 00754 const Scalar &v1, \ 00755 ReductScalar &reduct \ 00756 ) const; \ 00757 }; \ 00758 \ 00759 \ 00760 template<class Scalar> \ 00761 class ROP_CLASS_NAME \ 00762 : public RTOpPack::ROp_2_ScalarReduction< \ 00763 Scalar, \ 00764 REDUCT_SCALAR, \ 00765 ROP_CLASS_NAME ## EleWiseReduction<Scalar, REDUCT_SCALAR >, \ 00766 RTOpPack::BasicReductObjReductionOp<REDUCT_SCALAR, BASIC_REDUCT_TYPE_ENUM> > \ 00767 { \ 00768 public: \ 00769 ROP_CLASS_NAME() \ 00770 { \ 00771 this->setOpNameBase( #ROP_CLASS_NAME ); \ 00772 this->initReductObjValue(ScalarTraits<REDUCT_SCALAR >::zero()); \ 00773 } \ 00774 }; \ 00775 \ 00776 template<class Scalar, class ReductScalar> \ 00777 void ROP_CLASS_NAME ## EleWiseReduction<Scalar, ReductScalar>::operator()( \ 00778 const Scalar &v0, const Scalar &v1, ReductScalar &reduct) const 00779 00780 00781 // 00782 // TOp 0 to 1 vector transformation 00783 // 00784 00785 00787 template<class Scalar, class EleWiseTransformation> 00788 class TOp_0_1_Base : public RTOpT<Scalar> 00789 { 00790 public: 00791 00793 TOp_0_1_Base( 00794 EleWiseTransformation eleWiseTransformation = EleWiseTransformation() 00795 ) 00796 : eleWiseTransformation_(eleWiseTransformation) 00797 {} 00798 00801 00803 void apply_op_impl( 00804 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00805 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00806 const Ptr<ReductTarget> &reduct_obj_inout 00807 ) const 00808 { 00809 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 00810 typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t; 00811 00812 #ifdef TEUCHOS_DEBUG 00813 validate_apply_op<Scalar>(*this, 0, 1, false, 00814 sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst()); 00815 #endif 00816 00817 const RTOpPack::index_type subDim = targ_sub_vecs[0].subDim(); 00818 00819 iter_t z0_val = targ_sub_vecs[0].values().begin(); 00820 const ptrdiff_t z0_s = targ_sub_vecs[0].stride(); 00821 00822 if ( z0_s == 1 ) { 00823 for( Teuchos_Ordinal i = 0; i < subDim; ++i ) 00824 eleWiseTransformation_( *z0_val++); 00825 } 00826 else { 00827 for( Teuchos_Ordinal i = 0; i < subDim; ++i, z0_val += z0_s ) 00828 eleWiseTransformation_( *z0_val); 00829 } 00830 00831 } 00832 00834 00835 private: 00836 00837 EleWiseTransformation eleWiseTransformation_; 00838 00839 }; 00840 00841 00844 template<class Scalar, class EleWiseTransformation> 00845 class TOp_0_1_CoordVariantBase : public RTOpT<Scalar> 00846 { 00847 public: 00848 00850 TOp_0_1_CoordVariantBase( 00851 EleWiseTransformation eleWiseTransformation = EleWiseTransformation() 00852 ) 00853 : eleWiseTransformation_(eleWiseTransformation) 00854 {} 00855 00857 void setEleWiseTransformation(EleWiseTransformation eleWiseTransformation) 00858 { 00859 eleWiseTransformation_ = eleWiseTransformation; 00860 } 00861 00863 const EleWiseTransformation& getEleWiseTransformation() const 00864 { 00865 return eleWiseTransformation_; 00866 } 00867 00870 00872 bool coord_invariant_impl() const { return false; } 00873 00875 void apply_op_impl( 00876 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00877 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00878 const Ptr<ReductTarget> &reduct_obj_inout 00879 ) const 00880 { 00881 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 00882 typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t; 00883 00884 #ifdef TEUCHOS_DEBUG 00885 validate_apply_op<Scalar>(*this, 0, 1, false, 00886 sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst()); 00887 #endif 00888 00889 const RTOpPack::index_type subDim = targ_sub_vecs[0].subDim(); 00890 00891 iter_t z0_val = targ_sub_vecs[0].values().begin(); 00892 const ptrdiff_t z0_s = targ_sub_vecs[0].stride(); 00893 00894 RTOpPack::index_type global_i = targ_sub_vecs[0].globalOffset(); 00895 00896 if ( z0_s == 1 ) { 00897 for( Teuchos_Ordinal i = 0; i < subDim; ++i, ++global_i ) 00898 eleWiseTransformation_(global_i, *z0_val++); 00899 } 00900 else { 00901 for( Teuchos_Ordinal i = 0; i < subDim; ++i, z0_val += z0_s, ++global_i ) 00902 eleWiseTransformation_(global_i, *z0_val); 00903 } 00904 00905 } 00906 00908 00909 private: 00910 00911 EleWiseTransformation eleWiseTransformation_; 00912 00913 }; 00914 00915 00916 // 00917 // TOp 1 to 1 vector transformation 00918 // 00919 00920 00922 template<class Scalar, class EleWiseTransformation> 00923 class TOp_1_1_Base : public RTOpT<Scalar> 00924 { 00925 public: 00926 00928 TOp_1_1_Base( 00929 EleWiseTransformation eleWiseTransformation = EleWiseTransformation() 00930 ) 00931 : eleWiseTransformation_(eleWiseTransformation) 00932 {} 00933 00936 00938 void apply_op_impl( 00939 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 00940 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 00941 const Ptr<ReductTarget> &reduct_obj_inout 00942 ) const 00943 { 00944 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 00945 typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t; 00946 00947 #ifdef TEUCHOS_DEBUG 00948 validate_apply_op<Scalar>(*this, 1, 1, false, 00949 sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst()); 00950 #endif 00951 00952 const RTOpPack::index_type subDim = sub_vecs[0].subDim(); 00953 00954 const_iter_t v0_val = sub_vecs[0].values().begin(); 00955 const ptrdiff_t v0_s = sub_vecs[0].stride(); 00956 00957 iter_t z0_val = targ_sub_vecs[0].values().begin(); 00958 const ptrdiff_t z0_s = targ_sub_vecs[0].stride(); 00959 00960 if ( v0_s == 1 && z0_s == 1 ) { 00961 for( Teuchos_Ordinal i = 0; i < subDim; ++i ) 00962 eleWiseTransformation_( *v0_val++, *z0_val++); 00963 } 00964 else { 00965 for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s, z0_val += z0_s ) 00966 eleWiseTransformation_( *v0_val, *z0_val); 00967 } 00968 00969 } 00970 00972 00973 private: 00974 00975 EleWiseTransformation eleWiseTransformation_; 00976 00977 }; 00978 00979 00981 #define RTOP_TOP_1_1( TOP_CLASS_NAME ) \ 00982 \ 00983 template<class Scalar> \ 00984 class TOP_CLASS_NAME ## EleWiseTransformation \ 00985 { \ 00986 public: \ 00987 inline void operator()( const Scalar &v0, Scalar &z0 ) const; \ 00988 }; \ 00989 \ 00990 \ 00991 template<class Scalar> \ 00992 class TOP_CLASS_NAME \ 00993 : public RTOpPack::TOp_1_1_Base< Scalar, \ 00994 TOP_CLASS_NAME ## EleWiseTransformation<Scalar> > \ 00995 { \ 00996 public: \ 00997 TOP_CLASS_NAME() \ 00998 { \ 00999 this->setOpNameBase( #TOP_CLASS_NAME ); \ 01000 } \ 01001 }; \ 01002 \ 01003 \ 01004 template<class Scalar> \ 01005 void TOP_CLASS_NAME ## EleWiseTransformation<Scalar>::operator()( \ 01006 const Scalar &v0, Scalar &z0 \ 01007 ) const 01008 01009 01010 // 01011 // TOp 2 to 1 vector transformation 01012 // 01013 01014 01016 template<class Scalar, class EleWiseTransformation> 01017 class TOp_2_1_Base : public RTOpT<Scalar> 01018 { 01019 public: 01020 01022 TOp_2_1_Base( 01023 EleWiseTransformation eleWiseTransformation = EleWiseTransformation() 01024 ) 01025 : eleWiseTransformation_(eleWiseTransformation) 01026 {} 01027 01030 01032 void apply_op_impl( 01033 const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs, 01034 const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs, 01035 const Ptr<ReductTarget> &reduct_obj_inout 01036 ) const 01037 { 01038 typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t; 01039 typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t; 01040 01041 #ifdef TEUCHOS_DEBUG 01042 validate_apply_op<Scalar>(*this, 2, 1, false, 01043 sub_vecs, targ_sub_vecs, reduct_obj_inout); 01044 #endif 01045 01046 const RTOpPack::index_type subDim = sub_vecs[0].subDim(); 01047 01048 const_iter_t v0_val = sub_vecs[0].values().begin(); 01049 const ptrdiff_t v0_s = sub_vecs[0].stride(); 01050 01051 const_iter_t v1_val = sub_vecs[1].values().begin(); 01052 const ptrdiff_t v1_s = sub_vecs[1].stride(); 01053 01054 iter_t z0_val = targ_sub_vecs[0].values().begin(); 01055 const ptrdiff_t z0_s = targ_sub_vecs[0].stride(); 01056 01057 if ( v0_s == 1 && v1_s == 1 && z0_s == 1 ) { 01058 for( Teuchos_Ordinal i = 0; i < subDim; ++i ) 01059 eleWiseTransformation_( *v0_val++, *v1_val++, *z0_val++ ); 01060 } 01061 else { 01062 for( 01063 Teuchos_Ordinal i = 0; 01064 i < subDim; 01065 ++i, v0_val += v0_s, v1_val += v1_s, z0_val += z0_s 01066 ) 01067 { 01068 eleWiseTransformation_( *v0_val, *v1_val, *z0_val ); 01069 } 01070 } 01071 01072 } 01073 01075 01076 private: 01077 01078 EleWiseTransformation eleWiseTransformation_; 01079 01080 }; 01081 01082 01083 } // namespace RTOpPack 01084 01085 01086 #endif // RTOPPACK_RTOP_T_HELPERS_DECL_HPP
1.7.6.1