SIMDExpression.h

00001 /*
00002  * Expression Template Matrix Library
00003  *
00004  * Copyright (C) 2004 - 2006 Ricky Lung <mtlung@users.sourceforge.net>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 
00023 #ifdef _MSC_VER
00024 #   pragma once
00025 #   pragma warning( push )
00026 #   pragma warning( disable : 4324 4702 4714 )
00027 #endif  // _MSC_VER
00028 
00029 namespace exmat {
00030 
00031 
00032 #if (HAVE_TT_PARAMETER)
00033 template<class Exp, class newL, class newR> struct RefillBinExp;
00034 template<template<class,class,class> class Exp, class L, class R, class SpecTag, class newL, class newR>
00035 struct RefillBinExp< exmat::SIMD::SSCon<Exp<L,R,SpecTag> >, newL, newR> {
00036     typedef Exp<newL, newR, SpecTag> RET;
00037 };
00038 #endif  // HAVE_TT_PARAMETER
00039 
00040 
00041 #if HAVE_PARTIAL_SPECIALIZATION && EXMAT_ENABLE_SIMD
00042 using namespace exmat::SIMD;
00043 
00045 
00046 template<typename T, int ROWS, int COLS, class Left, class Right>
00047 struct GetBinExpTmpType<T,ROWS,COLS,SSCon<Left>,SSCon<Right> > {
00048     typedef Mat<SSCon<SCon<ROWS,COLS,T> >, EmptyErrorChecker> RET;
00049 };
00050 template<typename T, int ROWS, int COLS, class Left, class Right>
00051 struct GetBinExpTmpType<T,ROWS,COLS,SSCon<Left>,ScalarCon<Right> > {
00052     typedef Mat<SSCon<SCon<ROWS,COLS,T> >, EmptyErrorChecker> RET;
00053 };
00054 template<typename T, int ROWS, int COLS, class Left, class Right>
00055 struct GetBinExpTmpType<T,ROWS,COLS,ScalarCon<Left>,SSCon<Right> > {
00056     typedef Mat<SSCon<SCon<ROWS,COLS,T> >, EmptyErrorChecker> RET;
00057 };
00059 
00060 
00061 // Common typedefs for different SIMD expressions
00062 /*  The typedef of rep_type do the magic that the resulting AddExp
00063  *  will be wrapped by the SSCon
00064  */
00065 #define COMMON_SIMDEXP_TYPEDEFS(LOrR)                   \
00066 typedef SSCon<self_type>                rep_type;       \
00067 typedef const ExpRow<self_type>         const_row_type; \
00068 typedef typename super_type::index_type index_type;     \
00069 typedef typename LOrR::SIMD_unit_type   SIMD_unit_type; \
00070 typedef typename super_type::value_type value_type;     \
00071 enum {  ROWS = super_type::ROWS,                        \
00072         COLS = super_type::COLS     };                  \
00073 typedef Left left_type;                                 \
00074 typedef Right right_type;                               \
00075 using super_type::leftOp;                               \
00076 using super_type::rightOp;                              \
00077 typedef typename GetBinExpTmpType<value_type,ROWS,COLS,Left,Right>::RET temp_type;
00078 
00079 
00081 
00082 // The new specialization is inherited form the general one,
00083 // so the ability of per element access is still there.
00084 template<class Left_, class Right_>
00085 class AddExp<SSCon<Left_>, SSCon<Right_> > :
00086 public AddExp<Left_, Right_>,
00087 public SIMDTag
00088 {
00089     typedef SSCon<Left_>            Left;
00090     typedef SSCon<Right_>           Right;
00091     typedef AddExp<Left_, Right_>   super_type;
00092     typedef AddExp<Left, Right>     self_type;
00093 public:
00094 
00095     COMMON_SIMDEXP_TYPEDEFS(Left);
00096 
00097     EXMAT_INLINE2 AddExp(const self_type& self)
00098         : super_type(self) {}
00099     EXMAT_INLINE2 AddExp(const Left& l, const Right& r)
00100         : super_type(l, r) {}
00101 
00102     /************************************************/
00103     // Index function
00104     EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00105         return Intrinsics::add_p(leftOp.getUnitAt(i), rightOp.getUnitAt(i));
00106     }
00107 };
00108 
00110 template<class Left_, typename Right_>
00111 class AddExp<SSCon<Left_>, ScalarCon<Right_> > :
00112 public AddExp<Left_, ScalarCon<Right_> >,
00113 public SIMDTag
00114 {
00115     typedef SSCon<Left_>            Left;
00116     typedef ScalarCon<Right_>       Right;
00117     typedef AddExp<Left_, Right>    super_type;
00118     typedef AddExp<Left, Right>     self_type;
00119 public:
00120 
00121     COMMON_SIMDEXP_TYPEDEFS(Left);
00122 
00123     EXMAT_INLINE2 AddExp(const self_type& self)
00124         : super_type(self), unitData(self.unitData)
00125     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00126     EXMAT_INLINE2 AddExp(const Left& l, const Right& r)
00127         : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&r.scalar))
00128     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00129 
00130     /************************************************/
00131     // Index function
00132     EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00133         return Intrinsics::add_p(leftOp.getUnitAt(i), unitData);
00134     }
00135 protected:
00136     SIMD_unit_type unitData;
00137 };
00138 
00140 template<class Left_, typename Right_>
00141 class AddExp<ScalarCon<Left_>, SSCon<Right_> > :
00142 public AddExp<ScalarCon<Left_>, Right_>,
00143 public SIMDTag
00144 {
00145     typedef ScalarCon<Left_>        Left;
00146     typedef SSCon<Right_>           Right;
00147     typedef AddExp<Left, Right_>    super_type;
00148     typedef AddExp<Left, Right>     self_type;
00149 public:
00150 
00151     COMMON_SIMDEXP_TYPEDEFS(Right);
00152 
00153     EXMAT_INLINE2 AddExp(const self_type& self)
00154         : super_type(self), unitData(self.unitData)
00155     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00156     EXMAT_INLINE2 AddExp(const Left& l, const Right& r)
00157         : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&l.scalar))
00158     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00159 
00160     /************************************************/
00161     // Index function
00162     EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00163         return Intrinsics::add_p(unitData, rightOp.getUnitAt(i));
00164     }
00165 protected:
00166     SIMD_unit_type unitData;
00167 };
00169 
00170 
00172 
00173 template<class Left_, class Right_>
00174 class SubExp<SSCon<Left_>, SSCon<Right_> > :
00175 public SubExp<Left_, Right_>,
00176 public SIMDTag
00177 {
00178     typedef SSCon<Left_>            Left;
00179     typedef SSCon<Right_>           Right;
00180     typedef SubExp<Left_, Right_>   super_type;
00181     typedef SubExp<Left, Right>     self_type;
00182 public:
00183 
00184     COMMON_SIMDEXP_TYPEDEFS(Left);
00185 
00186     EXMAT_INLINE2 SubExp(const self_type& self)
00187         : super_type(self) {}
00188     EXMAT_INLINE2 SubExp(const Left& l, const Right& r)
00189         : super_type(l, r) {}
00190 
00191     /************************************************/
00192     // Index function
00193     EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00194         return Intrinsics::sub_p(leftOp.getUnitAt(i), rightOp.getUnitAt(i));
00195     }
00196 };
00197 
00199 template<class Left_, typename Right_>
00200 class SubExp<SSCon<Left_>, ScalarCon<Right_> > :
00201 public SubExp<Left_, ScalarCon<Right_> >,
00202 public SIMDTag
00203 {
00204     typedef SSCon<Left_>            Left;
00205     typedef ScalarCon<Right_>       Right;
00206     typedef SubExp<Left_, Right>    super_type;
00207     typedef SubExp<Left, Right>     self_type;
00208 public:
00209 
00210     COMMON_SIMDEXP_TYPEDEFS(Left);
00211 
00212     EXMAT_INLINE2 SubExp(const self_type& self)
00213         : super_type(self), unitData(self.unitData)
00214     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00215     EXMAT_INLINE2 SubExp(const Left& l, const Right& r)
00216         : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&r.scalar))
00217     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00218 
00219     /************************************************/
00220     // Index function
00221     EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00222         return Intrinsics::sub_p(leftOp.getUnitAt(i), unitData);
00223     }
00224 protected:
00225     SIMD_unit_type unitData;
00226 };
00227 
00229 template<class Left_, typename Right_>
00230 class SubExp<ScalarCon<Left_>, SSCon<Right_> > :
00231 public SubExp<ScalarCon<Left_>, Right_>,
00232 public SIMDTag
00233 {
00234     typedef ScalarCon<Left_>        Left;
00235     typedef SSCon<Right_>           Right;
00236     typedef SubExp<Left, Right_>    super_type;
00237     typedef SubExp<Left, Right>     self_type;
00238 public:
00239 
00240     COMMON_SIMDEXP_TYPEDEFS(Right);
00241 
00242     EXMAT_INLINE2 SubExp(const self_type& self)
00243         : super_type(self), unitData(self.unitData)
00244     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00245     EXMAT_INLINE2 SubExp(const Left& l, const Right& r)
00246         : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&l.scalar))
00247     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00248 
00249     /************************************************/
00250     // Index function
00251     EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00252         return Intrinsics::sub_p(unitData, rightOp.getUnitAt(i));
00253     }
00254 protected:
00255     SIMD_unit_type unitData;
00256 };
00258 
00259 
00261 
00262 template<class Left_, class Right_>
00263 class MulExp<SSCon<Left_>, SSCon<Right_> > :
00264 public MulExp<Left_, Right_>,
00265 public SIMDTag
00266 {
00267     typedef SSCon<Left_>            Left;
00268     typedef SSCon<Right_>           Right;
00269     typedef MulExp<Left_, Right_>   super_type;
00270     typedef MulExp<Left, Right>     self_type;
00271 public:
00272 
00273     COMMON_SIMDEXP_TYPEDEFS(Left);
00274 
00275     EXMAT_INLINE2 MulExp(const self_type& self)
00276         : super_type(self) {}
00277     EXMAT_INLINE2 MulExp(const Left& l, const Right& r)
00278         : super_type(l, r) {}
00279 
00281 
00282     EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00283         THROWMSG(false, InternalErrMsg, __FILE__);
00284         return leftOp.getUnitAt(i);
00285     }
00287 };
00288 
00290 template<class Left_, class Right_>
00291 class ScalarMulExp<SSCon<Left_>, ScalarCon<Right_> > :
00292 public ScalarMulExp<Left_, ScalarCon<Right_> >,
00293 public SIMDTag
00294 {
00295     typedef SSCon<Left_>                Left;
00296     typedef ScalarCon<Right_>           Right;
00297     typedef ScalarMulExp<Left_, Right>  super_type;
00298     typedef ScalarMulExp<Left, Right>   self_type;
00299 public:
00300 
00301     COMMON_SIMDEXP_TYPEDEFS(Left);
00302 
00303     EXMAT_INLINE2 ScalarMulExp(const self_type& self)
00304         : super_type(self), unitData(self.unitData)
00305     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00306     EXMAT_INLINE2 ScalarMulExp(const Left& l, const Right& r)
00307         : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&r.scalar))
00308     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00309 
00310     /************************************************/
00311     // Index function
00312     EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00313         return Intrinsics::mul_p(leftOp.getUnitAt(i), unitData);
00314     }
00315 protected:
00316     SIMD_unit_type unitData;
00317 };
00318 
00320 template<class Left_, class Right_>
00321 class ScalarMulExp<ScalarCon<Left_>, SSCon<Right_> > :
00322 public ScalarMulExp<ScalarCon<Left_>, Right_>,
00323 public SIMDTag
00324 {
00325     typedef ScalarCon<Left_>            Left;
00326     typedef SSCon<Right_>               Right;
00327     typedef ScalarMulExp<Left, Right_>  super_type;
00328     typedef ScalarMulExp<Left, Right>   self_type;
00329 public:
00330 
00331     COMMON_SIMDEXP_TYPEDEFS(Right);
00332 
00333     EXMAT_INLINE2 ScalarMulExp(const self_type& self)
00334         : super_type(self), unitData(self.unitData)
00335     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00336     EXMAT_INLINE2 ScalarMulExp(const Left& l, const Right& r)
00337         : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&l.scalar))
00338     {   ALIGNMENT_CHECK(sizeof(SIMD_unit_type));    }
00339 
00340     /************************************************/
00341     // Index function
00342     EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00343         return Intrinsics::mul_p(unitData, rightOp.getUnitAt(i));
00344     }
00345 protected:
00346     SIMD_unit_type unitData;
00347 };
00349 
00350 
00351 #undef COMMON_SIMDEXP_TYPEDEFS
00352 
00353 
00354 #endif  // HAVE_PARTIAL_SPECIALIZATION
00355 
00356 
00357 };
00358 
00359 #ifdef _MSC_VER
00360 #   pragma warning( pop )
00361 #endif  // _MSC_VER

Generated on Sat May 6 23:12:01 2006 for Exmat by  doxygen 1.4.6-NO