[Beignet] [PATCH 1/2] Handle edge and illegal values.
Yi Sun
yi.sun at intel.com
Thu Aug 8 03:46:52 PDT 2013
Such as |x| = 1.0, |x| < 2**-27 and |x| > 1.
Signed-off-by: Yi Sun <yi.sun at intel.com>
---
backend/src/ocl_stdlib.tmpl.h | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/backend/src/ocl_stdlib.tmpl.h b/backend/src/ocl_stdlib.tmpl.h
index 84f15ca..899a085 100644
--- a/backend/src/ocl_stdlib.tmpl.h
+++ b/backend/src/ocl_stdlib.tmpl.h
@@ -561,7 +561,42 @@ INLINE_OVERLOADABLE float __gen_ocl_internal_tanh(float x) {
float y = native_exp(-2 * x);
return (1 - y) / (1 + y);
}
+
+typedef union
+{
+ float value;
+ int word;
+} ieee_float_shape_type;
+
+#ifndef GET_FLOAT_WORD
+# define GET_FLOAT_WORD(i,d) \
+do { \
+ ieee_float_shape_type gf_u; \
+ gf_u.value = (d); \
+ (i) = gf_u.word; \
+} while (0)
+#endif
+
+const float
+one = 1.0000000000e+00, /* 0x3F800000 */
+huge = 1.000e+30,
+pio2_hi = 1.57079637050628662109375f,
+pio2_lo = -4.37113900018624283e-8f;
+
INLINE_OVERLOADABLE float __gen_ocl_internal_asin(float x) {
+ int hx, ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix == 0x3f800000) {
+ return x*pio2_hi + x*pio2_lo; /* asin(1)=+-pi/2 with inexact */
+ }
+ if(ix > 0x3f800000) { /* |x|>= 1 */
+ return (x-x) / (x-x); /* asin(|x|>1) is NaN */
+ }
+ if(ix < 0x32000000) { /* if |x| < 2**-27 */
+ if(huge + x > one) return x; /* return x with inexact if x!=0*/
+ }
+ /* 1 > |x| >= 2**-27 */
float sum = x, c = x, m = 1.0;
int n = 1;
do
--
1.7.6.4
More information about the Beignet
mailing list