24#ifndef SIMD_PACK_512_H_
25#define SIMD_PACK_512_H_
38template <
typename T>
class Mask;
39template <
typename T>
class Pack;
48 static constexpr unsigned storage_size = 8;
53 for (
unsigned j=1; j < storage_size; ++j) {
54 mask |= value[j] << j;
59 Mask(
bool b0,
bool b1,
bool b2,
bool b3,
bool b4,
bool b5,
bool b6,
bool b7):
60 _reg(std::uint16_t(b0 | b1<<1 | b2<<2 | b3<<3 | b4<<4 | b5<<5 | b6<<6 | b7<<7)) { }
63 _reg(_load_mask16(reinterpret_cast<std::uint16_t*>(ptr))) { }
66 Mask(ptr + iCell / storage_size) { }
78 return _knot_mask8(_reg);
83 const std::uint8_t* value =
reinterpret_cast<const std::uint8_t*
>(&_reg);
95 static constexpr unsigned storage_size = 16;
100 for (
unsigned j=1; j < storage_size; ++j) {
101 mask |= value[j] << j;
107 _reg(_load_mask16(ptr)) { }
110 Mask(ptr + iCell / storage_size) { }
122 return _knot_mask16(_reg);
125 operator bool()
const
127 const std::uint16_t* value =
reinterpret_cast<const std::uint16_t*
>(&_reg);
128 return value[0] != 0;
142 static constexpr std::size_t size = 8;
150 Pack(_mm512_set1_pd(val)) { }
153 Pack(static_cast<double>(val)) { }
156 Pack(static_cast<double>(val)) { }
158 Pack(
double a,
double b,
double c,
double d,
double e,
double f,
double g,
double h):
159 Pack(_mm512_set_pd(h,g,f,e,d,c,b,a)) { }
162 Pack(_mm512_loadu_pd(ptr)) { }
165 Pack(_mm512_i32gather_pd(_mm256_loadu_si256(reinterpret_cast<const __m256i*>(idx)), ptr, sizeof(double))) { }
180 return reinterpret_cast<const double*
>(&_reg)[i];
185 return reinterpret_cast<double*
>(&_reg)[i];
190 return Pack(_mm512_add_pd(_reg, rhs));
195 _reg = _mm512_add_pd(_reg, rhs);
201 return Pack(_mm512_sub_pd(_reg, rhs));
206 _reg = _mm512_sub_pd(_reg, rhs);
212 return Pack(_mm512_mul_pd(_reg, rhs));
217 _reg = _mm512_mul_pd(_reg, rhs);
223 return Pack(_mm512_div_pd(_reg, rhs));
228 _reg = _mm512_div_pd(_reg, rhs);
234 return *
this *
Pack(-1);
239 return _mm512_sqrt_pd(_reg);
252 static constexpr std::size_t size = 16;
260 Pack(_mm512_set1_ps(val)) { }
263 Pack(static_cast<float>(val)) { }
266 Pack(static_cast<float>(val)) { }
269 Pack(static_cast<float>(val)) { }
271 Pack(
float a,
float b,
float c,
float d,
float e,
float f,
float g,
float h,
float i,
float j,
float k,
float l,
float m,
float n,
float o,
float p):
272 Pack(_mm512_set_ps(p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a)) { }
275 Pack(_mm512_loadu_ps(ptr)) { }
278 Pack(_mm512_i32gather_ps(_mm512_loadu_si512(reinterpret_cast<const __m512i*>(idx)), ptr, sizeof(float))) { }
293 return reinterpret_cast<const float*
>(&_reg)[i];
298 return reinterpret_cast<float*
>(&_reg)[i];
303 return Pack(_mm512_add_ps(_reg, rhs));
308 _reg = _mm512_add_ps(_reg, rhs);
314 return Pack(_mm512_sub_ps(_reg, rhs));
319 _reg = _mm512_sub_ps(_reg, rhs);
325 return Pack(_mm512_mul_ps(_reg, rhs));
330 _reg = _mm512_mul_ps(_reg, rhs);
336 return Pack(_mm512_div_ps(_reg, rhs));
341 _reg = _mm512_div_ps(_reg, rhs);
347 return *
this *
Pack(-1);
352 return _mm512_sqrt_ps(_reg);
358Pack<T>
pow(Pack<T> base, Pack<T> exp)
367 for (
unsigned i=0; i < Pack<T>::size; ++i) {
374Pack<T>
min(Pack<T> rhs, Pack<T> lhs)
376 if constexpr (std::is_same_v<T,double>) {
377 return _mm512_min_pd(rhs, lhs);
379 return _mm512_min_ps(rhs, lhs);
384Pack<T>
max(Pack<T> rhs, Pack<T> lhs)
386 if constexpr (std::is_same_v<T,double>) {
387 return _mm512_max_pd(rhs, lhs);
389 return _mm512_max_ps(rhs, lhs);
394Pack<T>
fabs(Pack<T> x)
396 if constexpr (std::is_same_v<T,double>) {
397 return _mm512_abs_pd(x);
399 return _mm512_abs_ps(x);
404void maskstore(T* target, Mask<T> mask, Pack<T> value);
409 _mm512_mask_storeu_pd(target, mask, value);
415 _mm512_mask_storeu_ps(target, mask, value);
420void store(T* target, Pack<T> value);
425 _mm512_storeu_pd(target, value);
431 _mm512_storeu_ps(target, value);
436void store(T* target, Pack<T> value,
const typename Pack<T>::index_t* indices);
441 _mm512_i32scatter_pd(target, _mm256_loadu_si256(
reinterpret_cast<const __m256i*
>(indices)), value,
sizeof(
double));
448 _mm512_i32scatter_ps(target, _mm512_loadu_si512(
reinterpret_cast<const __m512i*
>(indices)), value,
sizeof(
float));
Mask(storage_t *ptr, std::size_t iCell)
static storage_t encode(bool *value)
Mask(bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7)
Mask(storage_t *ptr, std::size_t iCell)
static storage_t encode(bool *value)
Pack & operator+=(Pack rhs)
Pack operator/=(Pack rhs)
Pack operator/(Pack rhs) const
Pack operator+(Pack rhs) const
double operator[](unsigned i) const
Pack operator-=(Pack rhs)
Pack operator-(Pack rhs) const
Pack & operator=(Pack rhs)
Pack(const double *ptr, const index_t *idx)
Pack operator*(Pack rhs) const
Pack & operator*=(Pack rhs)
double & operator[](unsigned i)
Pack(double a, double b, double c, double d, double e, double f, double g, double h)
Pack operator*(Pack rhs) const
Pack & operator*=(Pack rhs)
Pack & operator+=(Pack rhs)
Pack operator+(Pack rhs) const
Pack & operator-=(Pack rhs)
Pack operator/(Pack rhs) const
float & operator[](unsigned i)
Pack operator-(Pack rhs) const
Pack(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l, float m, float n, float o, float p)
Pack(const float *ptr, const index_t *idx)
Pack & operator/=(Pack rhs)
Pack & operator=(Pack rhs)
float operator[](unsigned i) const
void maskstore< double >(double *target, Mask< double > mask, Pack< double > value)
Pack< T > pow(Pack< T > base, Pack< T > exp)
void store< double >(double *target, Pack< double > value)
Pack< T > min(Pack< T > rhs, Pack< T > lhs)
Pack< T > max(Pack< T > rhs, Pack< T > lhs)
void maskstore< float >(float *target, Mask< float > mask, Pack< float > value)
void store(T *target, Pack< T > value)
void store< float >(float *target, Pack< float > value)
Pack< T > fabs(Pack< T > x)
void maskstore(T *target, Mask< T > mask, Pack< T > value)
Expr pow(Expr base, Expr exp)
Top level namespace for all of OpenLB.