summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrander <rander.wang@intel.com>2017-03-30 15:23:14 +0800
committerYang Rong <rong.r.yang@intel.com>2017-04-17 16:08:48 +0800
commit603bbd9c47186452bc71115e04bb60ac60b35fd6 (patch)
treec2c0f49acb49c00dadc03cebbc4427acd47572af
parent5502b964d6b309172ba852d69f7fab44a1f21018 (diff)
downloadbeignet-603bbd9c47186452bc71115e04bb60ac60b35fd6.tar.gz
backend: add double version of sinpi
it is a simple implementation and need to be refined to pass cft Signed-off-by: rander <rander.wang@intel.com> Tested-by: Yang Rong <rong.r.yang@intel.com>
-rw-r--r--backend/src/libocl/tmpl/ocl_math_common.tmpl.cl49
-rw-r--r--backend/src/libocl/tmpl/ocl_math_common.tmpl.h1
2 files changed, 50 insertions, 0 deletions
diff --git a/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl b/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl
index e6452388..9f36e701 100644
--- a/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl
+++ b/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl
@@ -1777,6 +1777,55 @@ OVERLOADABLE double sinh(double x)
return x*shuge;
}
+OVERLOADABLE double sinpi(double x)
+{
+ double zero= 0.00000000000000000000e+00,
+ two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+ halfD= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+ one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+ pi = 3.141592653589793238462e+00; /* 0x400921FB, 0x54442D18 */
+
+ double y,z;
+ int n,ix;
+
+ ix = 0x7fffffff&__HI(x);
+
+ if(ix<0x3fd00000) return __kernel_sin(pi*x,zero,0);
+ y = -x; /* x is assume negative */
+
+ if(ix >=0x7ff00000)return NAN;
+ /*
+ * argument reduction, make sure inexact flag not raised if input
+ * is an integer
+ */
+ z = floor(y);
+ if(z!=y) { /* inexact anyway */
+ y *= 0.5;
+ y = 2.0*(y - floor(y)); /* y = |x| mod 2.0 */
+ n = (int) (y*4.0);
+ } else {
+ if(ix>=0x43400000) {
+ y = zero; n = 0; /* y must be even */
+ } else {
+ if(ix<0x43300000) z = y+two52; /* exact */
+ n = __LO(z)&1; /* lower word of z */
+ y = n;
+ n<<= 2;
+ }
+ }
+ switch (n) {
+ case 0: y = __kernel_sin(pi*y,zero,0); break;
+ case 1:
+ case 2: y = __kernel_cos(pi*(0.5-y),zero); break;
+ case 3:
+ case 4: y = __kernel_sin(pi*(one-y),zero,0); break;
+ case 5:
+ case 6: y = -__kernel_cos(pi*(y-1.5),zero); break;
+ default: y = __kernel_sin(pi*(y-2.0),zero,0); break;
+ }
+ return -y;
+}
+
OVERLOADABLE double sqrt(double x)
{
double z;
diff --git a/backend/src/libocl/tmpl/ocl_math_common.tmpl.h b/backend/src/libocl/tmpl/ocl_math_common.tmpl.h
index 5f703f38..4401308a 100644
--- a/backend/src/libocl/tmpl/ocl_math_common.tmpl.h
+++ b/backend/src/libocl/tmpl/ocl_math_common.tmpl.h
@@ -57,6 +57,7 @@ OVERLOADABLE double rint(double x);
OVERLOADABLE double round(double x);
OVERLOADABLE double sin(double x);
OVERLOADABLE double sinh(double x);
+OVERLOADABLE double sinpi(double x);
OVERLOADABLE double sqrt(double x);
OVERLOADABLE double tan(double x);
OVERLOADABLE double tanh(double x);