RTOpPack_ROpGetSubVector.hpp

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_ROP_GET_SUB_VECTOR_HPP
00031 #define RTOPPACK_ROP_GET_SUB_VECTOR_HPP
00032 
00033 #include "RTOpPack_RTOpTHelpers.hpp"
00034 
00035 namespace RTOpPack {
00036 
00038 template<class Scalar> class ReductTargetSubVectorT;
00039 
00045 template<class Scalar>
00046 class ROpGetSubVector : public RTOpT<Scalar> {
00047 public:
00048 
00050   typedef typename RTOpT<Scalar>::primitive_value_type primitive_value_type;
00051 
00053   ROpGetSubVector( const index_type l = 0, const index_type u = 0 );
00054 
00056   void set_range( const index_type l, const index_type u );
00057 
00059   ReductTargetSubVectorT<Scalar>& operator()( ReductTarget& reduct_obj ) const;
00060 
00062   const ReductTargetSubVectorT<Scalar>& operator()( const ReductTarget& reduct_obj ) const;
00063 
00066 
00068   void get_reduct_type_num_entries(
00069     int*   num_values
00070     ,int*  num_indexes
00071     ,int*  num_chars
00072     ) const;
00074   Teuchos::RefCountPtr<ReductTarget> reduct_obj_create() const;
00076   void reduce_reduct_objs(
00077     const ReductTarget& _in_reduct_obj, ReductTarget* _inout_reduct_obj
00078     ) const;
00080   void reduct_obj_reinit( ReductTarget* reduct_obj ) const;
00082   void extract_reduct_obj_state(
00083     const ReductTarget        &reduct_obj
00084     ,int                      num_values
00085     ,primitive_value_type     value_data[]
00086     ,int                      num_indexes
00087     ,Teuchos_Index            index_data[]
00088     ,int                      num_chars
00089     ,::RTOpPack::char_type           char_data[]
00090     ) const;
00092   void load_reduct_obj_state(
00093     int                            num_values
00094     ,const primitive_value_type    value_data[]
00095     ,int                           num_indexes
00096     ,const Teuchos_Index           index_data[]
00097     ,int                           num_chars
00098     ,const ::RTOpPack::char_type          char_data[]
00099     ,ReductTarget                  *reduct_obj
00100     ) const;
00102   void get_op_type_num_entries(
00103     int*  num_values
00104     ,int* num_indexes
00105     ,int* num_chars
00106     ) const;
00108   void extract_op_state(
00109     int                             num_values
00110     ,primitive_value_type           value_data[]
00111     ,int                            num_indexes
00112     ,Teuchos_Index                  index_data[]
00113     ,int                            num_chars
00114     ,::RTOpPack::char_type                 char_data[]
00115     ) const;
00117   void load_op_state(
00118     int                           num_values
00119     ,const primitive_value_type   value_data[]
00120     ,int                          num_indexes
00121     ,const Teuchos_Index          index_data[]
00122     ,int                          num_chars
00123     ,const ::RTOpPack::char_type         char_data[]
00124     );
00126   bool coord_invariant() const;
00128   void apply_op(
00129     const int   num_vecs,       const ConstSubVectorView<Scalar>         sub_vecs[]
00130     ,const int  num_targ_vecs,  const SubVectorView<Scalar>  targ_sub_vecs[]
00131     ,ReductTarget *reduct_obj
00132     ) const;
00133 
00135 
00136 private:
00137 
00138   index_type  l_;
00139   index_type  u_;
00140 
00141 }; // class ROpGetSubVector
00142 
00144 template<class Scalar>
00145 class ReductTargetSubVectorT : public ReductTarget {
00146 public:
00148   ReductTargetSubVectorT( const index_type l, const index_type u)
00149     {
00150       Scalar *values = NULL;
00151       try {
00152         const int subDim = u-l+1;
00153         sub_vec.initialize(
00154           l                    // global_offset
00155           ,subDim              // subDim
00156           ,new Scalar[subDim]  // values
00157           ,1                   // stride
00158           );
00159         reinit();
00160       }
00161       catch(...) {
00162         delete [] values;
00163       }
00164     }
00166   ~ReductTargetSubVectorT()
00167     {
00168       free(&sub_vec);
00169     }
00171   void reinit()
00172     {
00173       std::fill_n( const_cast<Scalar*>(sub_vec.values()), sub_vec.subDim(), Teuchos::ScalarTraits<Scalar>::zero() );
00174     }
00176   void transfer( ConstSubVectorView<Scalar> *sub_vec_out )
00177     {
00178       sub_vec_out->initialize(sub_vec.globalOffset(),sub_vec.subDim(),sub_vec.values(),sub_vec.stride());
00179       sub_vec.set_uninitialized();
00180     }
00182   static void free( ConstSubVectorView<Scalar> *sub_vec )
00183     {
00184       if(sub_vec->values())
00185         delete [] const_cast<Scalar*>(sub_vec->values());
00186       sub_vec->set_uninitialized();
00187     }
00189   ConstSubVectorView<Scalar>  sub_vec;
00190 private:
00191   // Not defined and not to be called!
00192   ReductTargetSubVectorT();
00193   ReductTargetSubVectorT(const ReductTargetSubVectorT&);
00194   ReductTargetSubVectorT<Scalar>& operator=(const ReductTargetSubVectorT&);
00195 };
00196 
00197 // ////////////////////////////////
00198 // Template definitions
00199 
00200 template<class Scalar>
00201 ROpGetSubVector<Scalar>::ROpGetSubVector( const index_type l, const index_type u )
00202   :RTOpT<Scalar>("ROpGetSubVector"), l_(l), u_(u)
00203 {}
00204 
00205 template<class Scalar>
00206 void ROpGetSubVector<Scalar>::set_range( const index_type l, const index_type u )
00207 {
00208   l_ = l;
00209   u_ = u;
00210 }
00211 
00212 template<class Scalar>
00213 ReductTargetSubVectorT<Scalar>&
00214 ROpGetSubVector<Scalar>::operator()(ReductTarget& reduct_obj ) const
00215 {
00216   using Teuchos::dyn_cast;
00217   return dyn_cast<ReductTargetSubVectorT<Scalar> >(reduct_obj);
00218 }
00219 
00220 template<class Scalar>
00221 const ReductTargetSubVectorT<Scalar>&
00222 ROpGetSubVector<Scalar>::operator()( const ReductTarget& reduct_obj ) const
00223 {
00224   using Teuchos::dyn_cast;
00225   return dyn_cast<const ReductTargetSubVectorT<Scalar> >(reduct_obj);
00226 }
00227 
00228 // Overridden from RTOpT
00229 
00230 template<class Scalar>
00231 void ROpGetSubVector<Scalar>::get_reduct_type_num_entries(
00232   int*   num_values
00233   ,int*  num_indexes
00234   ,int*  num_chars
00235   ) const
00236 {
00237   const int num_prim_objs_per_scalar = Teuchos::PrimitiveTypeTraits<Scalar>::numPrimitiveObjs();
00238   *num_values  = (u_-l_+1)*num_prim_objs_per_scalar;
00239   *num_indexes = 0;
00240   *num_chars   = 0;
00241 }
00242 
00243 template<class Scalar>
00244 Teuchos::RefCountPtr<ReductTarget>
00245 ROpGetSubVector<Scalar>::reduct_obj_create() const
00246 {
00247   return Teuchos::rcp(new ReductTargetSubVectorT<Scalar>(l_,u_));
00248 }
00249 
00250 template<class Scalar>
00251 void ROpGetSubVector<Scalar>::reduce_reduct_objs(
00252   const ReductTarget& in_reduct_obj, ReductTarget* inout_reduct_obj
00253   ) const
00254 {
00255   using Teuchos::dyn_cast;
00256   const ConstSubVectorView<Scalar> &sub_vec_in = dyn_cast<const ReductTargetSubVectorT<Scalar> >(in_reduct_obj).sub_vec;
00257   ConstSubVectorView<Scalar> &sub_vec_inout = dyn_cast<ReductTargetSubVectorT<Scalar> >(*inout_reduct_obj).sub_vec;
00258   TEST_FOR_EXCEPT(
00259     sub_vec_in.subDim()!=sub_vec_inout.subDim()||sub_vec_in.globalOffset()!=sub_vec_inout.globalOffset()
00260     ||!sub_vec_in.values()||!sub_vec_inout.values()
00261     );
00262   Scalar *svio_values = const_cast<Scalar*>(sub_vec_inout.values());
00263   for( int k = 0; k < sub_vec_in.subDim(); ++k ) {
00264     svio_values[k] += sub_vec_in[k];
00265   }
00266 }
00267 
00268 template<class Scalar>
00269 void ROpGetSubVector<Scalar>::reduct_obj_reinit( ReductTarget* reduct_obj ) const
00270 {
00271   using Teuchos::dyn_cast;
00272   dyn_cast<ReductTargetSubVectorT<Scalar> >(*reduct_obj).reinit();
00273 }
00274 
00275 template<class Scalar>
00276 void ROpGetSubVector<Scalar>::extract_reduct_obj_state(
00277   const ReductTarget        &reduct_obj
00278   ,int                      num_values
00279   ,primitive_value_type     value_data[]
00280   ,int                      num_indexes
00281   ,Teuchos_Index          index_data[]
00282   ,int                      num_chars
00283   ,::RTOpPack::char_type           char_data[]
00284   ) const
00285 {
00286   using Teuchos::dyn_cast;
00287   typedef Teuchos::PrimitiveTypeTraits<Scalar> PTT;
00288   const int num_prim_objs_per_scalar = PTT::numPrimitiveObjs();
00289   const ConstSubVectorView<Scalar> &sub_vec = dyn_cast<const ReductTargetSubVectorT<Scalar> >(reduct_obj).sub_vec;
00290   int value_data_off = 0;
00291   for( int k = 0; k < sub_vec.subDim(); ++k, value_data_off += num_prim_objs_per_scalar )
00292     PTT::extractPrimitiveObjs( sub_vec[k], num_prim_objs_per_scalar, value_data+value_data_off );
00293 }
00294 
00295 template<class Scalar>
00296 void ROpGetSubVector<Scalar>::load_reduct_obj_state(
00297   int                            num_values
00298   ,const primitive_value_type    value_data[]
00299   ,int                           num_indexes
00300   ,const Teuchos_Index         index_data[]
00301   ,int                           num_chars
00302   ,const ::RTOpPack::char_type          char_data[]
00303   ,ReductTarget                  *reduct_obj
00304   ) const
00305 {
00306   using Teuchos::dyn_cast;
00307   typedef Teuchos::PrimitiveTypeTraits<Scalar> PTT;
00308   const int num_prim_objs_per_scalar = PTT::numPrimitiveObjs();
00309   ConstSubVectorView<Scalar> &sub_vec = dyn_cast<ReductTargetSubVectorT<Scalar> >(*reduct_obj).sub_vec;
00310   Scalar *sv_values = const_cast<Scalar*>(sub_vec.values()); 
00311   int value_data_off = 0;
00312   for( int k = 0; k < sub_vec.subDim(); ++k, value_data_off += num_prim_objs_per_scalar )
00313     PTT::loadPrimitiveObjs( num_prim_objs_per_scalar, value_data+value_data_off, &sv_values[k] );
00314 }
00315 
00316 template<class Scalar>
00317 void ROpGetSubVector<Scalar>::get_op_type_num_entries(
00318   int*  num_values
00319   ,int* num_indexes
00320   ,int* num_chars
00321   ) const
00322 {
00323   TEST_FOR_EXCEPT( !num_values || !num_indexes || !num_chars ); 
00324   *num_values  = 0;
00325   *num_indexes = 2; // l, u
00326   *num_chars   = 0;
00327 }
00328 
00329 template<class Scalar>
00330 void ROpGetSubVector<Scalar>::extract_op_state(
00331   int                             num_values
00332   ,primitive_value_type           value_data[]
00333   ,int                            num_indexes
00334   ,Teuchos_Index                index_data[]
00335   ,int                            num_chars
00336   ,::RTOpPack::char_type                 char_data[]
00337   ) const
00338 {
00339   TEST_FOR_EXCEPT( num_values!=0 || num_indexes!=2 || num_chars!=0 ); 
00340   TEST_FOR_EXCEPT( !index_data ); 
00341   index_data[0] = l_;
00342   index_data[1] = u_;
00343 }
00344 
00345 template<class Scalar>
00346 void ROpGetSubVector<Scalar>::load_op_state(
00347   int                           num_values
00348   ,const primitive_value_type   value_data[]
00349   ,int                          num_indexes
00350   ,const Teuchos_Index        index_data[]
00351   ,int                          num_chars
00352   ,const ::RTOpPack::char_type         char_data[]
00353   )
00354 {
00355   TEST_FOR_EXCEPT( num_values!=0 || num_indexes!=2 || num_chars!=0 ); 
00356   TEST_FOR_EXCEPT( !index_data ); 
00357   l_ = index_data[0];
00358   u_ = index_data[1];
00359 }
00360 
00361 template<class Scalar>
00362 bool ROpGetSubVector<Scalar>::coord_invariant() const
00363 {
00364   return false;
00365 }
00366 
00367 template<class Scalar>
00368 void ROpGetSubVector<Scalar>::apply_op(
00369   const int   num_vecs,       const ConstSubVectorView<Scalar>         sub_vecs[]
00370   ,const int  num_targ_vecs,  const SubVectorView<Scalar>  targ_sub_vecs[]
00371   ,ReductTarget *reduct_obj
00372   ) const
00373 {
00374   using Teuchos::dyn_cast;
00375 
00376   RTOP_APPLY_OP_1_0(num_vecs,sub_vecs,num_targ_vecs,targ_sub_vecs);
00377 
00378   if( u_ < globalOffset || globalOffset + subDim - 1 < l_ )
00379     return; // None of the sub-vector elements that we are looking for is in this vector chunk!
00380   
00381   index_type
00382     i_l = ( l_ <= globalOffset           ? 0          : l_ - globalOffset  ),
00383     i_u = ( u_ >= globalOffset+subDim-1  ? subDim-1   : u_ - globalOffset  );
00384 
00385   ConstSubVectorView<Scalar> &sub_vec_targ = dyn_cast<ReductTargetSubVectorT<Scalar> >(*reduct_obj).sub_vec;
00386   Scalar *svt_values = const_cast<Scalar*>(sub_vec_targ.values());
00387 
00388   for( index_type i = i_l; i <= i_u; ++i )
00389     svt_values[i+(globalOffset-l_)] = v0_val[i*v0_s];
00390 
00391 }
00392 
00393 } // namespace RTOpPack
00394 
00395 #endif // RTOPPACK_ROP_GET_SUB_VECTOR_HPP

Generated on Thu Sep 18 12:30:40 2008 for Collection of Concrete Vector Reduction/Transformation Operator Implementations by doxygen 1.3.9.1