MFEM  v4.5.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
m256.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef MFEM_SIMD_M256_HPP
13 #define MFEM_SIMD_M256_HPP
14 
15 #ifdef __AVX__
16 
17 #include "../../config/tconfig.hpp"
18 #if defined(__x86_64__)
19 #include <x86intrin.h>
20 #else // assuming MSVC with _M_X64 or _M_IX86
21 #include <intrin.h>
22 #endif
23 
24 namespace mfem
25 {
26 
27 template <typename, int, int> struct AutoSIMD;
28 
29 template <> struct AutoSIMD<double,4,32>
30 {
31  typedef double scalar_type;
32  static constexpr int size = 4;
33  static constexpr int align_bytes = 32;
34 
35  union
36  {
37  __m256d m256d;
38  double vec[size];
39  };
40 
41  AutoSIMD() = default;
42 
43  AutoSIMD(const AutoSIMD &) = default;
44 
45  inline MFEM_ALWAYS_INLINE double &operator[](int i)
46  {
47  return vec[i];
48  }
49 
50  inline MFEM_ALWAYS_INLINE const double &operator[](int i) const
51  {
52  return vec[i];
53  }
54 
55  inline MFEM_ALWAYS_INLINE AutoSIMD &operator=(const AutoSIMD &v)
56  {
57  m256d = v.m256d;
58  return *this;
59  }
60 
61  inline MFEM_ALWAYS_INLINE AutoSIMD &operator=(const double &e)
62  {
63  m256d = _mm256_set1_pd(e);
64  return *this;
65  }
66 
67  inline MFEM_ALWAYS_INLINE AutoSIMD &operator+=(const AutoSIMD &v)
68  {
69  m256d = _mm256_add_pd(m256d,v.m256d);
70  return *this;
71  }
72 
73  inline MFEM_ALWAYS_INLINE AutoSIMD &operator+=(const double &e)
74  {
75  m256d = _mm256_add_pd(m256d,_mm256_set1_pd(e));
76  return *this;
77  }
78 
79  inline MFEM_ALWAYS_INLINE AutoSIMD &operator-=(const AutoSIMD &v)
80  {
81  m256d = _mm256_sub_pd(m256d,v.m256d);
82  return *this;
83  }
84 
85  inline MFEM_ALWAYS_INLINE AutoSIMD &operator-=(const double &e)
86  {
87  m256d = _mm256_sub_pd(m256d,_mm256_set1_pd(e));
88  return *this;
89  }
90 
91  inline MFEM_ALWAYS_INLINE AutoSIMD &operator*=(const AutoSIMD &v)
92  {
93  m256d = _mm256_mul_pd(m256d,v.m256d);
94  return *this;
95  }
96 
97  inline MFEM_ALWAYS_INLINE AutoSIMD &operator*=(const double &e)
98  {
99  m256d = _mm256_mul_pd(m256d,_mm256_set1_pd(e));
100  return *this;
101  }
102 
103  inline MFEM_ALWAYS_INLINE AutoSIMD &operator/=(const AutoSIMD &v)
104  {
105  m256d = _mm256_div_pd(m256d,v.m256d);
106  return *this;
107  }
108 
109  inline MFEM_ALWAYS_INLINE AutoSIMD &operator/=(const double &e)
110  {
111  m256d = _mm256_div_pd(m256d,_mm256_set1_pd(e));
112  return *this;
113  }
114 
115  inline MFEM_ALWAYS_INLINE AutoSIMD operator-() const
116  {
117  AutoSIMD r;
118  r.m256d = _mm256_xor_pd(_mm256_set1_pd(-0.0), m256d);
119  return r;
120  }
121 
122  inline MFEM_ALWAYS_INLINE AutoSIMD operator+() const
123  {
124  return *this;
125  }
126 
127  inline MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const
128  {
129  AutoSIMD r;
130  r.m256d = _mm256_add_pd(m256d,v.m256d);
131  return r;
132  }
133 
134  inline MFEM_ALWAYS_INLINE AutoSIMD operator+(const double &e) const
135  {
136  AutoSIMD r;
137  r.m256d = _mm256_add_pd(m256d, _mm256_set1_pd(e));
138  return r;
139  }
140 
141  inline MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const
142  {
143  AutoSIMD r;
144  r.m256d = _mm256_sub_pd(m256d,v.m256d);
145  return r;
146  }
147 
148  inline MFEM_ALWAYS_INLINE AutoSIMD operator-(const double &e) const
149  {
150  AutoSIMD r;
151  r.m256d = _mm256_sub_pd(m256d, _mm256_set1_pd(e));
152  return r;
153  }
154 
155  inline MFEM_ALWAYS_INLINE AutoSIMD operator*(const AutoSIMD &v) const
156  {
157  AutoSIMD r;
158  r.m256d = _mm256_mul_pd(m256d,v.m256d);
159  return r;
160  }
161 
162  inline MFEM_ALWAYS_INLINE AutoSIMD operator*(const double &e) const
163  {
164  AutoSIMD r;
165  r.m256d = _mm256_mul_pd(m256d, _mm256_set1_pd(e));
166  return r;
167  }
168 
169  inline MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const
170  {
171  AutoSIMD r;
172  r.m256d = _mm256_div_pd(m256d,v.m256d);
173  return r;
174  }
175 
176  inline MFEM_ALWAYS_INLINE AutoSIMD operator/(const double &e) const
177  {
178  AutoSIMD r;
179  r.m256d = _mm256_div_pd(m256d, _mm256_set1_pd(e));
180  return r;
181  }
182 
183  inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const AutoSIMD &v, const AutoSIMD &w)
184  {
185 #ifndef __AVX2__
186  m256d = _mm256_add_pd(_mm256_mul_pd(w.m256d,v.m256d),m256d);
187 #else
188  m256d = _mm256_fmadd_pd(w.m256d,v.m256d,m256d);
189 #endif
190  return *this;
191  }
192 
193  inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const AutoSIMD &v, const double &e)
194  {
195 #ifndef __AVX2__
196  m256d = _mm256_add_pd(_mm256_mul_pd(_mm256_set1_pd(e),v.m256d),m256d);
197 #else
198  m256d = _mm256_fmadd_pd(_mm256_set1_pd(e),v.m256d,m256d);
199 #endif
200  return *this;
201  }
202 
203  inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const double &e, const AutoSIMD &v)
204  {
205 #ifndef __AVX2__
206  m256d = _mm256_add_pd(_mm256_mul_pd(v.m256d,_mm256_set1_pd(e)),m256d);
207 #else
208  m256d = _mm256_fmadd_pd(v.m256d,_mm256_set1_pd(e),m256d);
209 #endif
210  return *this;
211  }
212 
213  inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const AutoSIMD &v, const AutoSIMD &w)
214  {
215  m256d = _mm256_mul_pd(v.m256d,w.m256d);
216  return *this;
217  }
218 
219  inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const AutoSIMD &v, const double &e)
220  {
221  m256d = _mm256_mul_pd(v.m256d,_mm256_set1_pd(e));
222  return *this;
223  }
224 
225  inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const double &e, const AutoSIMD &v)
226  {
227  m256d = _mm256_mul_pd(_mm256_set1_pd(e),v.m256d);
228  return *this;
229  }
230 };
231 
232 inline MFEM_ALWAYS_INLINE
234  const AutoSIMD<double,4,32> &v)
235 {
237  r.m256d = _mm256_add_pd(_mm256_set1_pd(e),v.m256d);
238  return r;
239 }
240 
241 inline MFEM_ALWAYS_INLINE
243  const AutoSIMD<double,4,32> &v)
244 {
246  r.m256d = _mm256_sub_pd(_mm256_set1_pd(e),v.m256d);
247  return r;
248 }
249 
250 inline MFEM_ALWAYS_INLINE
252  const AutoSIMD<double,4,32> &v)
253 {
255  r.m256d = _mm256_mul_pd(_mm256_set1_pd(e),v.m256d);
256  return r;
257 }
258 
259 inline MFEM_ALWAYS_INLINE
261  const AutoSIMD<double,4,32> &v)
262 {
264  r.m256d = _mm256_div_pd(_mm256_set1_pd(e),v.m256d);
265  return r;
266 }
267 
268 } // namespace mfem
269 
270 #endif // __AVX__
271 
272 #endif // MFEM_SIMD_M256_HPP
MFEM_ALWAYS_INLINE double & operator[](int i)
Definition: m256.hpp:45
MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const
Definition: m256.hpp:141
MFEM_ALWAYS_INLINE AutoSIMD operator/(const double &e) const
Definition: m256.hpp:176
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const double &e)
Definition: m256.hpp:219
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const double &e)
Definition: m256.hpp:97
MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const
Definition: m256.hpp:127
MFEM_ALWAYS_INLINE AutoSIMD< scalar_t, S, A > operator/(const scalar_t &e, const AutoSIMD< scalar_t, S, A > &v)
Definition: auto.hpp:271
MFEM_ALWAYS_INLINE AutoSIMD operator*(const AutoSIMD &v) const
Definition: m256.hpp:155
static const int size
Definition: auto.hpp:27
scalar_t vec[size]
Definition: auto.hpp:30
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const AutoSIMD &v)
Definition: m256.hpp:91
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const AutoSIMD &v)
Definition: m256.hpp:55
MFEM_ALWAYS_INLINE AutoSIMD operator+() const
Definition: m256.hpp:122
MFEM_ALWAYS_INLINE AutoSIMD< scalar_t, S, A > operator+(const scalar_t &e, const AutoSIMD< scalar_t, S, A > &v)
Definition: auto.hpp:238
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const AutoSIMD &v)
Definition: m256.hpp:103
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const AutoSIMD &v)
Definition: m256.hpp:67
MFEM_ALWAYS_INLINE AutoSIMD operator+(const double &e) const
Definition: m256.hpp:134
MFEM_ALWAYS_INLINE AutoSIMD & fma(const AutoSIMD &v, const double &e)
Definition: m256.hpp:193
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const double &e)
Definition: m256.hpp:73
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const double &e)
Definition: m256.hpp:109
static const int align_bytes
Definition: auto.hpp:28
MFEM_ALWAYS_INLINE AutoSIMD & mul(const double &e, const AutoSIMD &v)
Definition: m256.hpp:225
MFEM_ALWAYS_INLINE AutoSIMD operator-() const
Definition: m256.hpp:115
MFEM_ALWAYS_INLINE AutoSIMD & fma(const AutoSIMD &v, const AutoSIMD &w)
Definition: m256.hpp:183
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const AutoSIMD &w)
Definition: m256.hpp:213
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const AutoSIMD &v)
Definition: m256.hpp:79
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const double &e)
Definition: m256.hpp:61
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const double &e)
Definition: m256.hpp:85
MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const
Definition: m256.hpp:169
MFEM_ALWAYS_INLINE AutoSIMD & fma(const double &e, const AutoSIMD &v)
Definition: m256.hpp:203
MFEM_ALWAYS_INLINE AutoSIMD operator-(const double &e) const
Definition: m256.hpp:148
MFEM_ALWAYS_INLINE AutoSIMD operator*(const double &e) const
Definition: m256.hpp:162
AutoSIMD()=default
MemoryClass operator*(MemoryClass mc1, MemoryClass mc2)
Return a suitable MemoryClass from a pair of MemoryClasses.
MFEM_ALWAYS_INLINE AutoSIMD< scalar_t, S, A > operator-(const scalar_t &e, const AutoSIMD< scalar_t, S, A > &v)
Definition: auto.hpp:249
MFEM_ALWAYS_INLINE const double & operator[](int i) const
Definition: m256.hpp:50