RTOp Package Browser (Single Doxygen Collection) Version of the Day
RTOpPack_RTOpTHelpers_decl.hpp
Go to the documentation of this file.
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_Index i = 0; i < subDim; ++i )
00487           eleWiseReduction_( *v0_val++, reduct);
00488       }
00489       else {
00490         for( Teuchos_Index 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_Index i = 0; i < subDim; ++i, ++global_i )
00639           eleWiseReduction_( global_i, *v0_val++, reduct);
00640       }
00641       else {
00642         for( Teuchos_Index 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_Index i = 0; i < subDim; ++i )
00722           eleWiseReduction_( *v0_val++, *v1_val++, reduct);
00723       }
00724       else {
00725         for( Teuchos_Index 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_Index i = 0; i < subDim; ++i )
00824           eleWiseTransformation_( *z0_val++);
00825       }
00826       else {
00827         for( Teuchos_Index 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_Index i = 0; i < subDim; ++i, ++global_i )
00898           eleWiseTransformation_(global_i, *z0_val++);
00899       }
00900       else {
00901         for( Teuchos_Index 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_Index i = 0; i < subDim; ++i )
00962           eleWiseTransformation_( *v0_val++, *z0_val++);
00963       }
00964       else {
00965         for( Teuchos_Index 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_Index i = 0; i < subDim; ++i )
01059           eleWiseTransformation_( *v0_val++, *v1_val++, *z0_val++ );
01060       }
01061       else {
01062         for(
01063           Teuchos_Index 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines