[Beignet] [PATCH] backend:add double support to round
rander
rander.wang at intel.com
Tue Mar 28 01:48:19 UTC 2017
do it as spec:Return the integral value nearest to x rounding
halfway cases away from zero, regardless of the current rounding
direction. for round(1.5) = 2, round(1.49) = 1:
Signed-off-by: rander <rander.wang at intel.com>
---
backend/src/libocl/tmpl/ocl_math.tmpl.cl | 37 +++++++++++++++++++++++++++++
backend/src/libocl/tmpl/ocl_math.tmpl.h | 1 +
backend/src/libocl/tmpl/ocl_math_20.tmpl.cl | 37 +++++++++++++++++++++++++++++
backend/src/libocl/tmpl/ocl_math_20.tmpl.h | 1 +
4 files changed, 76 insertions(+)
diff --git a/backend/src/libocl/tmpl/ocl_math.tmpl.cl b/backend/src/libocl/tmpl/ocl_math.tmpl.cl
index f7d599d..b5917f7 100644
--- a/backend/src/libocl/tmpl/ocl_math.tmpl.cl
+++ b/backend/src/libocl/tmpl/ocl_math.tmpl.cl
@@ -4403,6 +4403,43 @@ OVERLOADABLE double fmin(double a, double b)
return (c <= 0) ? a:b;
}
+OVERLOADABLE double round(double x)
+{
+ long ret;
+ long lval = as_long(x);
+ int exp = ((lval & DF_EXP_MASK) >> DF_EXP_OFFSET) - DF_EXP_BIAS;
+ long sign = (lval & DF_SIGN_MASK)?1:0;
+ long ma = (lval &DF_MAN_MASK);
+
+ if((lval & DF_ABS_MASK) == 0)
+ return as_double(sign << 63);
+
+ if(exp < -1)
+ {
+ ret = ((sign << 63)) ;
+ return as_double(ret);
+ }
+
+ if(exp > 51) return x;
+
+ long i = (1L << (52 - exp));
+ i = 0x10000000000000 - i;
+ unsigned long uv = 0xFFF0000000000000 + i;
+ ulong vv = lval & uv;
+ double dp = as_double(vv);
+ if(exp == -1) dp = 0;
+
+ long fval = ma | DF_IMPLICITE_ONE;
+ long roundBits = (fval & ( (1L << (52 -exp)) -1));
+
+ if(roundBits > (1L << (51 -exp)))
+ dp = (sign) ? dp-1.0:dp+1.0;
+ else if(roundBits == (1L << (51 -exp)))
+ dp = (sign) ? dp-1.0:dp+1.0;
+
+ return dp;
+}
+
OVERLOADABLE double trunc(double x)
{
double ret = floor(fabs(x));
diff --git a/backend/src/libocl/tmpl/ocl_math.tmpl.h b/backend/src/libocl/tmpl/ocl_math.tmpl.h
index 8318085..86e365f 100644
--- a/backend/src/libocl/tmpl/ocl_math.tmpl.h
+++ b/backend/src/libocl/tmpl/ocl_math.tmpl.h
@@ -253,6 +253,7 @@ OVERLOADABLE double log1p(double x);
OVERLOADABLE double logb(double x);
OVERLOADABLE int ilogb(double x);
OVERLOADABLE double mad(double a, double b, double c);
+OVERLOADABLE double round(double x);
OVERLOADABLE double trunc(double x);
diff --git a/backend/src/libocl/tmpl/ocl_math_20.tmpl.cl b/backend/src/libocl/tmpl/ocl_math_20.tmpl.cl
index 941127f..8e8e5d4 100644
--- a/backend/src/libocl/tmpl/ocl_math_20.tmpl.cl
+++ b/backend/src/libocl/tmpl/ocl_math_20.tmpl.cl
@@ -4279,6 +4279,43 @@ OVERLOADABLE double fmin(double a, double b)
return (c <= 0) ? a:b;
}
+OVERLOADABLE double round(double x)
+{
+ long ret;
+ long lval = as_long(x);
+ int exp = ((lval & DF_EXP_MASK) >> DF_EXP_OFFSET) - DF_EXP_BIAS;
+ long sign = (lval & DF_SIGN_MASK)?1:0;
+ long ma = (lval &DF_MAN_MASK);
+
+ if((lval & DF_ABS_MASK) == 0)
+ return as_double(sign << 63);
+
+ if(exp < -1)
+ {
+ ret = ((sign << 63)) ;
+ return as_double(ret);
+ }
+
+ if(exp > 51) return x;
+
+ long i = (1L << (52 - exp));
+ i = 0x10000000000000 - i;
+ unsigned long uv = 0xFFF0000000000000 + i;
+ ulong vv = lval & uv;
+ double dp = as_double(vv);
+ if(exp == -1) dp = 0;
+
+ long fval = ma | DF_IMPLICITE_ONE;
+ long roundBits = (fval & ( (1L << (52 -exp)) -1));
+
+ if(roundBits > (1L << (51 -exp)))
+ dp = (sign) ? dp-1.0:dp+1.0;
+ else if(roundBits == (1L << (51 -exp)))
+ dp = (sign) ? dp-1.0:dp+1.0;
+
+ return dp;
+}
+
OVERLOADABLE double trunc(double x)
{
double ret = floor(fabs(x));
diff --git a/backend/src/libocl/tmpl/ocl_math_20.tmpl.h b/backend/src/libocl/tmpl/ocl_math_20.tmpl.h
index 34e29e0..cdf8d69 100644
--- a/backend/src/libocl/tmpl/ocl_math_20.tmpl.h
+++ b/backend/src/libocl/tmpl/ocl_math_20.tmpl.h
@@ -230,6 +230,7 @@ OVERLOADABLE double log1p(double x);
OVERLOADABLE double logb(double x);
OVERLOADABLE int ilogb(double x);
OVERLOADABLE double mad(double a, double b, double c);
+OVERLOADABLE double round(double x);
OVERLOADABLE double trunc(double x);
--
2.7.4
More information about the Beignet
mailing list