[Beignet] [PATCH 1/2] Add 14 built-in functions

Xing, Homer homer.xing at intel.com
Wed May 15 17:39:19 PDT 2013


Yes, you are right. 

When |x|>1, the series does not converge.

I will publish a newer version.

Best regards,
Homer


-----Original Message-----
From: Feng, Boqun 
Sent: Wednesday, May 15, 2013 5:16 PM
To: Xing, Homer
Cc: beignet at lists.freedesktop.org
Subject: Re: [Beignet] [PATCH 1/2] Add 14 built-in functions

Hi Homer,
  I git am your patchset from "Enable cospi, cbrt, tan" and run the
  test.
  
  I test is on my machine, and I got "compiler_math_2op" failed, and I
  found it's caused by atan2, maybe this is because the taylor series
  your use.

  According to http://en.wikipedia.org/wiki/Taylor_series, the taylor
  series for arctan is only for |x| <= 1, and when |x| > 1 , we need to
  transform arctan(x) to PI/2 * sgn(x) - arctan(1/x) to use taylor
  series, where sgn(x) is 1 if x > 0 and -1 if x < 0

Thx,
Boqun

On Wed, May 15, 2013 at 02:33:09PM +0800, Homer Hsing wrote:
> Implemented sincos, asin, asinpi, acos, acospi, atan, atanpi, atan2,
>             atan2pi, copysign, erf, erfc, maxmag, minmag.
> 
> Signed-off-by: Homer Hsing <homer.xing at intel.com>
> ---
>  backend/src/ocl_stdlib.h | 149 
> ++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 148 insertions(+), 1 deletion(-)
> 
> diff --git a/backend/src/ocl_stdlib.h b/backend/src/ocl_stdlib.h index 
> 0ebc059..b444114 100644
> --- a/backend/src/ocl_stdlib.h
> +++ b/backend/src/ocl_stdlib.h
> @@ -429,6 +429,48 @@ INLINE OVERLOADABLE float 
> __gen_ocl_internal_expm1(float x) { return __gen_ocl_p  INLINE OVERLOADABLE float __gen_ocl_internal_cbrt(float x) {
>    return __gen_ocl_pow(x, 0.3333333333f);  }
> +INLINE OVERLOADABLE float __gen_ocl_internal_sincos(float x, float 
> +*cosval) {
> +  *cosval = native_cos(x);
> +  return native_sin(x);
> +}
> +INLINE OVERLOADABLE float2 __gen_ocl_internal_sincos(float2 x, float2 
> +*cosval) {
> +  return (float2)(__gen_ocl_internal_sincos(x.s0, (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s1, 1 + (float 
> +*)cosval)); } INLINE OVERLOADABLE float4 
> +__gen_ocl_internal_sincos(float4 x, float4 *cosval) {
> +  return (float4)(__gen_ocl_internal_sincos(x.s0, (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s1, 1 + (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s2, 2 + (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s3, 3 + (float 
> +*)cosval)); } INLINE OVERLOADABLE float8 
> +__gen_ocl_internal_sincos(float8 x, float8 *cosval) {
> +  return (float8)(__gen_ocl_internal_sincos(x.s0, (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s1, 1 + (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s2, 2 + (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s3, 3 + (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s4, 4 + (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s5, 5 + (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s6, 6 + (float *)cosval),
> +                  __gen_ocl_internal_sincos(x.s7, 7 + (float 
> +*)cosval)); } INLINE OVERLOADABLE float16 
> +__gen_ocl_internal_sincos(float16 x, float16 *cosval) {
> +  return (float16)(__gen_ocl_internal_sincos(x.s0, (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.s1, 1 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.s2, 2 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.s3, 3 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.s4, 4 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.s5, 5 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.s6, 6 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.s7, 7 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.s8, 8 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.s9, 9 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.sa, 10 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.sb, 11 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.sc, 12 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.sd, 13 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.se, 14 + (float *)cosval),
> +                   __gen_ocl_internal_sincos(x.sf, 15 + (float 
> +*)cosval)); }
>  INLINE OVERLOADABLE float __gen_ocl_internal_sinh(float x) {
>    return (1 - native_exp(-2 * x)) / (2 * native_exp(-x));  } @@ 
> -439,6 +481,30 @@ INLINE OVERLOADABLE float __gen_ocl_internal_tanh(float x) {
>    float y = native_exp(-2 * x);
>    return (1 - y) / (1 + y);
>  }
> +INLINE OVERLOADABLE float __gen_ocl_internal_asin(float x) {
> +  return x + __gen_ocl_pow(x, 3) / 6 + __gen_ocl_pow(x, 5) * 3 / 40 + 
> +__gen_ocl_pow(x, 7) * 5 / 112; } INLINE OVERLOADABLE float 
> +__gen_ocl_internal_asinpi(float x) {
> +  return __gen_ocl_internal_asin(x) / M_PI_F; } INLINE OVERLOADABLE 
> +float __gen_ocl_internal_acos(float x) {
> +  return M_PI_2_F - __gen_ocl_internal_asin(x); } INLINE OVERLOADABLE 
> +float __gen_ocl_internal_acospi(float x) {
> +  return __gen_ocl_internal_acos(x) / M_PI_F; } INLINE OVERLOADABLE 
> +float __gen_ocl_internal_atan(float x) {
> +  return x - __gen_ocl_pow(x, 3) / 3 + __gen_ocl_pow(x, 5) / 5 - 
> +__gen_ocl_pow(x, 7) / 7 + __gen_ocl_pow(x, 9) / 9; } INLINE 
> +OVERLOADABLE float __gen_ocl_internal_atanpi(float x) {
> +  return __gen_ocl_internal_atan(x) / M_PI_F; } INLINE OVERLOADABLE 
> +float __gen_ocl_internal_atan2(float y, float x) {
> +  return __gen_ocl_internal_atan(y / x); } INLINE OVERLOADABLE float 
> +__gen_ocl_internal_atan2pi(float y, float x) {
> +  return __gen_ocl_internal_atan2(y, x) / M_PI_F; }
>  INLINE OVERLOADABLE float __gen_ocl_internal_asinh(float x) {
>    return native_log(x + native_sqrt(x * x + 1));  } @@ -448,6 +514,15 
> @@ INLINE OVERLOADABLE float __gen_ocl_internal_acosh(float x) {  
> INLINE OVERLOADABLE float __gen_ocl_internal_atanh(float x) {
>    return 0.5f * native_sqrt((1 + x) / (1 - x));  }
> +INLINE OVERLOADABLE float __gen_ocl_internal_copysign(float x, float 
> +y) {
> +  return x * y < 0 ? -x : x;
> +}
> +INLINE OVERLOADABLE float __gen_ocl_internal_erf(float x) {
> +  return M_2_SQRTPI_F * (x - __gen_ocl_pow(x, 3) / 3 + 
> +__gen_ocl_pow(x, 5) / 10 - __gen_ocl_pow(x, 7) / 42 + 
> +__gen_ocl_pow(x, 9) / 216); } INLINE OVERLOADABLE float 
> +__gen_ocl_internal_erfc(float x) {
> +  return 1 - __gen_ocl_internal_erf(x); }
>  
>  // XXX work-around PTX profile
>  #define sqrt native_sqrt
> @@ -467,23 +542,34 @@ INLINE OVERLOADABLE float remainder(float x, 
> float y) { return x-y*__gen_ocl_rnd  INLINE OVERLOADABLE float __gen_ocl_internal_rint(float x) {
>    return 2 * __gen_ocl_internal_round(x / 2);  }
> -
>  // TODO use llvm intrinsics definitions  #define cos native_cos  
> #define cospi __gen_ocl_internal_cospi  #define cosh 
> __gen_ocl_internal_cosh
> +#define acos __gen_ocl_internal_acos
> +#define acospi __gen_ocl_internal_acospi
>  #define acosh __gen_ocl_internal_acosh  #define sin native_sin  
> #define sinpi __gen_ocl_internal_sinpi  #define sinh 
> __gen_ocl_internal_sinh
> +#define sincos __gen_ocl_internal_sincos #define asin 
> +__gen_ocl_internal_asin #define asinpi __gen_ocl_internal_asinpi
>  #define asinh __gen_ocl_internal_asinh  #define tan native_tan  
> #define tanpi __gen_ocl_internal_tanpi  #define tanh 
> __gen_ocl_internal_tanh
> +#define atan __gen_ocl_internal_atan
> +#define atanpi __gen_ocl_internal_atanpi
>  #define atanh __gen_ocl_internal_atanh
> +#define atan2 __gen_ocl_internal_atan2 #define atan2pi 
> +__gen_ocl_internal_atan2pi
>  #define pow powr
>  #define cbrt __gen_ocl_internal_cbrt
>  #define rint __gen_ocl_internal_rint
> +#define copysign __gen_ocl_internal_copysign #define erf 
> +__gen_ocl_internal_erf #define erfc __gen_ocl_internal_erfc
>  
>  INLINE OVERLOADABLE float mad(float a, float b, float c) {
>    return a*b+c;
> @@ -553,6 +639,14 @@ DECL_MIN_MAX(unsigned char)
>  
>  INLINE OVERLOADABLE float __gen_ocl_internal_fmax(float a, float b) { 
> return max(a,b); }  INLINE OVERLOADABLE float 
> __gen_ocl_internal_fmin(float a, float b) { return min(a,b); }
> +INLINE OVERLOADABLE float __gen_ocl_internal_maxmag(float x, float y) 
> +{
> +  float a = __gen_ocl_fabs(x), b = __gen_ocl_fabs(y);
> +  return a > b ? x : b > a ? y : max(x, y); } INLINE OVERLOADABLE 
> +float __gen_ocl_internal_minmag(float x, float y) {
> +  float a = __gen_ocl_fabs(x), b = __gen_ocl_fabs(y);
> +  return a < b ? x : b < a ? y : min(x, y); }
>  INLINE OVERLOADABLE float mix(float x, float y, float a) { return x + 
> (y-x)*a;}  INLINE OVERLOADABLE float __gen_ocl_internal_fdim(float x, float y) {
>    return __gen_ocl_internal_fmax(x, y) - y; @@ -561,6 +655,44 @@ 
> INLINE OVERLOADABLE float fract(float x, float *p) {
>    *p = __gen_ocl_internal_floor(x);
>    return __gen_ocl_internal_fmin(x - *p, 0x1.FFFFFep-1F);  }
> +INLINE OVERLOADABLE float2 fract(float2 x, float2 *p) {
> +  return (float2)(fract(x.s0, (float *)p),
> +                  fract(x.s1, 1 + (float *)p)); } INLINE OVERLOADABLE 
> +float4 fract(float4 x, float4 *p) {
> +  return (float4)(fract(x.s0, (float *)p),
> +                  fract(x.s1, 1 + (float *)p),
> +                  fract(x.s2, 2 + (float *)p),
> +                  fract(x.s3, 3 + (float *)p)); } INLINE OVERLOADABLE 
> +float8 fract(float8 x, float8 *p) {
> +  return (float8)(fract(x.s0, (float *)p),
> +                  fract(x.s1, 1 + (float *)p),
> +                  fract(x.s2, 2 + (float *)p),
> +                  fract(x.s3, 3 + (float *)p),
> +                  fract(x.s4, 4 + (float *)p),
> +                  fract(x.s5, 5 + (float *)p),
> +                  fract(x.s6, 6 + (float *)p),
> +                  fract(x.s7, 7 + (float *)p)); } INLINE OVERLOADABLE 
> +float16 fract(float16 x, float16 *p) {
> +  return (float16)(fract(x.s0, (float *)p),
> +                   fract(x.s1, 1 + (float *)p),
> +                   fract(x.s2, 2 + (float *)p),
> +                   fract(x.s3, 3 + (float *)p),
> +                   fract(x.s4, 4 + (float *)p),
> +                   fract(x.s5, 5 + (float *)p),
> +                   fract(x.s6, 6 + (float *)p),
> +                   fract(x.s7, 7 + (float *)p),
> +                   fract(x.s8, 8 + (float *)p),
> +                   fract(x.s9, 9 + (float *)p),
> +                   fract(x.sa, 10 + (float *)p),
> +                   fract(x.sb, 11 + (float *)p),
> +                   fract(x.sc, 12 + (float *)p),
> +                   fract(x.sd, 13 + (float *)p),
> +                   fract(x.se, 14 + (float *)p),
> +                   fract(x.sf, 15 + (float *)p)); }
>  INLINE OVERLOADABLE float native_divide(float x, float y) { return 
> x/y; }  INLINE OVERLOADABLE float ldexp(float x, int n) {
>    return __gen_ocl_pow(2, n) * x;
> @@ -711,14 +843,20 @@ DECL_UNTYPED_RW_ALL(float)  
> DECL_VECTOR_1OP(native_cos, float);  
> DECL_VECTOR_1OP(__gen_ocl_internal_cospi, float);  
> DECL_VECTOR_1OP(__gen_ocl_internal_cosh, float);
> +DECL_VECTOR_1OP(__gen_ocl_internal_acos, float); 
> +DECL_VECTOR_1OP(__gen_ocl_internal_acospi, float);
>  DECL_VECTOR_1OP(__gen_ocl_internal_acosh, float);  
> DECL_VECTOR_1OP(native_sin, float);  
> DECL_VECTOR_1OP(__gen_ocl_internal_sinpi, float);  
> DECL_VECTOR_1OP(__gen_ocl_internal_sinh, float);
> +DECL_VECTOR_1OP(__gen_ocl_internal_asin, float); 
> +DECL_VECTOR_1OP(__gen_ocl_internal_asinpi, float);
>  DECL_VECTOR_1OP(__gen_ocl_internal_asinh, float);  
> DECL_VECTOR_1OP(native_tan, float);  
> DECL_VECTOR_1OP(__gen_ocl_internal_tanpi, float);  
> DECL_VECTOR_1OP(__gen_ocl_internal_tanh, float);
> +DECL_VECTOR_1OP(__gen_ocl_internal_atan, float); 
> +DECL_VECTOR_1OP(__gen_ocl_internal_atanpi, float);
>  DECL_VECTOR_1OP(__gen_ocl_internal_atanh, float);  
> DECL_VECTOR_1OP(native_sqrt, float);  DECL_VECTOR_1OP(native_rsqrt, 
> float); @@ -739,6 +877,8 @@ DECL_VECTOR_1OP(__gen_ocl_internal_log, 
> float);  DECL_VECTOR_1OP(__gen_ocl_internal_log2, float);  
> DECL_VECTOR_1OP(__gen_ocl_internal_log10, float);  
> DECL_VECTOR_1OP(__gen_ocl_internal_rint, float);
> +DECL_VECTOR_1OP(__gen_ocl_internal_erf, float); 
> +DECL_VECTOR_1OP(__gen_ocl_internal_erfc, float);
>  #undef DECL_VECTOR_1OP
>  
> //////////////////////////////////////////////////////////////////////
> ///////
>  // Arithmetic functions
> @@ -766,6 +906,8 @@ DECL_VECTOR_1OP(__gen_ocl_internal_rint, float);
>      dst.s89abcdef = NAME(v0.s89abcdef, v1.s89abcdef);\
>      return dst;\
>    }
> +DECL_VECTOR_2OP(atan2, float);
> +DECL_VECTOR_2OP(atan2pi, float);
>  DECL_VECTOR_2OP(hypot, float);
>  DECL_VECTOR_2OP(min, float);
>  DECL_VECTOR_2OP(max, float);
> @@ -776,6 +918,9 @@ DECL_VECTOR_2OP(fmod, float);  
> DECL_VECTOR_2OP(remainder, float);  DECL_VECTOR_2OP(powr, float);  
> DECL_VECTOR_2OP(native_divide, float);
> +DECL_VECTOR_2OP(copysign, float);
> +DECL_VECTOR_2OP(__gen_ocl_internal_maxmag, float); 
> +DECL_VECTOR_2OP(__gen_ocl_internal_minmag, float);
>  #undef DECL_VECTOR_2OP
>  
>  #define DECL_VECTOR_2OP(NAME, TYPE, TYPE2) \ @@ -855,6 +1000,8 @@ 
> INLINE OVERLOADABLE float16 mix(float16 x, float16 y, float a) { 
> return mix(x,y,  #define fmax __gen_ocl_internal_fmax  #define fma mad  
> #define fdim __gen_ocl_internal_fdim
> +#define maxmag __gen_ocl_internal_maxmag #define minmag 
> +__gen_ocl_internal_minmag
>  
>  
> //////////////////////////////////////////////////////////////////////
> ///////
>  // Synchronization functions
> --
> 1.8.1.2
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list