VM2D 1.14
Vortex methods for 2D flows simulation
Loading...
Searching...
No Matches
avx.h
Go to the documentation of this file.
1#pragma once
2#include <immintrin.h>
3#include <type_traits>
4
5namespace fmm {
6
7 #define AVX256
8
9 namespace detail {
10#if defined(AVX128)
11 inline const int avx_vec_length = 2;
12#elif defined(AVX256)
13 inline const int avx_vec_length = 4;
14#elif defined(AVX512)
15 inline const int avx_vec_length = 8;
16#endif
17 }
18
19 template <typename vec_type>
20 vec_type avx_zero_vec()
21 {
22 if constexpr (std::is_same_v<vec_type, __m128d>)
23 return _mm_setzero_pd();
24 if constexpr (std::is_same_v<vec_type, __m256d>)
25 return _mm256_setzero_pd();
26 if constexpr (std::is_same_v<vec_type, __m512d>)
27 return _mm512_setzero_pd();
28 }
29
30 template <typename vec_type>
31 inline void avx_store(double* data, vec_type& v)
32 {
33 if constexpr (std::is_same_v<vec_type, __m128d>)
34 _mm_store_pd(data, v);
35 if constexpr (std::is_same_v<vec_type, __m256d>)
36 _mm256_store_pd(data, v);
37 if constexpr (std::is_same_v<vec_type, __m512d>)
38 _mm512_store_pd(data, v);
39 }
40
41 template <typename vec_type>
42 inline vec_type avx_add(const vec_type& v1, const vec_type& v2)
43 {
44 if constexpr (std::is_same_v<vec_type, __m128d>)
45 return _mm_add_pd(v1, v2);
46 if constexpr (std::is_same_v<vec_type, __m256d>)
47 return _mm256_add_pd(v1, v2);
48 if constexpr (std::is_same_v<vec_type, __m512d>)
49 return _mm512_add_pd(v1, v2);
50 }
51
52 template <typename vec_type>
53 inline vec_type avx_sub(const vec_type& v1, const vec_type& v2)
54 {
55 if constexpr (std::is_same_v<vec_type, __m128d>)
56 return _mm_sub_pd(v1, v2);
57 if constexpr (std::is_same_v<vec_type, __m256d>)
58 return _mm256_sub_pd(v1, v2);
59 if constexpr (std::is_same_v<vec_type, __m512d>)
60 return _mm512_sub_pd(v1, v2);
61 }
62
63 template <typename vec_type>
64 inline vec_type avx_mul(const vec_type& v1, const vec_type& v2)
65 {
66 if constexpr (std::is_same_v<vec_type, __m128d>)
67 return _mm_mul_pd(v1, v2);
68 if constexpr (std::is_same_v<vec_type, __m256d>)
69 return _mm256_mul_pd(v1, v2);
70 if constexpr (std::is_same_v<vec_type, __m512d>)
71 return _mm512_mul_pd(v1, v2);
72 }
73
74 inline double avx_hsum(__m128d v) {
75 return _mm_cvtsd_f64(_mm_add_sd(v, _mm_unpackhi_pd(v, v)));
76 }
77
78 inline double avx_hsum(__m256d v) {
79 __m128d vlow = _mm256_castpd256_pd128(v);
80 vlow = _mm_add_pd(vlow, _mm256_extractf128_pd(v, 1));
81 return _mm_cvtsd_f64(_mm_add_sd(vlow, _mm_unpackhi_pd(vlow, vlow)));
82 }
83
84 inline double avx_hsum(__m512d v) {
85 __m256d vlow = _mm512_castpd512_pd256(v);
86 return avx_hsum(_mm256_add_pd(vlow, _mm512_extractf64x4_pd(v, 1)));
87 }
88
89 template <typename vec_type>
90 inline void avx_set_range(vec_type& vec, double* val)
91 {
92 if constexpr (std::is_same_v<vec_type, __m128d>)
93 vec = _mm_set_pd(val[1], val[0]);
94 if constexpr (std::is_same_v<vec_type, __m256d>)
95 vec = _mm256_set_pd(val[3], val[2], val[1], val[0]);
96 if constexpr (std::is_same_v<vec_type, __m512d>)
97 vec = _mm512_set_pd(val[7], val[6], val[5], val[4], val[3], val[2], val[1], val[0]);
98 }
99
100 template <typename vec_type>
101 inline void avx_set_constant(vec_type& vec, double val)
102 {
103 if constexpr (std::is_same_v<vec_type, __m128d>)
104 vec = _mm_set_pd(val, val);
105 if constexpr (std::is_same_v<vec_type, __m256d>)
106 vec = _mm256_set_pd(val, val, val, val);
107 if constexpr (std::is_same_v<vec_type, __m512d>)
108 vec = _mm512_set_pd(val, val, val, val, val, val, val, val);
109 }
110
111 inline void avx_inv_dr(const __m512d& oneVec, const __m512d& epsVec,
112 const __m512d& x_target, const __m512d& y_target, const __m512d& z_target,
113 __m512d& temp1, __m512d& temp2, __m512d& temp3,
114 __m512d& dx, __m512d& dy, __m512d& dz, __m512d& invdr, __m512d& invdr2)
115 {
116 dx = _mm512_sub_pd(x_target, temp1);
117 dy = _mm512_sub_pd(y_target, temp2);
118 dz = _mm512_sub_pd(z_target, temp3);
119 temp1 = _mm512_mul_pd(dx, dx);
120 temp2 = _mm512_mul_pd(dy, dy);
121 temp3 = _mm512_mul_pd(dz, dz);
122 invdr = _mm512_add_pd(temp1, temp2);
123 invdr = _mm512_add_pd(invdr, temp3);
124 invdr = _mm512_max_pd(invdr, epsVec);
125 invdr2 = _mm512_div_pd(oneVec, invdr);
126 invdr = _mm512_sqrt_pd(invdr2);
127 }
128
129 inline void avx_inv_dr(const __m256d& oneVec, const __m256d& epsVec,
130 const __m256d& x_target, const __m256d& y_target, const __m256d& z_target,
131 __m256d& temp1, __m256d& temp2, __m256d& temp3,
132 __m256d& dx, __m256d& dy, __m256d& dz, __m256d& invdr, __m256d& invdr2)
133 {
134 dx = _mm256_sub_pd(x_target, temp1);
135 dy = _mm256_sub_pd(y_target, temp2);
136 dz = _mm256_sub_pd(z_target, temp3);
137 temp1 = _mm256_mul_pd(dx, dx);
138 temp2 = _mm256_mul_pd(dy, dy);
139 temp3 = _mm256_mul_pd(dz, dz);
140
141 invdr = _mm256_add_pd(temp1, temp2);
142 invdr = _mm256_add_pd(invdr, temp3);
143
144 invdr = _mm256_max_pd(invdr, epsVec);
145 invdr2 = _mm256_div_pd(oneVec, invdr);
146 invdr = _mm256_sqrt_pd(invdr2);
147 }
148
149 inline void avx_inv_dr(const __m128d& oneVec, const __m128d& epsVec,
150 const __m128d& x_target, const __m128d& y_target, const __m128d& z_target,
151 __m128d& temp1, __m128d& temp2, __m128d& temp3,
152 __m128d& dx, __m128d& dy, __m128d& dz, __m128d& invdr, __m128d& invdr2)
153 {
154 dx = _mm_sub_pd(x_target, temp1);
155 dy = _mm_sub_pd(y_target, temp2);
156 dz = _mm_sub_pd(z_target, temp3);
157 temp1 = _mm_mul_pd(dx, dx);
158 temp2 = _mm_mul_pd(dy, dy);
159 temp3 = _mm_mul_pd(dz, dz);
160
161 invdr = _mm_add_pd(temp1, temp2);
162 invdr = _mm_add_pd(invdr, temp3);
163 invdr = _mm_max_pd(invdr, epsVec);
164 invdr2 = _mm_div_pd(oneVec, invdr);
165 invdr = _mm_sqrt_pd(invdr2);
166 }
167}
const int avx_vec_length
Definition avx.h:13
Definition avx.h:5
void avx_set_range(vec_type &vec, double *val)
Definition avx.h:90
void avx_inv_dr(const __m512d &oneVec, const __m512d &epsVec, const __m512d &x_target, const __m512d &y_target, const __m512d &z_target, __m512d &temp1, __m512d &temp2, __m512d &temp3, __m512d &dx, __m512d &dy, __m512d &dz, __m512d &invdr, __m512d &invdr2)
Definition avx.h:111
void avx_store(double *data, vec_type &v)
Definition avx.h:31
vec_type avx_add(const vec_type &v1, const vec_type &v2)
Definition avx.h:42
vec_type avx_mul(const vec_type &v1, const vec_type &v2)
Definition avx.h:64
vec_type avx_sub(const vec_type &v1, const vec_type &v2)
Definition avx.h:53
double avx_hsum(__m128d v)
Definition avx.h:74
void avx_set_constant(vec_type &vec, double val)
Definition avx.h:101
vec_type avx_zero_vec()
Definition avx.h:20