00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024 #ifndef SHCONCRETECTYPEOPIMPL_HPP
00025 #define SHCONCRETECTYPEOPIMPL_HPP
00026
00027 #include <numeric>
00028 #include <cmath>
00029 #include "ShEval.hpp"
00030 #include "ShVariant.hpp"
00031 #include "ShDebug.hpp"
00032 #include "ShError.hpp"
00033 #include "ShTypeInfo.hpp"
00034
00035 namespace {
00037 template<typename T1, typename T2>
00038 T1 _sh_intpow(T1 x, T2 pow)
00039 {
00040 T1 result = 1;
00041 if(pow < 0) {
00042 x = 1 / x;
00043 pow = -pow;
00044 }
00045 for(;pow; pow >>= 1, x *= x) {
00046 if(pow & 1) result *= x;
00047 }
00048 return result;
00049 }
00050 }
00051 namespace SH {
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #define SHCCTO_UNARY_OP(op, opsrc)\
00070 template<typename T>\
00071 struct ShConcreteCTypeOp<op, T>\
00072 { \
00073 typedef ShDataVariant<T, SH_HOST> Variant; \
00074 typedef Variant* DataPtr; \
00075 typedef const Variant* DataCPtr; \
00076 \
00077 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00078 {\
00079 SH_DEBUG_ASSERT(dest && a);\
00080 int ao = a->size() > 1;\
00081 \
00082 typename Variant::iterator D = dest->begin();\
00083 typename Variant::const_iterator A = a->begin();\
00084 for(; D != dest->end(); A += ao, ++D) {\
00085 (*D) = opsrc;\
00086 }\
00087 } \
00088 };
00089
00090
00091 #define SHCCTO_BINARY_OP(op, opsrc)\
00092 template<typename T>\
00093 struct ShConcreteCTypeOp<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);\
00102 int ao = a->size() > 1;\
00103 int bo = b->size() > 1;\
00104 \
00105 typename Variant::iterator D = dest->begin();\
00106 typename Variant::const_iterator A, B;\
00107 A = a->begin();\
00108 B = b->begin();\
00109 for(; D != dest->end(); A += ao, B += bo, ++D) {\
00110 (*D) = opsrc;\
00111 }\
00112 } \
00113 };
00114
00115
00116 #define SHCCTO_TERNARY_OP(op, opsrc)\
00117 template<typename T>\
00118 struct ShConcreteCTypeOp<op, T>\
00119 { \
00120 typedef ShDataVariant<T, SH_HOST> Variant; \
00121 typedef Variant* DataPtr; \
00122 typedef const Variant* DataCPtr; \
00123 \
00124 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00125 {\
00126 SH_DEBUG_ASSERT(dest && a && b && c);\
00127 int ao = a->size() > 1;\
00128 int bo = b->size() > 1;\
00129 int co = c->size() > 1;\
00130 \
00131 typename Variant::iterator D = dest->begin();\
00132 typename Variant::const_iterator A, B, C;\
00133 A = a->begin();\
00134 B = b->begin();\
00135 C = c->begin();\
00136 for(; D != dest->end(); A += ao, B += bo, C += co, ++D) {\
00137 (*D) = opsrc;\
00138 }\
00139 }\
00140 };
00141
00142 #define SHCCTO_OP_SPEC(T, op)\
00143 template<>\
00144 struct \
00145 SH_DLLEXPORT \
00146 ShConcreteCTypeOp<op, T>\
00147 { \
00148 typedef ShDataVariant<T, SH_HOST> Variant; \
00149 typedef Variant* DataPtr; \
00150 typedef const Variant* DataCPtr; \
00151 \
00152 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0); \
00153 };
00154
00155 #define SHCCTO_OP_CMATH_SPEC(op)\
00156 SHCCTO_OP_SPEC(double, op);\
00157 SHCCTO_OP_SPEC(float, op);
00158
00159
00160
00161
00162
00163
00164 SHCCTO_UNARY_OP(SH_OP_ABS, (shDataTypeIsPositive(*A) ? (*A) : -(*A)));
00165
00166 SHCCTO_OP_CMATH_SPEC(SH_OP_ACOS);
00167 SHCCTO_OP_CMATH_SPEC(SH_OP_ASIN);
00168
00169 SHCCTO_UNARY_OP(SH_OP_ASN, (*A));
00170
00171 SHCCTO_OP_CMATH_SPEC(SH_OP_ATAN);
00172 SHCCTO_OP_CMATH_SPEC(SH_OP_CBRT);
00173 SHCCTO_OP_CMATH_SPEC(SH_OP_CEIL);
00174
00175 template<typename T>
00176 struct ShConcreteCTypeOp<SH_OP_CMUL, T>
00177 {
00178 typedef ShDataVariant<T, SH_HOST> Variant;
00179 typedef Variant* DataPtr;
00180 typedef const Variant* DataCPtr;
00181
00182 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00183 {
00184
00185 (*dest)[0] = std::accumulate(a->begin(), a->end(),
00186 ShDataTypeInfo<T, SH_HOST>::One,
00187 std::multiplies<typename Variant::DataType>());
00188 }
00189 };
00190
00191 SHCCTO_OP_CMATH_SPEC(SH_OP_COS);
00192
00193 template<typename T>
00194 struct ShConcreteCTypeOp<SH_OP_CSUM, T>
00195 {
00196 typedef ShDataVariant<T, SH_HOST> Variant;
00197 typedef Variant* DataPtr;
00198 typedef const Variant* DataCPtr;
00199
00200 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00201 {
00202
00203 (*dest)[0] = std::accumulate(a->begin(), a->end(),
00204 ShDataTypeInfo<T, SH_HOST>::Zero,
00205 std::plus<typename Variant::DataType>());
00206 }
00207 };
00208
00209 SHCCTO_OP_CMATH_SPEC(SH_OP_EXP);
00210 SHCCTO_OP_CMATH_SPEC(SH_OP_EXP2);
00211 SHCCTO_OP_CMATH_SPEC(SH_OP_EXP10);
00212 SHCCTO_OP_CMATH_SPEC(SH_OP_FLR);
00213 SHCCTO_OP_CMATH_SPEC(SH_OP_FRAC);
00214 SHCCTO_OP_CMATH_SPEC(SH_OP_LOG);
00215 SHCCTO_OP_CMATH_SPEC(SH_OP_LOG2);
00216 SHCCTO_OP_CMATH_SPEC(SH_OP_LOG10);
00217 SHCCTO_OP_CMATH_SPEC(SH_OP_NORM);
00218
00219 SHCCTO_UNARY_OP(SH_OP_RCP, 1 / (*A));
00220
00221 SHCCTO_OP_CMATH_SPEC(SH_OP_RND);
00222 SHCCTO_OP_CMATH_SPEC(SH_OP_RSQ);
00223 SHCCTO_OP_CMATH_SPEC(SH_OP_SIN);
00224
00225 SHCCTO_UNARY_OP(SH_OP_SGN, (*A) > 0 ? 1 : (*A) < 0 ? -1 : 0);
00226
00227 SHCCTO_OP_CMATH_SPEC(SH_OP_SQRT);
00228 SHCCTO_OP_CMATH_SPEC(SH_OP_TAN);
00229
00230 template<typename T>
00231 struct ShConcreteCTypeOp<SH_OP_LIT, T>
00232 {
00233 typedef ShDataVariant<T, SH_HOST> Variant;
00234 typedef Variant* DataPtr;
00235 typedef const Variant* DataCPtr;
00236
00237 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00238 {
00239 typename Variant::DataType x, y, w;
00240 x = (*a)[0];
00241 if (x < 0) x = 0;
00242 y = (*a)[1];
00243 if (y < 0) y = 0;
00244 w = (*a)[2];
00245 if (w < -128) w = -128;
00246 if (w > 128) w = 128;
00247 (*dest)[0] = 1;
00248 (*dest)[1] = x;
00249 (*dest)[2] = (x > 0) ? std::pow(y,w) : 0;
00250 (*dest)[3] = 1;
00251 }
00252 };
00253
00254
00255 SHCCTO_BINARY_OP(SH_OP_ADD, (*A) + (*B));
00256
00257 SHCCTO_OP_CMATH_SPEC(SH_OP_ATAN2);
00258
00259 SHCCTO_BINARY_OP(SH_OP_DIV, (*A) / (*B));
00260
00261 template<typename T>
00262 struct ShConcreteCTypeOp<SH_OP_DOT, T>
00263 {
00264 typedef ShDataVariant<T, SH_HOST> Variant;
00265 typedef Variant* DataPtr;
00266 typedef const Variant* DataCPtr;
00267
00268 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00269 {
00270
00271 (*dest)[0] = std::inner_product(a->begin(), a->end(), b->begin(),
00272 ShDataTypeInfo<T, SH_HOST>::Zero);
00273 }
00274 };
00275
00276 SHCCTO_BINARY_OP(SH_OP_MAX, std::max((*A), (*B)));
00277 SHCCTO_BINARY_OP(SH_OP_MIN, std::min((*A), (*B)));
00278
00279 SHCCTO_BINARY_OP(SH_OP_MOD, ((*A) - (*B) * (int)std::floor((double)(*A) / (*B))));
00280 SHCCTO_OP_CMATH_SPEC(SH_OP_MOD);
00281
00282 SHCCTO_BINARY_OP(SH_OP_MUL, (*A) * (*B));
00283
00284
00285 SHCCTO_BINARY_OP(SH_OP_POW, _sh_intpow((*A), (*B)));
00286 SHCCTO_OP_CMATH_SPEC(SH_OP_POW);
00287
00288
00289 SHCCTO_BINARY_OP(SH_OP_SEQ, (shDataTypeCond<T, SH_HOST>((*A) == (*B))));
00290 SHCCTO_BINARY_OP(SH_OP_SGE, (shDataTypeCond<T, SH_HOST>((*A) >= (*B))));
00291 SHCCTO_BINARY_OP(SH_OP_SGT, (shDataTypeCond<T, SH_HOST>((*A) > (*B))));
00292 SHCCTO_BINARY_OP(SH_OP_SLE, (shDataTypeCond<T, SH_HOST>((*A) <= (*B))));
00293 SHCCTO_BINARY_OP(SH_OP_SLT, (shDataTypeCond<T, SH_HOST>((*A) < (*B))));
00294 SHCCTO_BINARY_OP(SH_OP_SNE, (shDataTypeCond<T, SH_HOST>((*A) != (*B))));
00295
00296 template<typename T>
00297 struct ShConcreteCTypeOp<SH_OP_XPD, T>
00298 {
00299 typedef ShDataVariant<T, SH_HOST> Variant;
00300 typedef Variant* DataPtr;
00301 typedef const Variant* DataCPtr;
00302
00303 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00304 {
00305
00306
00307 typename Variant::DataType t0, t1;
00308 t0 = (*a)[1] * (*b)[2] - (*a)[2] * (*b)[1];
00309 t1 = -((*a)[0] * (*b)[2] - (*a)[2] * (*b)[0]);
00310 (*dest)[2] = (*a)[0] * (*b)[1] - (*a)[1] * (*b)[0];
00311 (*dest)[0] = t0;
00312 (*dest)[1] = t1;
00313 }
00314 };
00315
00316
00317 SHCCTO_TERNARY_OP(SH_OP_COND, ((*A) > 0 ? (*B) : (*C)));
00318 SHCCTO_TERNARY_OP(SH_OP_LRP, (*A) * (*B) + (1 - (*A)) * (*C));
00319 SHCCTO_TERNARY_OP(SH_OP_MAD, (*A) * (*B) + (*C));
00320
00321 }
00322
00323 #endif