Blender V4.3
math_float8.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2013 Intel Corporation
2 * SPDX-FileCopyrightText: 2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: Apache-2.0 */
5
6#ifndef __UTIL_MATH_FLOAT8_H__
7#define __UTIL_MATH_FLOAT8_H__
8
9#ifndef __UTIL_MATH_H__
10# error "Do not include this file directly, include util/types.h instead."
11#endif
12
14
16{
17#ifdef __KERNEL_AVX__
18 return vfloat8(_mm256_setzero_ps());
19#else
20 return make_vfloat8(0.0f);
21#endif
22}
23
25{
26 return make_vfloat8(1.0f);
27}
28
29ccl_device_inline vfloat8 operator+(const vfloat8 a, const vfloat8 b)
30{
31#ifdef __KERNEL_AVX__
32 return vfloat8(_mm256_add_ps(a.m256, b.m256));
33#else
34 return make_vfloat8(
35 a.a + b.a, a.b + b.b, a.c + b.c, a.d + b.d, a.e + b.e, a.f + b.f, a.g + b.g, a.h + b.h);
36#endif
37}
38
39ccl_device_inline vfloat8 operator+(const vfloat8 a, const float f)
40{
41 return a + make_vfloat8(f);
42}
43
44ccl_device_inline vfloat8 operator+(const float f, const vfloat8 a)
45{
46 return make_vfloat8(f) + a;
47}
48
49ccl_device_inline vfloat8 operator-(const vfloat8 a)
50{
51#ifdef __KERNEL_AVX__
52 __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x80000000));
53 return vfloat8(_mm256_xor_ps(a.m256, mask));
54#else
55 return make_vfloat8(-a.a, -a.b, -a.c, -a.d, -a.e, -a.f, -a.g, -a.h);
56#endif
57}
58
59ccl_device_inline vfloat8 operator-(const vfloat8 a, const vfloat8 b)
60{
61#ifdef __KERNEL_AVX__
62 return vfloat8(_mm256_sub_ps(a.m256, b.m256));
63#else
64 return make_vfloat8(
65 a.a - b.a, a.b - b.b, a.c - b.c, a.d - b.d, a.e - b.e, a.f - b.f, a.g - b.g, a.h - b.h);
66#endif
67}
68
69ccl_device_inline vfloat8 operator-(const vfloat8 a, const float f)
70{
71 return a - make_vfloat8(f);
72}
73
74ccl_device_inline vfloat8 operator-(const float f, const vfloat8 a)
75{
76 return make_vfloat8(f) - a;
77}
78
79ccl_device_inline vfloat8 operator*(const vfloat8 a, const vfloat8 b)
80{
81#ifdef __KERNEL_AVX__
82 return vfloat8(_mm256_mul_ps(a.m256, b.m256));
83#else
84 return make_vfloat8(
85 a.a * b.a, a.b * b.b, a.c * b.c, a.d * b.d, a.e * b.e, a.f * b.f, a.g * b.g, a.h * b.h);
86#endif
87}
88
89ccl_device_inline vfloat8 operator*(const vfloat8 a, const float f)
90{
91 return a * make_vfloat8(f);
92}
93
94ccl_device_inline vfloat8 operator*(const float f, const vfloat8 a)
95{
96 return make_vfloat8(f) * a;
97}
98
99ccl_device_inline vfloat8 operator/(const vfloat8 a, const vfloat8 b)
100{
101#ifdef __KERNEL_AVX__
102 return vfloat8(_mm256_div_ps(a.m256, b.m256));
103#else
104 return make_vfloat8(
105 a.a / b.a, a.b / b.b, a.c / b.c, a.d / b.d, a.e / b.e, a.f / b.f, a.g / b.g, a.h / b.h);
106#endif
107}
108
109ccl_device_inline vfloat8 operator/(const vfloat8 a, const float f)
110{
111 return a / make_vfloat8(f);
112}
113
114ccl_device_inline vfloat8 operator/(const float f, const vfloat8 a)
115{
116 return make_vfloat8(f) / a;
117}
118
119ccl_device_inline vfloat8 operator+=(vfloat8 a, const vfloat8 b)
120{
121 return a = a + b;
122}
123
124ccl_device_inline vfloat8 operator-=(vfloat8 a, const vfloat8 b)
125{
126 return a = a - b;
127}
128
129ccl_device_inline vfloat8 operator*=(vfloat8 a, const vfloat8 b)
130{
131 return a = a * b;
132}
133
134ccl_device_inline vfloat8 operator*=(vfloat8 a, float f)
135{
136 return a = a * f;
137}
138
139ccl_device_inline vfloat8 operator/=(vfloat8 a, float f)
140{
141 return a = a / f;
142}
143
144ccl_device_inline bool operator==(const vfloat8 a, const vfloat8 b)
145{
146#ifdef __KERNEL_AVX__
147 return (_mm256_movemask_ps(_mm256_castsi256_ps(
148 _mm256_cmpeq_epi32(_mm256_castps_si256(a.m256), _mm256_castps_si256(b.m256)))) &
149 0b11111111) == 0b11111111;
150#else
151 return (a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e && a.f == b.f &&
152 a.g == b.g && a.h == b.h);
153#endif
154}
155
156ccl_device_inline const vfloat8 operator^(const vfloat8 a, const vfloat8 b)
157{
158#ifdef __KERNEL_AVX__
159 return vfloat8(_mm256_xor_ps(a.m256, b.m256));
160#else
169#endif
170}
171
172ccl_device_inline vfloat8 rcp(const vfloat8 a)
173{
174#ifdef __KERNEL_AVX__
175 return vfloat8(_mm256_rcp_ps(a.m256));
176#else
177 return make_vfloat8(1.0f / a.a,
178 1.0f / a.b,
179 1.0f / a.c,
180 1.0f / a.d,
181 1.0f / a.e,
182 1.0f / a.f,
183 1.0f / a.g,
184 1.0f / a.h);
185#endif
186}
187
188ccl_device_inline vfloat8 sqrt(const vfloat8 a)
189{
190#ifdef __KERNEL_AVX__
191 return vfloat8(_mm256_sqrt_ps(a.m256));
192#else
193 return make_vfloat8(sqrtf(a.a),
194 sqrtf(a.b),
195 sqrtf(a.c),
196 sqrtf(a.d),
197 sqrtf(a.e),
198 sqrtf(a.f),
199 sqrtf(a.g),
200 sqrtf(a.h));
201#endif
202}
203
204ccl_device_inline vfloat8 sqr(const vfloat8 a)
205{
206 return a * a;
207}
208
209ccl_device_inline bool is_zero(const vfloat8 a)
210{
211 return a == make_vfloat8(0.0f);
212}
213
214ccl_device_inline float reduce_add(const vfloat8 a)
215{
216#ifdef __KERNEL_AVX__
217 vfloat8 b(_mm256_hadd_ps(a.m256, a.m256));
218 vfloat8 h(_mm256_hadd_ps(b.m256, b.m256));
219 return h[0] + h[4];
220#else
221 return a.a + a.b + a.c + a.d + a.e + a.f + a.g + a.h;
222#endif
223}
224
225ccl_device_inline float average(const vfloat8 a)
226{
227 return reduce_add(a) / 8.0f;
228}
229
230ccl_device_inline vfloat8 min(const vfloat8 a, const vfloat8 b)
231{
232#ifdef __KERNEL_AVX__
233 return vfloat8(_mm256_min_ps(a.m256, b.m256));
234#else
235 return make_vfloat8(min(a.a, b.a),
236 min(a.b, b.b),
237 min(a.c, b.c),
238 min(a.d, b.d),
239 min(a.e, b.e),
240 min(a.f, b.f),
241 min(a.g, b.g),
242 min(a.h, b.h));
243#endif
244}
245
246ccl_device_inline vfloat8 max(const vfloat8 a, const vfloat8 b)
247{
248#ifdef __KERNEL_AVX__
249 return vfloat8(_mm256_max_ps(a.m256, b.m256));
250#else
251 return make_vfloat8(max(a.a, b.a),
252 max(a.b, b.b),
253 max(a.c, b.c),
254 max(a.d, b.d),
255 max(a.e, b.e),
256 max(a.f, b.f),
257 max(a.g, b.g),
258 max(a.h, b.h));
259#endif
260}
261
262ccl_device_inline vfloat8 clamp(const vfloat8 a, const vfloat8 mn, const vfloat8 mx)
263{
264 return min(max(a, mn), mx);
265}
266
267ccl_device_inline vfloat8 select(const vint8 mask, const vfloat8 a, const vfloat8 b)
268{
269#ifdef __KERNEL_AVX__
270 return vfloat8(_mm256_blendv_ps(b, a, _mm256_castsi256_ps(mask)));
271#else
272 return make_vfloat8((mask.a) ? a.a : b.a,
273 (mask.b) ? a.b : b.b,
274 (mask.c) ? a.c : b.c,
275 (mask.d) ? a.d : b.d,
276 (mask.e) ? a.e : b.e,
277 (mask.f) ? a.f : b.f,
278 (mask.g) ? a.g : b.g,
279 (mask.h) ? a.h : b.h);
280#endif
281}
282
283ccl_device_inline vfloat8 fabs(const vfloat8 a)
284{
285#ifdef __KERNEL_AVX__
286 return vfloat8(_mm256_and_ps(a.m256, _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff))));
287#else
288 return make_vfloat8(fabsf(a.a),
289 fabsf(a.b),
290 fabsf(a.c),
291 fabsf(a.d),
292 fabsf(a.e),
293 fabsf(a.f),
294 fabsf(a.g),
295 fabsf(a.h));
296#endif
297}
298
299ccl_device_inline vfloat8 mix(const vfloat8 a, const vfloat8 b, float t)
300{
301 return a + t * (b - a);
302}
303
304ccl_device_inline vfloat8 mix(const vfloat8 a, const vfloat8 b, vfloat8 t)
305{
306 return a + t * (b - a);
307}
308
309ccl_device_inline vfloat8 saturate(const vfloat8 a)
310{
311 return clamp(a, make_vfloat8(0.0f), make_vfloat8(1.0f));
312}
313
314ccl_device_inline vfloat8 exp(vfloat8 v)
315{
316 return make_vfloat8(
317 expf(v.a), expf(v.b), expf(v.c), expf(v.d), expf(v.e), expf(v.f), expf(v.g), expf(v.h));
318}
319
320ccl_device_inline vfloat8 log(vfloat8 v)
321{
322 return make_vfloat8(
323 logf(v.a), logf(v.b), logf(v.c), logf(v.d), logf(v.e), logf(v.f), logf(v.g), logf(v.h));
324}
325
326ccl_device_inline float dot(const vfloat8 a, const vfloat8 b)
327{
328#ifdef __KERNEL_AVX__
329 vfloat8 t(_mm256_dp_ps(a.m256, b.m256, 0xFF));
330 return t[0] + t[4];
331#else
332 return (a.a * b.a) + (a.b * b.b) + (a.c * b.c) + (a.d * b.d) + (a.e * b.e) + (a.f * b.f) +
333 (a.g * b.g) + (a.h * b.h);
334#endif
335}
336
337ccl_device_inline vfloat8 pow(vfloat8 v, float e)
338{
339 return make_vfloat8(powf(v.a, e),
340 powf(v.b, e),
341 powf(v.c, e),
342 powf(v.d, e),
343 powf(v.e, e),
344 powf(v.f, e),
345 powf(v.g, e),
346 powf(v.h, e));
347}
348
349ccl_device_inline float reduce_min(const vfloat8 a)
350{
351 return min(min(min(a.a, a.b), min(a.c, a.d)), min(min(a.e, a.f), min(a.g, a.h)));
352}
353
354ccl_device_inline float reduce_max(const vfloat8 a)
355{
356 return max(max(max(a.a, a.b), max(a.c, a.d)), max(max(a.e, a.f), max(a.g, a.h)));
357}
358
359ccl_device_inline bool isequal(const vfloat8 a, const vfloat8 b)
360{
361 return a == b;
362}
363
364ccl_device_inline vfloat8 safe_divide(const vfloat8 a, const float b)
365{
366 return (b != 0.0f) ? a / b : make_vfloat8(0.0f);
367}
368
369ccl_device_inline vfloat8 safe_divide(const vfloat8 a, const vfloat8 b)
370{
371 return make_vfloat8((b.a != 0.0f) ? a.a / b.a : 0.0f,
372 (b.b != 0.0f) ? a.b / b.b : 0.0f,
373 (b.c != 0.0f) ? a.c / b.c : 0.0f,
374 (b.d != 0.0f) ? a.d / b.d : 0.0f,
375 (b.e != 0.0f) ? a.e / b.e : 0.0f,
376 (b.f != 0.0f) ? a.f / b.f : 0.0f,
377 (b.g != 0.0f) ? a.g / b.g : 0.0f,
378 (b.h != 0.0f) ? a.h / b.h : 0.0f);
379}
380
382{
383 v.a = ensure_finite(v.a);
384 v.b = ensure_finite(v.b);
385 v.c = ensure_finite(v.c);
386 v.d = ensure_finite(v.d);
387 v.e = ensure_finite(v.e);
388 v.f = ensure_finite(v.f);
389 v.g = ensure_finite(v.g);
390 v.h = ensure_finite(v.h);
391
392 return v;
393}
394
396{
397 return isfinite_safe(v.a) && isfinite_safe(v.b) && isfinite_safe(v.c) && isfinite_safe(v.d) &&
399}
400
401ccl_device_inline vint8 cast(const vfloat8 a)
402{
403#ifdef __KERNEL_AVX__
404 return vint8(_mm256_castps_si256(a));
405#else
406 return make_vint8(__float_as_int(a.a),
407 __float_as_int(a.b),
408 __float_as_int(a.c),
409 __float_as_int(a.d),
410 __float_as_int(a.e),
411 __float_as_int(a.f),
412 __float_as_int(a.g),
413 __float_as_int(a.h));
414#endif
415}
416
417#ifdef __KERNEL_SSE__
418ccl_device_forceinline float4 low(const vfloat8 a)
419{
420# ifdef __KERNEL_AVX__
421 return float4(_mm256_extractf128_ps(a.m256, 0));
422# else
423 return make_float4(a.e, a.f, a.g, a.h);
424# endif
425}
426ccl_device_forceinline float4 high(const vfloat8 a)
427{
428# ifdef __KERNEL_AVX__
429 return float4(_mm256_extractf128_ps(a.m256, 1));
430# else
431 return make_float4(a.a, a.b, a.c, a.d);
432# endif
433}
434
435template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7>
436ccl_device_forceinline const vfloat8 shuffle(const vfloat8 a)
437{
438# ifdef __KERNEL_AVX__
439 return vfloat8(_mm256_permutevar_ps(a, _mm256_set_epi32(i7, i6, i5, i4, i3, i2, i1, i0)));
440# else
441 return make_vfloat8(a[i0], a[i1], a[i2], a[i3], a[i4 + 4], a[i5 + 4], a[i6 + 4], a[i7 + 4]);
442# endif
443}
444
445template<size_t i0, size_t i1, size_t i2, size_t i3>
446ccl_device_forceinline const vfloat8 shuffle(const vfloat8 a, const vfloat8 b)
447{
448# ifdef __KERNEL_AVX__
449 return vfloat8(_mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)));
450# else
451 return make_vfloat8(shuffle<i0, i1, i2, i3>(high(a), high(b)),
452 shuffle<i0, i1, i2, i3>(low(a), low(b)));
453# endif
454}
455
456template<size_t i0, size_t i1, size_t i2, size_t i3>
457ccl_device_forceinline const vfloat8 shuffle(const vfloat8 a)
458{
459 return shuffle<i0, i1, i2, i3>(a, a);
460}
461template<size_t i0> ccl_device_forceinline const vfloat8 shuffle(const vfloat8 a, const vfloat8 b)
462{
463 return shuffle<i0, i0, i0, i0>(a, b);
464}
465template<size_t i0> ccl_device_forceinline const vfloat8 shuffle(const vfloat8 a)
466{
467 return shuffle<i0>(a, a);
468}
469
470template<size_t i> ccl_device_forceinline float extract(const vfloat8 a)
471{
472# ifdef __KERNEL_AVX__
473 __m256 b = shuffle<i, i, i, i>(a).m256;
474 return _mm256_cvtss_f32(b);
475# else
476 return a[i];
477# endif
478}
479#endif
480
482
483#endif /* __UTIL_MATH_FLOAT8_H__ */
#define saturate(a)
__forceinline float extract(const int4 &b)
Definition binning.cpp:27
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
local_group_size(16, 16) .push_constant(Type b
#define ccl_device_forceinline
#define logf(x)
#define expf(x)
#define ccl_device_inline
#define powf(x, y)
#define CCL_NAMESPACE_END
ccl_device_forceinline float4 make_float4(const float x, const float y, const float z, const float w)
#define __float_as_int(x)
#define fabsf(x)
#define __float_as_uint(x)
#define sqrtf(x)
#define __uint_as_float(x)
#define mix(a, b, c)
Definition hash.h:36
ccl_device_inline vfloat8 safe_divide(const vfloat8 a, const float b)
ccl_device_inline vfloat8 exp(vfloat8 v)
ccl_device_inline vfloat8 operator/=(vfloat8 a, float f)
ccl_device_inline vfloat8 one_vfloat8()
Definition math_float8.h:24
ccl_device_inline vfloat8 sqrt(const vfloat8 a)
ccl_device_inline vfloat8 operator*(const vfloat8 a, const vfloat8 b)
Definition math_float8.h:79
ccl_device_inline bool operator==(const vfloat8 a, const vfloat8 b)
ccl_device_inline vfloat8 fabs(const vfloat8 a)
ccl_device_inline vfloat8 ensure_finite(vfloat8 v)
ccl_device_inline float average(const vfloat8 a)
ccl_device_inline vfloat8 sqr(const vfloat8 a)
ccl_device_inline vfloat8 operator+=(vfloat8 a, const vfloat8 b)
ccl_device_inline vfloat8 operator-(const vfloat8 a)
Definition math_float8.h:49
ccl_device_inline vfloat8 operator/(const vfloat8 a, const vfloat8 b)
Definition math_float8.h:99
ccl_device_inline vfloat8 rcp(const vfloat8 a)
ccl_device_inline vfloat8 operator-=(vfloat8 a, const vfloat8 b)
ccl_device_inline bool isequal(const vfloat8 a, const vfloat8 b)
ccl_device_inline float reduce_add(const vfloat8 a)
ccl_device_inline vint8 cast(const vfloat8 a)
ccl_device_inline bool is_zero(const vfloat8 a)
ccl_device_inline float dot(const vfloat8 a, const vfloat8 b)
CCL_NAMESPACE_BEGIN ccl_device_inline vfloat8 zero_vfloat8()
Definition math_float8.h:15
ccl_device_inline bool isfinite_safe(vfloat8 v)
ccl_device_inline vfloat8 operator*=(vfloat8 a, const vfloat8 b)
ccl_device_inline float reduce_min(const vfloat8 a)
ccl_device_inline vfloat8 select(const vint8 mask, const vfloat8 a, const vfloat8 b)
ccl_device_inline vfloat8 clamp(const vfloat8 a, const vfloat8 mn, const vfloat8 mx)
ccl_device_inline vfloat8 operator+(const vfloat8 a, const vfloat8 b)
Definition math_float8.h:29
ccl_device_inline vfloat8 pow(vfloat8 v, float e)
ccl_device_inline float reduce_max(const vfloat8 a)
ccl_device_inline vfloat8 log(vfloat8 v)
ccl_device_inline const vfloat8 operator^(const vfloat8 a, const vfloat8 b)
VecBase< float, 4 > float4
#define min(a, b)
Definition sort.c:32
struct BMEdge * e
float max
ccl_device_inline vfloat8 make_vfloat8(float f)
ccl_device_inline vint8 make_vint8(int a, int b, int c, int d, int e, int f, int g, int h)