vec2fa_sycl.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "../sys/alloc.h"
  5. #include "emath.h"
  6. #include "../simd/sse.h"
  7. namespace embree
  8. {
  9. struct Vec3fa;
  10. ////////////////////////////////////////////////////////////////////////////////
  11. /// SSE Vec2fa Type
  12. ////////////////////////////////////////////////////////////////////////////////
  13. struct __aligned(16) Vec2fa
  14. {
  15. //ALIGNED_STRUCT_(16);
  16. typedef float Scalar;
  17. enum { N = 2 };
  18. struct { float x,y; };
  19. ////////////////////////////////////////////////////////////////////////////////
  20. /// Constructors, Assignment & Cast Operators
  21. ////////////////////////////////////////////////////////////////////////////////
  22. __forceinline Vec2fa( ) {}
  23. //__forceinline Vec2fa( const __m128 a ) : m128(a) {}
  24. explicit Vec2fa(const Vec3fa& a);
  25. __forceinline explicit Vec2fa( const vfloat<4>& a ) {
  26. x = a[0];
  27. y = a[1];
  28. }
  29. __forceinline Vec2fa ( const Vec2<float>& other ) { x = other.x; y = other.y; }
  30. __forceinline Vec2fa& operator =( const Vec2<float>& other ) { x = other.x; y = other.y; return *this; }
  31. __forceinline Vec2fa ( const Vec2fa& other ) { x = other.x; y = other.y; }
  32. __forceinline Vec2fa& operator =( const Vec2fa& other ) { x = other.x; y = other.y; return *this; }
  33. __forceinline explicit Vec2fa( const float a ) : x(a), y(a) {}
  34. __forceinline Vec2fa( const float x, const float y) : x(x), y(y) {}
  35. //__forceinline explicit Vec2fa( const __m128i a ) : m128(_mm_cvtepi32_ps(a)) {}
  36. //__forceinline operator const __m128&() const { return m128; }
  37. //__forceinline operator __m128&() { return m128; }
  38. ////////////////////////////////////////////////////////////////////////////////
  39. /// Loads and Stores
  40. ////////////////////////////////////////////////////////////////////////////////
  41. static __forceinline Vec2fa load( const void* const a ) {
  42. const float* ptr = (const float*)a;
  43. return Vec2fa(ptr[0],ptr[1]);
  44. }
  45. static __forceinline Vec2fa loadu( const void* const a ) {
  46. const float* ptr = (const float*)a;
  47. return Vec2fa(ptr[0],ptr[1]);
  48. }
  49. static __forceinline void storeu ( void* a, const Vec2fa& v ) {
  50. float* ptr = (float*)a;
  51. ptr[0] = v.x; ptr[1] = v.y;
  52. }
  53. ////////////////////////////////////////////////////////////////////////////////
  54. /// Constants
  55. ////////////////////////////////////////////////////////////////////////////////
  56. __forceinline Vec2fa( ZeroTy ) : x(0.0f), y(0.0f) {}
  57. __forceinline Vec2fa( OneTy ) : x(1.0f), y(1.0f) {}
  58. __forceinline Vec2fa( PosInfTy ) : x(+INFINITY), y(+INFINITY) {}
  59. __forceinline Vec2fa( NegInfTy ) : x(-INFINITY), y(-INFINITY) {}
  60. ////////////////////////////////////////////////////////////////////////////////
  61. /// Array Access
  62. ////////////////////////////////////////////////////////////////////////////////
  63. //__forceinline const float& operator []( const size_t index ) const { assert(index < 2); return (&x)[index]; }
  64. //__forceinline float& operator []( const size_t index ) { assert(index < 2); return (&x)[index]; }
  65. };
  66. ////////////////////////////////////////////////////////////////////////////////
  67. /// Unary Operators
  68. ////////////////////////////////////////////////////////////////////////////////
  69. __forceinline Vec2fa operator +( const Vec2fa& a ) { return a; }
  70. __forceinline Vec2fa operator -( const Vec2fa& a ) { return Vec2fa(-a.x,-a.y); }
  71. __forceinline Vec2fa abs ( const Vec2fa& a ) { return Vec2fa(sycl::fabs(a.x),sycl::fabs(a.y)); }
  72. __forceinline Vec2fa sign ( const Vec2fa& a ) { return Vec2fa(sycl::sign(a.x),sycl::sign(a.y)); }
  73. //__forceinline Vec2fa rcp ( const Vec2fa& a ) { return Vec2fa(sycl::recip(a.x),sycl::recip(a.y)); }
  74. __forceinline Vec2fa rcp ( const Vec2fa& a ) { return Vec2fa(__sycl_std::__invoke_native_recip<float>(a.x),__sycl_std::__invoke_native_recip<float>(a.y)); }
  75. __forceinline Vec2fa sqrt ( const Vec2fa& a ) { return Vec2fa(sycl::sqrt(a.x),sycl::sqrt(a.y)); }
  76. __forceinline Vec2fa sqr ( const Vec2fa& a ) { return Vec2fa(a.x*a.x,a.y*a.y); }
  77. __forceinline Vec2fa rsqrt( const Vec2fa& a ) { return Vec2fa(sycl::rsqrt(a.x),sycl::rsqrt(a.y)); }
  78. __forceinline Vec2fa zero_fix(const Vec2fa& a) {
  79. const float x = sycl::fabs(a.x) < min_rcp_input ? min_rcp_input : a.x;
  80. const float y = sycl::fabs(a.y) < min_rcp_input ? min_rcp_input : a.y;
  81. return Vec2fa(x,y);
  82. }
  83. __forceinline Vec2fa rcp_safe(const Vec2fa& a) {
  84. return rcp(zero_fix(a));
  85. }
  86. __forceinline Vec2fa log ( const Vec2fa& a ) {
  87. return Vec2fa(sycl::log(a.x),sycl::log(a.y));
  88. }
  89. __forceinline Vec2fa exp ( const Vec2fa& a ) {
  90. return Vec2fa(sycl::exp(a.x),sycl::exp(a.y));
  91. }
  92. ////////////////////////////////////////////////////////////////////////////////
  93. /// Binary Operators
  94. ////////////////////////////////////////////////////////////////////////////////
  95. __forceinline Vec2fa operator +( const Vec2fa& a, const Vec2fa& b ) { return Vec2fa(a.x+b.x, a.y+b.y); }
  96. __forceinline Vec2fa operator -( const Vec2fa& a, const Vec2fa& b ) { return Vec2fa(a.x-b.x, a.y-b.y); }
  97. __forceinline Vec2fa operator *( const Vec2fa& a, const Vec2fa& b ) { return Vec2fa(a.x*b.x, a.y*b.y); }
  98. __forceinline Vec2fa operator *( const Vec2fa& a, const float b ) { return a * Vec2fa(b); }
  99. __forceinline Vec2fa operator *( const float a, const Vec2fa& b ) { return Vec2fa(a) * b; }
  100. __forceinline Vec2fa operator /( const Vec2fa& a, const Vec2fa& b ) { return Vec2fa(a.x/b.x, a.y/b.y); }
  101. __forceinline Vec2fa operator /( const Vec2fa& a, const float b ) { return Vec2fa(a.x/b, a.y/b); }
  102. __forceinline Vec2fa operator /( const float a, const Vec2fa& b ) { return Vec2fa(a/b.x, a/b.y); }
  103. __forceinline Vec2fa min( const Vec2fa& a, const Vec2fa& b ) {
  104. return Vec2fa(sycl::fmin(a.x,b.x), sycl::fmin(a.y,b.y));
  105. }
  106. __forceinline Vec2fa max( const Vec2fa& a, const Vec2fa& b ) {
  107. return Vec2fa(sycl::fmax(a.x,b.x), sycl::fmax(a.y,b.y));
  108. }
  109. /*
  110. #if defined(__SSE4_1__)
  111. __forceinline Vec2fa mini(const Vec2fa& a, const Vec2fa& b) {
  112. const vint4 ai = _mm_castps_si128(a);
  113. const vint4 bi = _mm_castps_si128(b);
  114. const vint4 ci = _mm_min_epi32(ai,bi);
  115. return _mm_castsi128_ps(ci);
  116. }
  117. #endif
  118. #if defined(__SSE4_1__)
  119. __forceinline Vec2fa maxi(const Vec2fa& a, const Vec2fa& b) {
  120. const vint4 ai = _mm_castps_si128(a);
  121. const vint4 bi = _mm_castps_si128(b);
  122. const vint4 ci = _mm_max_epi32(ai,bi);
  123. return _mm_castsi128_ps(ci);
  124. }
  125. #endif
  126. __forceinline Vec2fa pow ( const Vec2fa& a, const float& b ) {
  127. return Vec2fa(powf(a.x,b),powf(a.y,b));
  128. }
  129. */
  130. ////////////////////////////////////////////////////////////////////////////////
  131. /// Ternary Operators
  132. ////////////////////////////////////////////////////////////////////////////////
  133. __forceinline Vec2fa madd ( const Vec2fa& a, const Vec2fa& b, const Vec2fa& c) { return Vec2fa(madd(a.x,b.x,c.x), madd(a.y,b.y,c.y)); }
  134. __forceinline Vec2fa msub ( const Vec2fa& a, const Vec2fa& b, const Vec2fa& c) { return Vec2fa(msub(a.x,b.x,c.x), msub(a.y,b.y,c.y)); }
  135. __forceinline Vec2fa nmadd ( const Vec2fa& a, const Vec2fa& b, const Vec2fa& c) { return Vec2fa(nmadd(a.x,b.x,c.x), nmadd(a.y,b.y,c.y)); }
  136. __forceinline Vec2fa nmsub ( const Vec2fa& a, const Vec2fa& b, const Vec2fa& c) { return Vec2fa(nmsub(a.x,b.x,c.x), nmsub(a.y,b.y,c.y)); }
  137. __forceinline Vec2fa madd ( const float a, const Vec2fa& b, const Vec2fa& c) { return madd(Vec2fa(a),b,c); }
  138. __forceinline Vec2fa msub ( const float a, const Vec2fa& b, const Vec2fa& c) { return msub(Vec2fa(a),b,c); }
  139. __forceinline Vec2fa nmadd ( const float a, const Vec2fa& b, const Vec2fa& c) { return nmadd(Vec2fa(a),b,c); }
  140. __forceinline Vec2fa nmsub ( const float a, const Vec2fa& b, const Vec2fa& c) { return nmsub(Vec2fa(a),b,c); }
  141. ////////////////////////////////////////////////////////////////////////////////
  142. /// Assignment Operators
  143. ////////////////////////////////////////////////////////////////////////////////
  144. __forceinline Vec2fa& operator +=( Vec2fa& a, const Vec2fa& b ) { return a = a + b; }
  145. __forceinline Vec2fa& operator -=( Vec2fa& a, const Vec2fa& b ) { return a = a - b; }
  146. __forceinline Vec2fa& operator *=( Vec2fa& a, const Vec2fa& b ) { return a = a * b; }
  147. __forceinline Vec2fa& operator *=( Vec2fa& a, const float b ) { return a = a * b; }
  148. __forceinline Vec2fa& operator /=( Vec2fa& a, const Vec2fa& b ) { return a = a / b; }
  149. __forceinline Vec2fa& operator /=( Vec2fa& a, const float b ) { return a = a / b; }
  150. ////////////////////////////////////////////////////////////////////////////////
  151. /// Reductions
  152. ////////////////////////////////////////////////////////////////////////////////
  153. __forceinline float reduce_add(const Vec2fa& v) { return v.x+v.y; }
  154. __forceinline float reduce_mul(const Vec2fa& v) { return v.x*v.y; }
  155. __forceinline float reduce_min(const Vec2fa& v) { return sycl::fmin(v.x,v.y); }
  156. __forceinline float reduce_max(const Vec2fa& v) { return sycl::fmax(v.x,v.y); }
  157. ////////////////////////////////////////////////////////////////////////////////
  158. /// Comparison Operators
  159. ////////////////////////////////////////////////////////////////////////////////
  160. __forceinline bool operator ==( const Vec2fa& a, const Vec2fa& b ) { return a.x == b.x && a.y == b.y; }
  161. __forceinline bool operator !=( const Vec2fa& a, const Vec2fa& b ) { return a.x != b.x || a.y != b.y; }
  162. ////////////////////////////////////////////////////////////////////////////////
  163. /// Euclidian Space Operators
  164. ////////////////////////////////////////////////////////////////////////////////
  165. __forceinline float dot ( const Vec2fa& a, const Vec2fa& b ) {
  166. return reduce_add(a*b);
  167. }
  168. __forceinline Vec2fa cross ( const Vec2fa& a ) {
  169. return Vec2fa(-a.y,a.x);
  170. }
  171. __forceinline float sqr_length ( const Vec2fa& a ) { return dot(a,a); }
  172. __forceinline float rcp_length ( const Vec2fa& a ) { return rsqrt(dot(a,a)); }
  173. __forceinline float rcp_length2( const Vec2fa& a ) { return rcp(dot(a,a)); }
  174. __forceinline float length ( const Vec2fa& a ) { return sqrt(dot(a,a)); }
  175. __forceinline Vec2fa normalize( const Vec2fa& a ) { return a*rsqrt(dot(a,a)); }
  176. __forceinline float distance ( const Vec2fa& a, const Vec2fa& b ) { return length(a-b); }
  177. ////////////////////////////////////////////////////////////////////////////////
  178. /// Select
  179. ////////////////////////////////////////////////////////////////////////////////
  180. __forceinline Vec2fa select( bool s, const Vec2fa& t, const Vec2fa& f ) {
  181. return Vec2fa(s ? t.x : f.x, s ? t.y : f.y);
  182. }
  183. __forceinline Vec2fa lerp(const Vec2fa& v0, const Vec2fa& v1, const float t) {
  184. return madd(1.0f-t,v0,t*v1);
  185. }
  186. __forceinline int maxDim ( const Vec2fa& a )
  187. {
  188. const Vec2fa b = abs(a);
  189. if (b.x > b.y) return 0;
  190. else return 1;
  191. }
  192. ////////////////////////////////////////////////////////////////////////////////
  193. /// Rounding Functions
  194. ////////////////////////////////////////////////////////////////////////////////
  195. __forceinline Vec2fa trunc( const Vec2fa& a ) { return Vec2fa(sycl::trunc(a.x),sycl::trunc(a.y)); }
  196. __forceinline Vec2fa floor( const Vec2fa& a ) { return Vec2fa(sycl::floor(a.x),sycl::floor(a.y)); }
  197. __forceinline Vec2fa ceil ( const Vec2fa& a ) { return Vec2fa(sycl::ceil (a.x),sycl::ceil (a.y)); }
  198. ////////////////////////////////////////////////////////////////////////////////
  199. /// Output Operators
  200. ////////////////////////////////////////////////////////////////////////////////
  201. inline embree_ostream operator<<(embree_ostream cout, const Vec2fa& a) {
  202. return cout << "(" << a.x << ", " << a.y << ")";
  203. }
  204. /*template<>
  205. __forceinline vfloat_impl<4>::vfloat_impl(const Vec2fa& a)
  206. {
  207. v = 0;
  208. const unsigned int lid = get_sub_group_local_id();
  209. if (lid == 0) v = a.x;
  210. if (lid == 1) v = a.y;
  211. }*/
  212. typedef Vec2fa Vec2fa_t;
  213. }