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 #ifndef SHCONCRETEREGULAROPIMPL_HPP 
00002 #define SHCONCRETEREGULAROPIMPL_HPP
00003 #include <numeric>
00004 #include "ShEval.hpp"
00005 #include "ShDebug.hpp"
00006 #include "ShError.hpp"
00007 #include "ShTypeInfo.hpp"
00008 #include "ShVariant.hpp"
00009 
00010 namespace SH {
00011 
00012 /* Partial specialization for different operations */ 
00013 /* The operators that depend on cmath different library functions
00014  * are specialized for float and double types in ShEval.cpp 
00015  * right now
00016  */
00017 // TODO make this cleaner?
00018 // TODO use the information from sdt's ShOperationInfo to decide
00019 // whether to do the ao/bo/co special case for scalar
00020 // ops where we step through the destination tuple but always
00021 // use the same element from the scalar src tuple. 
00022 // macros for componentwise operations
00023 // do a partial specialization on the class
00024 // and define the doop function
00025 //
00026 #define SHCRO_UNARY_OP(op, opsrc)\
00027 template<typename T>\
00028 struct ShConcreteRegularOp<op, T>\
00029 { \
00030   typedef ShDataVariant<T, SH_HOST> Variant; \
00031   typedef Variant* DataPtr; \
00032   typedef const Variant* DataCPtr; \
00033 \
00034   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00035   {\
00036     SH_DEBUG_ASSERT(dest && a);\
00037     int ao = a->size() > 1;\
00038   \
00039     typename Variant::iterator D = dest->begin();\
00040     typename Variant::const_iterator A = a->begin();\
00041     for(; D != dest->end(); A += ao, ++D) {\
00042       (*D) = opsrc;\
00043     }\
00044   } \
00045 };
00046 
00047 #define SHCRO_BINARY_OP(op, opsrc)\
00048 template<typename T>\
00049 struct ShConcreteRegularOp<op, T>\
00050 { \
00051   typedef ShDataVariant<T, SH_HOST> Variant; \
00052   typedef Variant* DataPtr; \
00053   typedef const Variant* DataCPtr; \
00054 \
00055   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00056   {\
00057     SH_DEBUG_ASSERT(dest && a && b);\
00058     int ao = a->size() > 1;\
00059     int bo = b->size() > 1;\
00060   \
00061     typename Variant::iterator D = dest->begin();\
00062     typename Variant::const_iterator A, B;\
00063     A = a->begin();\
00064     B = b->begin();\
00065     for(; D != dest->end(); A += ao, B += bo, ++D) {\
00066       (*D) = opsrc;\
00067     }\
00068   } \
00069 };
00070 
00071 #define SHCRO_TERNARY_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 && c);\
00082     int ao = a->size() > 1;\
00083     int bo = b->size() > 1;\
00084     int co = c->size() > 1;\
00085   \
00086     typename Variant::iterator D = dest->begin();\
00087     typename Variant::const_iterator A, B, C;\
00088     A = a->begin();\
00089     B = b->begin();\
00090     C = c->begin();\
00091     for(; D != dest->end(); A += ao, B += bo, C += co, ++D) {\
00092       (*D) = opsrc;\
00093     }\
00094   }\
00095 };
00096 
00097 // Unary ops
00098 SHCRO_UNARY_OP(SH_OP_ABS, abs(*A));
00099 SHCRO_UNARY_OP(SH_OP_ACOS, acos(*A));
00100 SHCRO_UNARY_OP(SH_OP_ASIN, asin(*A));
00101 SHCRO_UNARY_OP(SH_OP_ASN, (*A));
00102 SHCRO_UNARY_OP(SH_OP_ATAN, atan(*A));
00103 SHCRO_UNARY_OP(SH_OP_CBRT, cbrt(*A));
00104 SHCRO_UNARY_OP(SH_OP_CEIL, ceil(*A));
00105 
00106 template<typename T>
00107 struct ShConcreteRegularOp<SH_OP_CMUL, T>
00108 {
00109   typedef ShDataVariant<T, SH_HOST> Variant; 
00110   typedef Variant* DataPtr; 
00111   typedef const Variant* DataCPtr; 
00112 
00113   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00114   {
00115     // dest->size should be 1 and a->size == b->size
00116     (*dest)[0] = std::accumulate(a->begin(), a->end(), 
00117                       ShDataTypeInfo<T, SH_HOST>::Zero, 
00118                       std::multiplies<typename Variant::DataType>());
00119   }
00120 };
00121 
00122 SHCRO_UNARY_OP(SH_OP_COS, cos(*A));
00123 
00124 template<typename T>
00125 struct ShConcreteRegularOp<SH_OP_CSUM, T>
00126 {
00127   typedef ShDataVariant<T, SH_HOST> Variant; 
00128   typedef Variant* DataPtr; 
00129   typedef const Variant* DataCPtr; 
00130 
00131   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00132   {
00133     // dest->size should be 1 and a->size == b->size
00134     (*dest)[0] = std::accumulate(a->begin(), a->end(), 
00135                       ShDataTypeInfo<T, SH_HOST>::Zero, 
00136                       std::plus<typename Variant::DataType>());
00137   }
00138 };
00139 
00140 SHCRO_UNARY_OP(SH_OP_EXP, exp(*A));
00141 SHCRO_UNARY_OP(SH_OP_EXP2, exp2(*A));
00142 SHCRO_UNARY_OP(SH_OP_EXP10, exp10(*A));
00143 SHCRO_UNARY_OP(SH_OP_FLR, floor(*A));
00144 SHCRO_UNARY_OP(SH_OP_FRAC, frac(*A));
00145 SHCRO_UNARY_OP(SH_OP_LOG, log(*A));
00146 SHCRO_UNARY_OP(SH_OP_LOG2, log(*A));
00147 SHCRO_UNARY_OP(SH_OP_LOG10, log10(*A));
00148 
00149 template<typename T>
00150 struct ShConcreteRegularOp<SH_OP_NORM, 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     SH_DEBUG_ASSERT(dest && a);
00159     typename Variant::DataType m = sqrt(std::inner_product(a->begin(), a->end(), 
00160           a->begin(), ShDataTypeInfo<T, SH_HOST>::Zero));
00161 
00162     typename Variant::iterator D = dest->begin();
00163     typename Variant::const_iterator A = a->begin();
00164     for(; D != dest->end(); ++A, ++D) (*D) = (*A) / m;
00165   }
00166 };
00167 
00168 SHCRO_UNARY_OP(SH_OP_RCP, rcp(*A));
00169 SHCRO_UNARY_OP(SH_OP_RND, rnd(*A));
00170 SHCRO_UNARY_OP(SH_OP_RSQ, rsq(*A));
00171 SHCRO_UNARY_OP(SH_OP_SIN, sin(*A));
00172 SHCRO_UNARY_OP(SH_OP_SGN, sgn(*A)); 
00173 SHCRO_UNARY_OP(SH_OP_SQRT, sqrt(*A)); 
00174 SHCRO_UNARY_OP(SH_OP_TAN, tan(*A)); 
00175 
00176 // Binary ops
00177 SHCRO_BINARY_OP(SH_OP_ADD, (*A) + (*B));
00178 SHCRO_BINARY_OP(SH_OP_ATAN2, atan2((*A), (*B)));
00179 SHCRO_BINARY_OP(SH_OP_DIV, (*A) / (*B));
00180 SHCRO_BINARY_OP(SH_OP_MAX, max((*A), (*B))); 
00181 SHCRO_BINARY_OP(SH_OP_MIN, min((*A), (*B))); 
00182 SHCRO_BINARY_OP(SH_OP_MOD, (*A) % (*B)); 
00183 SHCRO_BINARY_OP(SH_OP_MUL, (*A) * (*B));
00184 SHCRO_BINARY_OP(SH_OP_POW, pow((*A), (*B)));
00185 
00186 template<typename T>
00187 struct ShConcreteRegularOp<SH_OP_DOT, T>
00188 {
00189   typedef ShDataVariant<T, SH_HOST> Variant; 
00190   typedef Variant* DataPtr; 
00191   typedef const Variant* DataCPtr; 
00192 
00193   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00194   {
00195     // dest->size should be 1 and a->size == b->size
00196     (*dest)[0] = std::inner_product(a->begin(), a->end(), b->begin(), 
00197                       ShDataTypeInfo<T, SH_HOST>::Zero);
00198   }
00199 };
00200 
00201 SHCRO_BINARY_OP(SH_OP_SEQ, (*A) == (*B));
00202 SHCRO_BINARY_OP(SH_OP_SGE, (*A) >= (*B));
00203 SHCRO_BINARY_OP(SH_OP_SGT, (*A) > (*B));
00204 SHCRO_BINARY_OP(SH_OP_SLE, (*A) <= (*B));
00205 SHCRO_BINARY_OP(SH_OP_SLT, (*A) < (*B));
00206 SHCRO_BINARY_OP(SH_OP_SNE, (*A) != (*B));
00207 
00208 template<typename T>
00209 struct ShConcreteRegularOp<SH_OP_XPD, T>
00210 {
00211   typedef ShDataVariant<T, SH_HOST> Variant; 
00212   typedef Variant* DataPtr; 
00213   typedef const Variant* DataCPtr; 
00214 
00215   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) 
00216   {
00217     (*dest)[0] = (*a)[1] * (*b)[2] - (*a)[2] * (*b)[1];
00218     (*dest)[1] = -((*a)[0] * (*b)[2] - (*a)[2] * (*b)[0]);
00219     (*dest)[2] = (*a)[0] * (*b)[1] - (*a)[1] * (*b)[0];
00220   }
00221 };
00222 
00223 // Ternary Ops
00224 SHCRO_TERNARY_OP(SH_OP_COND, cond(*A, *B, *C)); 
00225 SHCRO_TERNARY_OP(SH_OP_LRP, lerp(*A, *B, *C));
00226 SHCRO_TERNARY_OP(SH_OP_MAD, (*A) * (*B) + (*C));
00227 
00228 }
00229 #endif

Generated on Mon Jan 24 18:36:31 2005 for Sh by  doxygen 1.4.1