Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ShConcreteRegularOpImpl.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright 2003-2005 Serious Hack Inc.
00004 // 
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00018 // MA  02110-1301, USA
00020 #ifndef SHCONCRETEREGULAROPIMPL_HPP 
00021 #define SHCONCRETEREGULAROPIMPL_HPP
00022 #include <numeric>
00023 #include <cmath>
00024 #include "ShEval.hpp"
00025 #include "ShDebug.hpp"
00026 #include "ShError.hpp"
00027 #include "ShTypeInfo.hpp"
00028 #include "ShVariant.hpp"
00029 
00030 namespace SH {
00031 
00032 /* Partial specialization for different operations */ 
00033 /* The operators that depend on cmath different library functions
00034  * are specialized for float and double types in ShEval.cpp 
00035  * right now
00036  */
00037 // TODO make this cleaner?
00038 // TODO use the information from sdt's ShOperationInfo to decide
00039 // whether to do the ao/bo/co special case for scalar
00040 // ops where we step through the destination tuple but always
00041 // use the same element from the scalar src tuple. 
00042 // macros for componentwise operations
00043 // do a partial specialization on the class
00044 // and define the doop function
00045 //
00046 #define SHCRO_UNARY_OP(op, opsrc)\
00047 template<typename T>\
00048 struct ShConcreteRegularOp<op, T>\
00049 { \
00050   typedef ShDataVariant<T, SH_HOST> Variant; \
00051   typedef Variant* DataPtr; \
00052   typedef const Variant* DataCPtr; \
00053 \
00054   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00055   {\
00056     SH_DEBUG_ASSERT(dest && a);\
00057     int ao = a->size() > 1;\
00058   \
00059     typename Variant::iterator D = dest->begin();\
00060     typename Variant::const_iterator A = a->begin();\
00061     for(; D != dest->end(); A += ao, ++D) {\
00062       (*D) = opsrc;\
00063     }\
00064   } \
00065 };
00066 
00067 #define SHCRO_BINARY_OP(op, opsrc)\
00068 template<typename T>\
00069 struct ShConcreteRegularOp<op, T>\
00070 { \
00071   typedef ShDataVariant<T, SH_HOST> Variant; \
00072   typedef Variant* DataPtr; \
00073   typedef const Variant* DataCPtr; \
00074 \
00075   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00076   {\
00077     SH_DEBUG_ASSERT(dest && a && b);\
00078     int ao = a->size() > 1;\
00079     int bo = b->size() > 1;\
00080   \
00081     typename Variant::iterator D = dest->begin();\
00082     typename Variant::const_iterator A, B;\
00083     A = a->begin();\
00084     B = b->begin();\
00085     for(; D != dest->end(); A += ao, B += bo, ++D) {\
00086       (*D) = opsrc;\
00087     }\
00088   } \
00089 };
00090 
00091 #define SHCRO_TERNARY_OP(op, opsrc)\
00092 template<typename T>\
00093 struct ShConcreteRegularOp<op, T>\
00094 { \
00095   typedef ShDataVariant<T, SH_HOST> Variant; \
00096   typedef Variant* DataPtr; \
00097   typedef const Variant* DataCPtr; \
00098 \
00099   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00100   {\
00101     SH_DEBUG_ASSERT(dest && a && b && c);\
00102     int ao = a->size() > 1;\
00103     int bo = b->size() > 1;\
00104     int co = c->size() > 1;\
00105   \
00106     typename Variant::iterator D = dest->begin();\
00107     typename Variant::const_iterator A, B, C;\
00108     A = a->begin();\
00109     B = b->begin();\
00110     C = c->begin();\
00111     for(; D != dest->end(); A += ao, B += bo, C += co, ++D) {\
00112       (*D) = opsrc;\
00113     }\
00114   }\
00115 };
00116 
00117 // Unary ops
00118 SHCRO_UNARY_OP(SH_OP_ABS, abs(*A));
00119 SHCRO_UNARY_OP(SH_OP_ACOS, acos(*A));
00120 SHCRO_UNARY_OP(SH_OP_ASIN, asin(*A));
00121 SHCRO_UNARY_OP(SH_OP_ASN, (*A));
00122 SHCRO_UNARY_OP(SH_OP_ATAN, atan(*A));
00123 SHCRO_UNARY_OP(SH_OP_CBRT, cbrt(*A));
00124 SHCRO_UNARY_OP(SH_OP_CEIL, ceil(*A));
00125 
00126 #ifdef WIN32
00127 SHCRO_UNARY_OP(SH_OP_ACOSH, log((*A) + sqrt((*A) * (*A) - 1)));
00128 SHCRO_UNARY_OP(SH_OP_ASINH, log((*A) + sqrt((*A) * (*A) + 1)));
00129 SHCRO_UNARY_OP(SH_OP_ATANH, log((1.0 + (*A))/(1.0 - (*A)))/2.0);
00130 #else
00131 SHCRO_UNARY_OP(SH_OP_ACOSH, acosh(*A));
00132 SHCRO_UNARY_OP(SH_OP_ASINH, asinh(*A));
00133 SHCRO_UNARY_OP(SH_OP_ATANH, atanh(*A));
00134 #endif
00135 
00136 template<typename T>
00137 struct ShConcreteRegularOp<SH_OP_CMUL, T>
00138 {
00139   typedef ShDataVariant<T, SH_HOST> Variant; 
00140   typedef Variant* DataPtr; 
00141   typedef const Variant* DataCPtr; 
00142 
00143   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00144   {
00145     // dest->size should be 1 and a->size == b->size
00146     (*dest)[0] = std::accumulate(a->begin(), a->end(), 
00147                       ShDataTypeInfo<T, SH_HOST>::One, 
00148                       std::multiplies<typename Variant::DataType>());
00149   }
00150 };
00151 
00152 SHCRO_UNARY_OP(SH_OP_COS, cos(*A));
00153 SHCRO_UNARY_OP(SH_OP_COSH, cosh(*A));
00154 
00155 template<typename T>
00156 struct ShConcreteRegularOp<SH_OP_CSUM, T>
00157 {
00158   typedef ShDataVariant<T, SH_HOST> Variant; 
00159   typedef Variant* DataPtr; 
00160   typedef const Variant* DataCPtr; 
00161 
00162   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00163   {
00164     // dest->size should be 1 and a->size == b->size
00165     (*dest)[0] = std::accumulate(a->begin(), a->end(), 
00166                       ShDataTypeInfo<T, SH_HOST>::Zero, 
00167                       std::plus<typename Variant::DataType>());
00168   }
00169 };
00170 
00171 SHCRO_UNARY_OP(SH_OP_EXP, exp(*A));
00172 SHCRO_UNARY_OP(SH_OP_EXP2, exp2(*A));
00173 SHCRO_UNARY_OP(SH_OP_EXP10, exp10(*A));
00174 SHCRO_UNARY_OP(SH_OP_FLR, floor(*A));
00175 SHCRO_UNARY_OP(SH_OP_FRAC, frac(*A));
00176 SHCRO_UNARY_OP(SH_OP_LOG, log(*A));
00177 SHCRO_UNARY_OP(SH_OP_LOG2, log(*A));
00178 SHCRO_UNARY_OP(SH_OP_LOG10, log10(*A));
00179 
00180 template<typename T>
00181 struct ShConcreteRegularOp<SH_OP_LIT, T>
00182 {
00183   typedef ShDataVariant<T, SH_HOST> Variant; 
00184   typedef Variant* DataPtr; 
00185   typedef const Variant* DataCPtr; 
00186   typedef typename Variant::DataType DataType;
00187 
00188   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00189   {
00190     DataType x, y, w;
00191     x = max((*a)[0], 0);
00192     y = max((*a)[1], 0);
00193     w = (*a)[2];
00194     w = min(w, 128); 
00195     w = max(w, -128); 
00196     (*dest)[0] = 1;
00197     (*dest)[1] = x;
00198     (*dest)[2] = (x > 0) * pow(y,w);
00199     (*dest)[3] = 1;
00200   }
00201 };
00202 
00203 template<typename T>
00204 struct ShConcreteRegularOp<SH_OP_HASH, T>
00205 {
00206   typedef ShDataVariant<T, SH_HOST> Variant; 
00207   typedef Variant* DataPtr; 
00208   typedef const Variant* DataCPtr; 
00209 
00210   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00211   {
00212     SH_DEBUG_ASSERT(dest && a);
00213     typename Variant::iterator D = dest->begin();
00214     typename Variant::const_iterator A = a->begin();
00215     for(; D != dest->end(); ++A, ++D) (*D) = (*A);
00216     // TODO: implement the real algorithm
00217   }
00218 };
00219 
00220 template<typename T>
00221 struct ShConcreteRegularOp<SH_OP_NOISE, T>
00222 {
00223   typedef ShDataVariant<T, SH_HOST> Variant; 
00224   typedef Variant* DataPtr; 
00225   typedef const Variant* DataCPtr; 
00226 
00227   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00228   {
00229     SH_DEBUG_ASSERT(dest && a);
00230     typename Variant::iterator D = dest->begin();
00231     typename Variant::const_iterator A = a->begin();
00232     for(; D != dest->end(); ++A, ++D) (*D) = (*A);
00233     // TODO: implement the real algorithm
00234   }
00235 };
00236 
00237 template<typename T>
00238 struct ShConcreteRegularOp<SH_OP_NORM, T>
00239 {
00240   typedef ShDataVariant<T, SH_HOST> Variant; 
00241   typedef Variant* DataPtr; 
00242   typedef const Variant* DataCPtr; 
00243 
00244   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00245   {
00246     SH_DEBUG_ASSERT(dest && a);
00247     typename Variant::DataType m = sqrt(std::inner_product(a->begin(), a->end(), 
00248           a->begin(), ShDataTypeInfo<T, SH_HOST>::Zero));
00249 
00250     typename Variant::iterator D = dest->begin();
00251     typename Variant::const_iterator A = a->begin();
00252     for(; D != dest->end(); ++A, ++D) (*D) = (*A) / m;
00253   }
00254 };
00255 
00256 SHCRO_UNARY_OP(SH_OP_RCP, rcp(*A));
00257 SHCRO_UNARY_OP(SH_OP_RND, rnd(*A));
00258 SHCRO_UNARY_OP(SH_OP_RSQ, rsq(*A));
00259 SHCRO_UNARY_OP(SH_OP_SIN, sin(*A));
00260 SHCRO_UNARY_OP(SH_OP_SINH, sinh(*A));
00261 SHCRO_UNARY_OP(SH_OP_SGN, sgn(*A));
00262 SHCRO_UNARY_OP(SH_OP_SQRT, sqrt(*A));
00263 SHCRO_UNARY_OP(SH_OP_TAN, tan(*A));
00264 SHCRO_UNARY_OP(SH_OP_TANH, tan(*A));
00265 
00266 // Binary ops
00267 SHCRO_BINARY_OP(SH_OP_ADD, (*A) + (*B));
00268 SHCRO_BINARY_OP(SH_OP_ATAN2, atan2((*B), (*A)));
00269 SHCRO_BINARY_OP(SH_OP_DIV, (*A) / (*B));
00270 SHCRO_BINARY_OP(SH_OP_MAX, max((*A), (*B))); 
00271 SHCRO_BINARY_OP(SH_OP_MIN, min((*A), (*B))); 
00272 SHCRO_BINARY_OP(SH_OP_MOD, (*A) % (*B)); 
00273 SHCRO_BINARY_OP(SH_OP_MUL, (*A) * (*B));
00274 SHCRO_BINARY_OP(SH_OP_POW, pow((*A), (*B)));
00275 
00276 template<typename T>
00277 struct ShConcreteRegularOp<SH_OP_DOT, T>
00278 {
00279   typedef ShDataVariant<T, SH_HOST> Variant; 
00280   typedef Variant* DataPtr; 
00281   typedef const Variant* DataCPtr; 
00282 
00283   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00284   {
00285     // dest->size should be 1 and a->size == b->size
00286     (*dest)[0] = std::inner_product(a->begin(), a->end(), b->begin(), 
00287                       ShDataTypeInfo<T, SH_HOST>::Zero);
00288   }
00289 };
00290 
00291 SHCRO_BINARY_OP(SH_OP_SEQ, (*A) == (*B));
00292 SHCRO_BINARY_OP(SH_OP_SGE, (*A) >= (*B));
00293 SHCRO_BINARY_OP(SH_OP_SGT, (*A) > (*B));
00294 SHCRO_BINARY_OP(SH_OP_SLE, (*A) <= (*B));
00295 SHCRO_BINARY_OP(SH_OP_SLT, (*A) < (*B));
00296 SHCRO_BINARY_OP(SH_OP_SNE, (*A) != (*B));
00297 
00298 template<typename T>
00299 struct ShConcreteRegularOp<SH_OP_XPD, T>
00300 {
00301   typedef ShDataVariant<T, SH_HOST> Variant; 
00302   typedef Variant* DataPtr; 
00303   typedef const Variant* DataCPtr; 
00304 
00305   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00306   {
00307     (*dest)[0] = (*a)[1] * (*b)[2] - (*a)[2] * (*b)[1];
00308     (*dest)[1] = -((*a)[0] * (*b)[2] - (*a)[2] * (*b)[0]);
00309     (*dest)[2] = (*a)[0] * (*b)[1] - (*a)[1] * (*b)[0];
00310   }
00311 };
00312 
00313 // Ternary Ops
00314 SHCRO_TERNARY_OP(SH_OP_COND, cond(*A, *B, *C)); 
00315 SHCRO_TERNARY_OP(SH_OP_LRP, lerp(*A, *B, *C));
00316 SHCRO_TERNARY_OP(SH_OP_MAD, (*A) * (*B) + (*C));
00317 
00318 }
00319 #endif

Generated on Thu Jul 28 17:33:01 2005 for Sh by  doxygen 1.4.3-20050530