[Beignet] [PATCH] backend: add double support to rint

rander rander.wang at intel.com
Tue Mar 28 01:53:08 UTC 2017


	spec:Round to integral value (using round to nearest
	even rounding mode) in floating-point format.
	it is similar to round, but it is round to even
	rint(0x1.1p0) = 2, rint(0x0.1p0) = 0

Signed-off-by: rander <rander.wang at intel.com>
---
 backend/src/libocl/tmpl/ocl_math.tmpl.cl    | 38 +++++++++++++++++++++++++++++
 backend/src/libocl/tmpl/ocl_math.tmpl.h     |  1 +
 backend/src/libocl/tmpl/ocl_math_20.tmpl.cl | 38 +++++++++++++++++++++++++++++
 backend/src/libocl/tmpl/ocl_math_20.tmpl.h  |  1 +
 4 files changed, 78 insertions(+)

diff --git a/backend/src/libocl/tmpl/ocl_math.tmpl.cl b/backend/src/libocl/tmpl/ocl_math.tmpl.cl
index b5917f7..c9e5219 100644
--- a/backend/src/libocl/tmpl/ocl_math.tmpl.cl
+++ b/backend/src/libocl/tmpl/ocl_math.tmpl.cl
@@ -4403,6 +4403,44 @@ OVERLOADABLE double fmin(double a, double b)
 	return (c <= 0) ? a:b;
 }
 
+OVERLOADABLE double rint(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 lastBit = (fval & (1L << (52 -exp)));
+	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))) && lastBit)
+		dp = (sign) ? dp-1.0:dp+1.0;
+
+	return dp;
+}
+
 OVERLOADABLE double round(double x)
 {
 	long ret;
diff --git a/backend/src/libocl/tmpl/ocl_math.tmpl.h b/backend/src/libocl/tmpl/ocl_math.tmpl.h
index 86e365f..de40d5d 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 rint(double x);
 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 8e8e5d4..0861f5a 100644
--- a/backend/src/libocl/tmpl/ocl_math_20.tmpl.cl
+++ b/backend/src/libocl/tmpl/ocl_math_20.tmpl.cl
@@ -4279,6 +4279,44 @@ OVERLOADABLE double fmin(double a, double b)
 	return (c <= 0) ? a:b;
 }
 
+OVERLOADABLE double rint(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 lastBit = (fval & (1L << (52 -exp)));
+	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))) && lastBit)
+		dp = (sign) ? dp-1.0:dp+1.0;
+
+	return dp;
+}
+
 OVERLOADABLE double round(double x)
 {
 	long ret;
diff --git a/backend/src/libocl/tmpl/ocl_math_20.tmpl.h b/backend/src/libocl/tmpl/ocl_math_20.tmpl.h
index cdf8d69..597f491 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 rint(double x);
 OVERLOADABLE double round(double x);
 OVERLOADABLE double trunc(double x);
 
-- 
2.7.4



More information about the Beignet mailing list