ShConcreteCTypeOp.cpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright 2003-2006 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 #include <cmath>
00021 #include "ShMath.hpp"
00022 #include <numeric>
00023 #include "ShOperation.hpp"
00024 #include "ShEval.hpp"
00025 
00026 namespace SH {
00027 
00028   // TODO some of these specializations don't need to be in the cpp
00029   // since they work for most things...
00030 
00031 /**************************************************************
00032  *** Use Specialization to define particular ops 
00033  **************************************************************/
00034 #define SHCCTO_UNARY_OP_SPEC_TMPL(T, op, opsrc)\
00035 template<>\
00036 SHCCTO_UNARY_OP_SPEC(T, op, opsrc)
00037 
00038 #define SHCCTO_UNARY_OP_SPEC(T, op, opsrc)\
00039 void ShConcreteCTypeOp<op, T>::doop(DataPtr dest, DataCPtr a, DataCPtr b, DataCPtr c) \
00040 {\
00041   int ao = a->size() > 1;\
00042 \
00043   Variant::iterator D = dest->begin();\
00044   Variant::const_iterator A = a->begin();\
00045   for(; D != dest->end(); A += ao, ++D) {\
00046     (*D) = opsrc;\
00047   }\
00048 }\
00049 
00050 #define SHCCTO_BINARY_OP_SPEC(T, op, opsrc)\
00051 void ShConcreteCTypeOp<op, T>::doop(DataPtr dest, DataCPtr a, DataCPtr b, DataCPtr c) \
00052 {\
00053   int ao = a->size() > 1;\
00054   int bo = b->size() > 1;\
00055 \
00056   Variant::iterator D = dest->begin();\
00057   Variant::const_iterator A, B;\
00058   A = a->begin();\
00059   B = b->begin();\
00060   for(; D != dest->end(); A += ao, B += bo, ++D) {\
00061     (*D) = opsrc;\
00062   }\
00063 }
00064 
00065 #define SHCCTO_TERNARY_OP_SPEC(T, op, opsrc)\
00066 void ShConcreteCTypeOp<op, T>::doop(DataPtr dest, DataCPtr a, DataCPtr b, DataCPtr c) \
00067 {\
00068   int ao = a->size() > 1;\
00069   int bo = b->size() > 1;\
00070   int co = c->size() > 1;\
00071 \
00072   Variant::iterator D = dest->begin();\
00073   Variant::const_iterator A, B, C;\
00074   A = a->begin();\
00075   B = b->begin();\
00076   C = c->begin();\
00077   for(; D != dest->end(); A += ao, B += bo, C += co, ++D) {\
00078     (*D) = opsrc;\
00079   }\
00080 }   
00081 
00082 /* Specializations for unary ops */
00083 SHCCTO_UNARY_OP_SPEC_TMPL(double, SH_OP_ABS, std::fabs(*A));
00084 SHCCTO_UNARY_OP_SPEC_TMPL(float,  SH_OP_ABS, fabsf(*A));
00085 SHCCTO_UNARY_OP_SPEC(double, SH_OP_ACOS, std::acos(*A));
00086 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_ACOS, acosf(*A));
00087 SHCCTO_UNARY_OP_SPEC(double, SH_OP_ASIN, std::asin(*A));
00088 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_ASIN, asinf(*A));
00089 SHCCTO_UNARY_OP_SPEC(double, SH_OP_ATAN, std::atan(*A));
00090 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_ATAN, atanf(*A));
00091 SHCCTO_UNARY_OP_SPEC(double, SH_OP_CBRT, std::pow(*A, 1.0 / 3.0));
00092 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_CBRT, powf(*A, 1.0f / 3.0f));
00093 SHCCTO_UNARY_OP_SPEC(double, SH_OP_CEIL, std::ceil(*A));
00094 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_CEIL, ceilf(*A));
00095 SHCCTO_UNARY_OP_SPEC(double, SH_OP_COS, std::cos(*A));
00096 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_COS, cosf(*A));
00097 SHCCTO_UNARY_OP_SPEC_TMPL(double, SH_OP_COSH, std::cosh(*A));
00098 SHCCTO_UNARY_OP_SPEC_TMPL(float,  SH_OP_COSH, coshf(*A));
00099 SHCCTO_UNARY_OP_SPEC(double, SH_OP_EXP, std::exp(*A));
00100 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_EXP, expf(*A));
00101 SHCCTO_UNARY_OP_SPEC(double, SH_OP_EXP2, std::pow(2.0, *A));
00102 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_EXP2, powf(2.0f, *A));
00103 SHCCTO_UNARY_OP_SPEC(double, SH_OP_EXP10, std::pow(10.0, *A));
00104 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_EXP10, powf(10.0f, *A));
00105 SHCCTO_UNARY_OP_SPEC(double, SH_OP_FLR, std::floor(*A));
00106 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_FLR, floorf(*A));
00107 SHCCTO_UNARY_OP_SPEC(double, SH_OP_FRAC, (*A) - std::floor(*A));
00108 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_FRAC, (*A) - floorf(*A));
00109 SHCCTO_UNARY_OP_SPEC(double, SH_OP_LOG, std::log(*A)); 
00110 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_LOG, logf(*A)); 
00111 SHCCTO_UNARY_OP_SPEC(double, SH_OP_LOG2, std::log(*A) / std::log(2.0)); 
00112 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_LOG2, log2f(*A) / log2f(2.0f)); 
00113 SHCCTO_UNARY_OP_SPEC(double, SH_OP_LOG10, std::log(*A) / std::log(10.0)); 
00114 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_LOG10, logf(*A) / logf(10.0f)); 
00115 
00116 #ifdef _WIN32
00117 SHCCTO_UNARY_OP_SPEC(double, SH_OP_ACOSH, std::log((*A) + std::sqrt((*A) * (*A) - 1)));
00118 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_ACOSH, logf((*A) + sqrtf((*A) * (*A) - 1)));
00119 SHCCTO_UNARY_OP_SPEC(double, SH_OP_ASINH, std::log((*A) + std::sqrt((*A) * (*A) + 1)));
00120 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_ASINH, logf((*A) + sqrtf((*A) * (*A) + 1)));
00121 SHCCTO_UNARY_OP_SPEC(double, SH_OP_ATANH, std::log((1.0 + (*A))/(1.0 - (*A)))/2.0);
00122 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_ATANH, logf((1.0 + (*A))/(1.0 - (*A)))/2.0);
00123 #else
00124 SHCCTO_UNARY_OP_SPEC(double, SH_OP_ACOSH, acosh(*A));
00125 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_ACOSH, acoshf(*A));
00126 SHCCTO_UNARY_OP_SPEC(double, SH_OP_ASINH, asinh(*A));
00127 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_ASINH, asinhf(*A));
00128 SHCCTO_UNARY_OP_SPEC(double, SH_OP_ATANH, atanh(*A));
00129 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_ATANH, atanhf(*A));
00130 #endif
00131 
00132 void ShConcreteCTypeOp<SH_OP_NORM, double>::doop(DataPtr dest, DataCPtr a, DataCPtr b, DataCPtr c) 
00133 {
00134   // assume dest.size == a->size 
00135   double m = std::sqrt(std::inner_product(a->begin(), a->end(), a->begin(), 0.0));
00136 
00137   Variant::const_iterator A = a->begin();
00138   Variant::iterator D = dest->begin();
00139   for(; A != a->end(); ++D, ++A) (*D) = (*A) / m; 
00140 }
00141 
00142 
00143 void ShConcreteCTypeOp<SH_OP_NORM, float>::doop(DataPtr dest, DataCPtr a, DataCPtr b, DataCPtr c) 
00144 {
00145   // assume dest.size == a->size 
00146   float m = std::sqrt(std::inner_product(a->begin(), a->end(), a->begin(), 0.0f));
00147 
00148   Variant::const_iterator A = a->begin();
00149   Variant::iterator D = dest->begin();
00150   for(; A != a->end(); ++D, ++A) (*D) = (*A) / m; 
00151 }
00152 
00153 SHCCTO_UNARY_OP_SPEC_TMPL(double, SH_OP_RCP, 1.0 / (*A)); 
00154 SHCCTO_UNARY_OP_SPEC_TMPL(float,  SH_OP_RCP, 1.0f / (*A)); 
00155 SHCCTO_UNARY_OP_SPEC(double, SH_OP_RND, std::floor(*A + 0.5)); 
00156 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_RND, floorf(*A + 0.5f)); 
00157 SHCCTO_UNARY_OP_SPEC(double, SH_OP_RSQ, 1.0 / std::sqrt(*A)); 
00158 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_RSQ, 1.0f / sqrtf(*A)); 
00159 SHCCTO_UNARY_OP_SPEC_TMPL(double, SH_OP_SGN, ((*A) < 0 ? -1 : (*A) > 0 ? 1 : 0)); 
00160 SHCCTO_UNARY_OP_SPEC_TMPL(float , SH_OP_SGN, ((*A) < 0 ? -1 : (*A) > 0 ? 1 : 0)); 
00161 SHCCTO_UNARY_OP_SPEC(double, SH_OP_SIN, std::sin(*A)); 
00162 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_SIN, sinf(*A)); 
00163 SHCCTO_UNARY_OP_SPEC_TMPL(double, SH_OP_SINH, std::sinh(*A)); 
00164 SHCCTO_UNARY_OP_SPEC_TMPL(float,  SH_OP_SINH, sinhf(*A)); 
00165 SHCCTO_UNARY_OP_SPEC(double, SH_OP_SQRT, std::sqrt(*A)); 
00166 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_SQRT, sqrtf(*A)); 
00167 SHCCTO_UNARY_OP_SPEC(double, SH_OP_TAN, std::tan(*A)); 
00168 SHCCTO_UNARY_OP_SPEC(float,  SH_OP_TAN, tanf(*A)); 
00169 SHCCTO_UNARY_OP_SPEC_TMPL(double, SH_OP_TANH, std::tanh(*A)); 
00170 SHCCTO_UNARY_OP_SPEC_TMPL(float,  SH_OP_TANH, tanhf(*A)); 
00171 
00172 /* Specializations for binary ops */
00173 SHCCTO_BINARY_OP_SPEC(double, SH_OP_ATAN2, std::atan2((*A), (*B)));
00174 SHCCTO_BINARY_OP_SPEC(float,  SH_OP_ATAN2, atan2f((*A), (*B)));
00175 
00176 
00177 // Binary Ops
00178 SHCCTO_BINARY_OP_SPEC(double, SH_OP_MOD, ((*A) - (*B) * std::floor((*A) / (*B)))); 
00179 SHCCTO_BINARY_OP_SPEC(float,  SH_OP_MOD, ((*A) - (*B) * floorf((*A) / (*B)))); 
00180 SHCCTO_BINARY_OP_SPEC(double, SH_OP_POW, std::pow((*A), (*B))); 
00181 SHCCTO_BINARY_OP_SPEC(float,  SH_OP_POW, powf((*A), (*B))); 
00182 
00183 }

Generated on Thu Feb 16 14:51:31 2006 for Sh by  doxygen 1.4.6