AmpGen 2.1
Loading...
Searching...
No Matches
avx2f_types.h
Go to the documentation of this file.
1#ifndef AMPGEN_AVX_TYPES
2#define AMPGEN_AVX_TYPES 1
3
4#include <immintrin.h>
5#include <array>
6#include <iostream>
7#include <complex>
8#include <omp.h>
9#include <cmath>
10#include "AmpGen/Complex.h"
11
12#if USE_MVEC
13extern "C" void _ZGVdN8vvv_sincos(__m256 x, __m256i ptrs, __m256i ptrc);
14#define libmvec_alias(F, O) \
15 extern "C" __m256 _ZGVcN8v_##F(__m256 x); \
16 inline real_v O(const real_v &v) { return _ZGVcN8v_##F(v); }
17#else
18#define libmvec_alias(F, O) \
19 inline real_v O(const real_v &v) { \
20 auto arr = v.to_ptr(); \
21 return real_v(std::F(arr[0]), std::F(arr[1]), std::F(arr[2]), std::F(arr[3]), std::F(arr[4]), std::F(arr[5]), std::F(arr[6]), std::F(arr[7])); \
22 }
23#endif
24
25namespace AmpGen {
26 namespace AVX2f {
27 struct real_v {
28 __m256 data;
29 static constexpr unsigned size = 8;
30 typedef float scalar_type;
31 real_v() = default;
32 real_v(__m256 data) : data(data) {}
33 real_v(const int &f) : real_v(scalar_type(f)) {}
34 real_v(const scalar_type &f) : data(_mm256_set1_ps(f)) {}
35 real_v(const double &f) : data(_mm256_set1_ps(scalar_type(f))) {}
36 explicit real_v(const scalar_type *f) : data(_mm256_loadu_ps(f)) {}
37 real_v(const scalar_type &x0, const scalar_type &x1, const scalar_type &x2, const scalar_type &x3, const scalar_type &x4, const scalar_type &x5,
38 const scalar_type &x6, const scalar_type &x7) {
39 data = _mm256_set_ps(x7, x6, x5, x4, x3, x2, x1, x0);
40 }
41
42 void store(scalar_type *ptr) const { _mm256_storeu_ps(ptr, data); }
43 std::array<scalar_type, 8> to_array() const {
44 std::array<scalar_type, 8> b;
45 store(&b[0]);
46 return b;
47 }
48 const scalar_type *to_ptr() const { return reinterpret_cast<const scalar_type *>(&data); }
49 scalar_type *to_ptr() { return reinterpret_cast<scalar_type *>(&data); }
50 scalar_type at(const unsigned i) const { return to_ptr()[i]; }
51 operator __m256() const { return data; }
52 inline real_v operator+=(const real_v &rhs);
53 inline real_v operator-=(const real_v &rhs);
54 inline real_v operator*=(const real_v &rhs);
55 inline real_v operator/=(const real_v &rhs);
56 inline __m256i to_int() const { return _mm256_cvtps_epi32(data); }
57 };
58
59 inline real_v operator+(const real_v &lhs, const real_v &rhs) { return _mm256_add_ps(lhs, rhs); }
60 inline real_v operator-(const real_v &lhs, const real_v &rhs) { return _mm256_sub_ps(lhs, rhs); }
61 inline real_v operator*(const real_v &lhs, const real_v &rhs) { return _mm256_mul_ps(lhs, rhs); }
62 inline real_v operator/(const real_v &lhs, const real_v &rhs) { return _mm256_div_ps(lhs, rhs); }
63 inline real_v operator-(const real_v &x) { return -1.f * x; }
64 inline real_v operator&(const real_v &lhs, const real_v &rhs) { return _mm256_and_ps(lhs, rhs); }
65 inline real_v operator|(const real_v &lhs, const real_v &rhs) { return _mm256_or_ps(lhs, rhs); }
66 inline real_v operator^(const real_v &lhs, const real_v &rhs) { return _mm256_xor_ps(lhs, rhs); }
67 inline real_v operator&&(const real_v &lhs, const real_v &rhs) { return _mm256_and_ps(lhs, rhs); }
68 inline real_v operator||(const real_v &lhs, const real_v &rhs) { return _mm256_or_ps(lhs, rhs); }
69 inline real_v operator!(const real_v &x) { return x ^ _mm256_castsi256_ps(_mm256_set1_epi32(-1)); }
70 inline real_v operator<(const real_v &lhs, const real_v &rhs) { return _mm256_cmp_ps(lhs, rhs, _CMP_LT_OS); }
71 inline real_v operator>(const real_v &lhs, const real_v &rhs) { return _mm256_cmp_ps(lhs, rhs, _CMP_GT_OS); }
72 inline real_v operator<=(const real_v &lhs, const real_v &rhs) { return _mm256_cmp_ps(lhs, rhs, _CMP_LE_OS); }
73 inline real_v operator>=(const real_v &lhs, const real_v &rhs) { return _mm256_cmp_ps(lhs, rhs, _CMP_GE_OS); }
74 inline real_v operator==(const real_v &lhs, const real_v &rhs) { return _mm256_cmp_ps(lhs, rhs, _CMP_EQ_OS); }
75 inline real_v sqrt(const real_v &v) { return _mm256_sqrt_ps(v); }
76 inline real_v real_v::operator+=(const real_v &rhs) {
77 *this = *this + rhs;
78 return *this;
79 }
80 inline real_v real_v::operator-=(const real_v &rhs) {
81 *this = *this - rhs;
82 return *this;
83 }
84 inline real_v real_v::operator*=(const real_v &rhs) {
85 *this = *this * rhs;
86 return *this;
87 }
88 inline real_v real_v::operator/=(const real_v &rhs) {
89 *this = *this / rhs;
90 return *this;
91 }
93 libmvec_alias(logf, log) inline std::array<int32_t, real_v::size> store(const __m256i &v) {
94 alignas(32) std::array<int32_t, real_v::size> rt;
95 _mm256_store_si256((__m256i *)&rt[0], v);
96 return rt;
97 }
98
99 inline void sincos(const real_v &v, real_v &s, real_v &c) {
100 s = sin(v);
101 c = cos(v);
102 }
103 inline std::pair<real_v, real_v> sincos(const real_v &v) {
104 std::pair<real_v, real_v> rt;
105 sincos(v, rt.first, rt.second);
106 return rt;
107 }
108 inline real_v tan(const real_v &v) {
109 auto [s, c] = sincos(v);
110 return s / c;
111 }
112
113 inline real_v abs(const real_v &v) { return v & _mm256_castsi256_ps(_mm256_set1_epi32(0x7FFFFFFF)); }
114 inline real_v select(const real_v &mask, const real_v &a, const real_v &b) { return _mm256_blendv_ps(b, a, mask); }
115 inline real_v select(const bool &mask, const real_v &a, const real_v &b) { return mask ? a : b; }
116 inline real_v sign(const real_v &v) { return select(v > 0., +1., -1.); }
117 inline real_v fmadd(const real_v &a, const real_v &b, const real_v &c) { return _mm256_fmadd_ps(a, b, c); }
118 inline real_v remainder(const real_v &a, const real_v &b) { return a - real_v(_mm256_round_ps(a / b, _MM_FROUND_TO_NEG_INF)) * b; }
119 inline real_v atan2(const real_v &y, const real_v &x) {
120 const auto *bx = x.to_ptr();
121 const auto *by = y.to_ptr();
122 real_v rt;
123 for(unsigned i = 0; i != real_v::size; ++i) rt.to_ptr()[i] = std::atan2(by[i], bx[i]);
124 return rt;
125 }
126 inline real_v gather(const double *base_addr, const real_v &offsets) {
128 std::array<float, real_v::size> tmp;
129 auto ptr = store(offsets.to_int());
130 // int32_t* ptr = (int32_t*)(&ints);
131 for(int i = 0; i != real_v::size; ++i) tmp[i] = real_v::scalar_type(base_addr[ptr[i]]);
132 return real_v(tmp.data());
133 }
134
135 inline real_v fmod(const real_v &a, const real_v &b) {
136 auto r = remainder(abs(a), abs(b));
137 return select(a > 0., r, -r);
138 }
139
140 inline std::ostream &operator<<(std::ostream &os, const real_v &obj) {
141 auto buffer = obj.to_array();
142 for(unsigned i = 0; i != real_v::size; ++i) os << buffer[i] << " ";
143 return os;
144 }
145
147 inline complex_v select(const real_v &mask, const complex_v &a, const complex_v &b) {
148 return complex_v(select(mask, a.real(), b.real()), select(mask, a.imag(), b.imag()));
149 }
150 inline complex_v select(const real_v &mask, const real_v &a, const complex_v &b) {
151 return complex_v(select(mask, a, b.real()), select(mask, 0.f, b.imag()));
152 }
153 inline complex_v select(const real_v &mask, const complex_v &a, const real_v &b) {
154 return complex_v(select(mask, a.real(), b), select(mask, a.imag(), 0.f));
155 }
156 inline complex_v select(const bool &mask, const complex_v &a, const complex_v &b) { return mask ? a : b; }
157#pragma omp declare reduction(+ : real_v : omp_out = omp_out + omp_in)
158#pragma omp declare reduction(+ : complex_v : omp_out = omp_out + omp_in)
159 }
160}
161
162#endif
#define libmvec_alias(F)
real_v operator&(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:64
real_v operator-(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:60
real_v sqrt(const real_v &v)
Definition avx2f_types.h:75
real_v operator+(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:59
real_v operator||(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:68
real_v abs(const real_v &v)
void sincos(const real_v &v, real_v &s, real_v &c)
Definition avx2f_types.h:99
real_v operator==(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:74
real_v fmadd(const real_v &a, const real_v &b, const real_v &c)
real_v select(const real_v &mask, const real_v &a, const real_v &b)
real_v operator/(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:62
real_v sin(const real_v &v)
Definition avx2f_types.h:92
real_v fmod(const real_v &a, const real_v &b)
Complex< real_v > complex_v
real_v tan(const real_v &v)
real_v operator>=(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:73
real_v operator!(const real_v &x)
Definition avx2f_types.h:69
real_v operator^(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:66
std::array< int32_t, real_v::size > store(const __m256i &v)
Definition avx2f_types.h:93
real_v operator*(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:61
std::ostream & operator<<(std::ostream &os, const real_v &obj)
real_v exp(const real_v &v)
Definition avx2f_types.h:92
real_v operator|(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:65
real_v cos(const real_v &v)
Definition avx2f_types.h:92
real_v operator>(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:71
real_v log(const real_v &v)
Definition avx2f_types.h:93
real_v gather(const double *base_addr, const real_v &offsets)
real_v operator<(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:70
real_v remainder(const real_v &a, const real_v &b)
real_v operator&&(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:67
real_v sign(const real_v &v)
real_v atan2(const real_v &y, const real_v &x)
real_v operator<=(const real_v &lhs, const real_v &rhs)
Definition avx2f_types.h:72
AVX::real_v real_v
Definition utils.h:47
real_v(__m256 data)
Definition avx2f_types.h:32
real_v operator/=(const real_v &rhs)
Definition avx2f_types.h:88
real_v operator+=(const real_v &rhs)
Definition avx2f_types.h:76
const scalar_type * to_ptr() const
Definition avx2f_types.h:48
real_v(const scalar_type &f)
Definition avx2f_types.h:34
real_v(const scalar_type &x0, const scalar_type &x1, const scalar_type &x2, const scalar_type &x3, const scalar_type &x4, const scalar_type &x5, const scalar_type &x6, const scalar_type &x7)
Definition avx2f_types.h:37
real_v(const double &f)
Definition avx2f_types.h:35
scalar_type at(const unsigned i) const
Definition avx2f_types.h:50
void store(scalar_type *ptr) const
Definition avx2f_types.h:42
scalar_type * to_ptr()
Definition avx2f_types.h:49
std::array< scalar_type, 8 > to_array() const
Definition avx2f_types.h:43
real_v operator*=(const real_v &rhs)
Definition avx2f_types.h:84
real_v(const scalar_type *f)
Definition avx2f_types.h:36
real_v operator-=(const real_v &rhs)
Definition avx2f_types.h:80
__m256i to_int() const
Definition avx2f_types.h:56
static constexpr unsigned size
Definition avx2f_types.h:29
real_v(const int &f)
Definition avx2f_types.h:33
real_t real() const
Definition Complex.h:23
real_t imag() const
Definition Complex.h:24