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 software is provided 'as-is', without any express or implied
00006 // warranty. In no event will the authors be held liable for any damages
00007 // arising from the use of this software.
00008 // 
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it
00011 // freely, subject to the following restrictions:
00012 // 
00013 // 1. The origin of this software must not be misrepresented; you must
00014 // not claim that you wrote the original software. If you use this
00015 // software in a product, an acknowledgment in the product documentation
00016 // would be appreciated but is not required.
00017 // 
00018 // 2. Altered source versions must be plainly marked as such, and must
00019 // not be misrepresented as being the original software.
00020 // 
00021 // 3. This notice may not be removed or altered from any source
00022 // distribution.
00024 #ifndef SHCONCRETEREGULAROPIMPL_HPP 
00025 #define SHCONCRETEREGULAROPIMPL_HPP
00026 #include <numeric>
00027 #include <cmath>
00028 #include "ShEval.hpp"
00029 #include "ShDebug.hpp"
00030 #include "ShError.hpp"
00031 #include "ShTypeInfo.hpp"
00032 #include "ShVariant.hpp"
00033 
00034 namespace SH {
00035 
00036 /* Partial specialization for different operations */ 
00037 /* The operators that depend on cmath different library functions
00038  * are specialized for float and double types in ShEval.cpp 
00039  * right now
00040  */
00041 // TODO make this cleaner?
00042 // TODO use the information from sdt's ShOperationInfo to decide
00043 // whether to do the ao/bo/co special case for scalar
00044 // ops where we step through the destination tuple but always
00045 // use the same element from the scalar src tuple. 
00046 // macros for componentwise operations
00047 // do a partial specialization on the class
00048 // and define the doop function
00049 //
00050 #define SHCRO_UNARY_OP(op, opsrc)\
00051 template<typename T>\
00052 struct ShConcreteRegularOp<op, T>\
00053 { \
00054   typedef ShDataVariant<T, SH_HOST> Variant; \
00055   typedef Variant* DataPtr; \
00056   typedef const Variant* DataCPtr; \
00057 \
00058   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00059   {\
00060     SH_DEBUG_ASSERT(dest && a);\
00061     int ao = a->size() > 1;\
00062   \
00063     typename Variant::iterator D = dest->begin();\
00064     typename Variant::const_iterator A = a->begin();\
00065     for(; D != dest->end(); A += ao, ++D) {\
00066       (*D) = opsrc;\
00067     }\
00068   } \
00069 };
00070 
00071 #define SHCRO_BINARY_OP(op, opsrc)\
00072 template<typename T>\
00073 struct ShConcreteRegularOp<op, T>\
00074 { \
00075   typedef ShDataVariant<T, SH_HOST> Variant; \
00076   typedef Variant* DataPtr; \
00077   typedef const Variant* DataCPtr; \
00078 \
00079   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00080   {\
00081     SH_DEBUG_ASSERT(dest && a && b);\
00082     int ao = a->size() > 1;\
00083     int bo = b->size() > 1;\
00084   \
00085     typename Variant::iterator D = dest->begin();\
00086     typename Variant::const_iterator A, B;\
00087     A = a->begin();\
00088     B = b->begin();\
00089     for(; D != dest->end(); A += ao, B += bo, ++D) {\
00090       (*D) = opsrc;\
00091     }\
00092   } \
00093 };
00094 
00095 #define SHCRO_TERNARY_OP(op, opsrc)\
00096 template<typename T>\
00097 struct ShConcreteRegularOp<op, T>\
00098 { \
00099   typedef ShDataVariant<T, SH_HOST> Variant; \
00100   typedef Variant* DataPtr; \
00101   typedef const Variant* DataCPtr; \
00102 \
00103   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00104   {\
00105     SH_DEBUG_ASSERT(dest && a && b && c);\
00106     int ao = a->size() > 1;\
00107     int bo = b->size() > 1;\
00108     int co = c->size() > 1;\
00109   \
00110     typename Variant::iterator D = dest->begin();\
00111     typename Variant::const_iterator A, B, C;\
00112     A = a->begin();\
00113     B = b->begin();\
00114     C = c->begin();\
00115     for(; D != dest->end(); A += ao, B += bo, C += co, ++D) {\
00116       (*D) = opsrc;\
00117     }\
00118   }\
00119 };
00120 
00121 // Unary ops
00122 SHCRO_UNARY_OP(SH_OP_ABS, abs(*A));
00123 SHCRO_UNARY_OP(SH_OP_ACOS, acos(*A));
00124 SHCRO_UNARY_OP(SH_OP_ASIN, asin(*A));
00125 SHCRO_UNARY_OP(SH_OP_ASN, (*A));
00126 SHCRO_UNARY_OP(SH_OP_ATAN, atan(*A));
00127 SHCRO_UNARY_OP(SH_OP_CBRT, cbrt(*A));
00128 SHCRO_UNARY_OP(SH_OP_CEIL, ceil(*A));
00129 
00130 template<typename T>
00131 struct ShConcreteRegularOp<SH_OP_CMUL, T>
00132 {
00133   typedef ShDataVariant<T, SH_HOST> Variant; 
00134   typedef Variant* DataPtr; 
00135   typedef const Variant* DataCPtr; 
00136 
00137   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00138   {
00139     // dest->size should be 1 and a->size == b->size
00140     (*dest)[0] = std::accumulate(a->begin(), a->end(), 
00141                       ShDataTypeInfo<T, SH_HOST>::One, 
00142                       std::multiplies<typename Variant::DataType>());
00143   }
00144 };
00145 
00146 SHCRO_UNARY_OP(SH_OP_COS, cos(*A));
00147 SHCRO_UNARY_OP(SH_OP_COSH, cosh(*A));
00148 
00149 template<typename T>
00150 struct ShConcreteRegularOp<SH_OP_CSUM, T>
00151 {
00152   typedef ShDataVariant<T, SH_HOST> Variant; 
00153   typedef Variant* DataPtr; 
00154   typedef const Variant* DataCPtr; 
00155 
00156   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00157   {
00158     // dest->size should be 1 and a->size == b->size
00159     (*dest)[0] = std::accumulate(a->begin(), a->end(), 
00160                       ShDataTypeInfo<T, SH_HOST>::Zero, 
00161                       std::plus<typename Variant::DataType>());
00162   }
00163 };
00164 
00165 SHCRO_UNARY_OP(SH_OP_EXP, exp(*A));
00166 SHCRO_UNARY_OP(SH_OP_EXP2, exp2(*A));
00167 SHCRO_UNARY_OP(SH_OP_EXP10, exp10(*A));
00168 SHCRO_UNARY_OP(SH_OP_FLR, floor(*A));
00169 SHCRO_UNARY_OP(SH_OP_FRAC, frac(*A));
00170 SHCRO_UNARY_OP(SH_OP_LOG, log(*A));
00171 SHCRO_UNARY_OP(SH_OP_LOG2, log(*A));
00172 SHCRO_UNARY_OP(SH_OP_LOG10, log10(*A));
00173 
00174 template<typename T>
00175 struct ShConcreteRegularOp<SH_OP_LIT, T>
00176 {
00177   typedef ShDataVariant<T, SH_HOST> Variant; 
00178   typedef Variant* DataPtr; 
00179   typedef const Variant* DataCPtr; 
00180   typedef typename Variant::DataType DataType;
00181 
00182   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00183   {
00184     DataType x, y, w;
00185     x = max((*a)[0], 0);
00186     y = max((*a)[1], 0);
00187     w = (*a)[2];
00188     w = min(w, 128); 
00189     w = max(w, -128); 
00190     (*dest)[0] = 1;
00191     (*dest)[1] = x;
00192     (*dest)[2] = (x > 0) * pow(y,w);
00193     (*dest)[3] = 1;
00194   }
00195 };
00196 
00197 template<typename T>
00198 struct ShConcreteRegularOp<SH_OP_NORM, T>
00199 {
00200   typedef ShDataVariant<T, SH_HOST> Variant; 
00201   typedef Variant* DataPtr; 
00202   typedef const Variant* DataCPtr; 
00203 
00204   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00205   {
00206     SH_DEBUG_ASSERT(dest && a);
00207     typename Variant::DataType m = sqrt(std::inner_product(a->begin(), a->end(), 
00208           a->begin(), ShDataTypeInfo<T, SH_HOST>::Zero));
00209 
00210     typename Variant::iterator D = dest->begin();
00211     typename Variant::const_iterator A = a->begin();
00212     for(; D != dest->end(); ++A, ++D) (*D) = (*A) / m;
00213   }
00214 };
00215 
00216 SHCRO_UNARY_OP(SH_OP_RCP, rcp(*A));
00217 SHCRO_UNARY_OP(SH_OP_RND, rnd(*A));
00218 SHCRO_UNARY_OP(SH_OP_RSQ, rsq(*A));
00219 SHCRO_UNARY_OP(SH_OP_SIN, sin(*A));
00220 SHCRO_UNARY_OP(SH_OP_SINH, sinh(*A));
00221 SHCRO_UNARY_OP(SH_OP_SGN, sgn(*A));
00222 SHCRO_UNARY_OP(SH_OP_SQRT, sqrt(*A));
00223 SHCRO_UNARY_OP(SH_OP_TAN, tan(*A));
00224 SHCRO_UNARY_OP(SH_OP_TANH, tan(*A));
00225 
00226 // Binary ops
00227 SHCRO_BINARY_OP(SH_OP_ADD, (*A) + (*B));
00228 SHCRO_BINARY_OP(SH_OP_ATAN2, atan2((*A), (*B)));
00229 SHCRO_BINARY_OP(SH_OP_DIV, (*A) / (*B));
00230 SHCRO_BINARY_OP(SH_OP_MAX, max((*A), (*B))); 
00231 SHCRO_BINARY_OP(SH_OP_MIN, min((*A), (*B))); 
00232 SHCRO_BINARY_OP(SH_OP_MOD, (*A) % (*B)); 
00233 SHCRO_BINARY_OP(SH_OP_MUL, (*A) * (*B));
00234 SHCRO_BINARY_OP(SH_OP_POW, pow((*A), (*B)));
00235 
00236 template<typename T>
00237 struct ShConcreteRegularOp<SH_OP_DOT, T>
00238 {
00239   typedef ShDataVariant<T, SH_HOST> Variant; 
00240   typedef Variant* DataPtr; 
00241   typedef const Variant* DataCPtr; 
00242 
00243   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00244   {
00245     // dest->size should be 1 and a->size == b->size
00246     (*dest)[0] = std::inner_product(a->begin(), a->end(), b->begin(), 
00247                       ShDataTypeInfo<T, SH_HOST>::Zero);
00248   }
00249 };
00250 
00251 SHCRO_BINARY_OP(SH_OP_SEQ, (*A) == (*B));
00252 SHCRO_BINARY_OP(SH_OP_SGE, (*A) >= (*B));
00253 SHCRO_BINARY_OP(SH_OP_SGT, (*A) > (*B));
00254 SHCRO_BINARY_OP(SH_OP_SLE, (*A) <= (*B));
00255 SHCRO_BINARY_OP(SH_OP_SLT, (*A) < (*B));
00256 SHCRO_BINARY_OP(SH_OP_SNE, (*A) != (*B));
00257 
00258 template<typename T>
00259 struct ShConcreteRegularOp<SH_OP_XPD, T>
00260 {
00261   typedef ShDataVariant<T, SH_HOST> Variant; 
00262   typedef Variant* DataPtr; 
00263   typedef const Variant* DataCPtr; 
00264 
00265   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00266   {
00267     (*dest)[0] = (*a)[1] * (*b)[2] - (*a)[2] * (*b)[1];
00268     (*dest)[1] = -((*a)[0] * (*b)[2] - (*a)[2] * (*b)[0]);
00269     (*dest)[2] = (*a)[0] * (*b)[1] - (*a)[1] * (*b)[0];
00270   }
00271 };
00272 
00273 // Ternary Ops
00274 SHCRO_TERNARY_OP(SH_OP_COND, cond(*A, *B, *C)); 
00275 SHCRO_TERNARY_OP(SH_OP_LRP, lerp(*A, *B, *C));
00276 SHCRO_TERNARY_OP(SH_OP_MAD, (*A) * (*B) + (*C));
00277 
00278 }
00279 #endif

Generated on Wed Jun 15 18:12:39 2005 for Sh by  doxygen 1.4.3-20050530