MFEM  v4.5.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
m512.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_M512_HPP
13 #define MFEM_SIMD_M512_HPP
14 
15 #ifdef __AVX512F__
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 
25 namespace mfem
26 {
27 
28 template <typename, int, int> struct AutoSIMD;
29 
30 template <> struct AutoSIMD<double,8,64>
31 {
32  typedef double scalar_type;
33  static constexpr int size = 8;
34  static constexpr int align_bytes = 64;
35 
36  union
37  {
38  __m512d m512d;
39  double vec[size];
40  };
41 
42  AutoSIMD() = default;
43 
44  AutoSIMD(const AutoSIMD &) = default;
45 
46  inline MFEM_ALWAYS_INLINE double &operator[](int i)
47  {
48  return vec[i];
49  }
50 
51  inline MFEM_ALWAYS_INLINE const double &operator[](int i) const
52  {
53  return vec[i];
54  }
55 
56  inline MFEM_ALWAYS_INLINE AutoSIMD &operator=(const AutoSIMD &v)
57  {
58  m512d = v.m512d;
59  return *this;
60  }
61 
62  inline MFEM_ALWAYS_INLINE AutoSIMD &operator=(const double &e)
63  {
64  m512d = _mm512_set1_pd(e);
65  return *this;
66  }
67 
68  inline MFEM_ALWAYS_INLINE AutoSIMD &operator+=(const AutoSIMD &v)
69  {
70  m512d = _mm512_add_pd(m512d,v.m512d);
71  return *this;
72  }
73 
74  inline MFEM_ALWAYS_INLINE AutoSIMD &operator+=(const double &e)
75  {
76  m512d = _mm512_add_pd(m512d,_mm512_set1_pd(e));
77  return *this;
78  }
79 
80  inline MFEM_ALWAYS_INLINE AutoSIMD &operator-=(const AutoSIMD &v)
81  {
82  m512d = _mm512_sub_pd(m512d,v.m512d);
83  return *this;
84  }
85 
86  inline MFEM_ALWAYS_INLINE AutoSIMD &operator-=(const double &e)
87  {
88  m512d = _mm512_sub_pd(m512d,_mm512_set1_pd(e));
89  return *this;
90  }
91 
92  inline MFEM_ALWAYS_INLINE AutoSIMD &operator*=(const AutoSIMD &v)
93  {
94  m512d = _mm512_mul_pd(m512d,v.m512d);
95  return *this;
96  }
97 
98  inline MFEM_ALWAYS_INLINE AutoSIMD &operator*=(const double &e)
99  {
100  m512d = _mm512_mul_pd(m512d,_mm512_set1_pd(e));
101  return *this;
102  }
103 
104  inline MFEM_ALWAYS_INLINE AutoSIMD &operator/=(const AutoSIMD &v)
105  {
106  m512d = _mm512_div_pd(m512d,v.m512d);
107  return *this;
108  }
109 
110  inline MFEM_ALWAYS_INLINE AutoSIMD &operator/=(const double &e)
111  {
112  m512d = _mm512_div_pd(m512d,_mm512_set1_pd(e));
113  return *this;
114  }
115 
116  inline MFEM_ALWAYS_INLINE AutoSIMD operator-() const
117  {
118  AutoSIMD r;
119 #ifdef __AVX512DQ__
120  r.m512d = _mm512_xor_pd(_mm512_set1_pd(-0.0), m512d);
121 #else
122  r.m512d = _mm512_sub_pd(_mm512_set1_pd(0.0), m512d);
123 #endif
124  return r;
125  }
126 
127  inline MFEM_ALWAYS_INLINE AutoSIMD operator+() const
128  {
129  return *this;
130  }
131 
132  inline MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const
133  {
134  AutoSIMD r;
135  r.m512d = _mm512_add_pd(m512d,v.m512d);
136  return r;
137  }
138 
139  inline MFEM_ALWAYS_INLINE AutoSIMD operator+(const double &e) const
140  {
141  AutoSIMD r;
142  r.m512d = _mm512_add_pd(m512d, _mm512_set1_pd(e));
143  return r;
144  }
145 
146  inline MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const
147  {
148  AutoSIMD r;
149  r.m512d = _mm512_sub_pd(m512d,v.m512d);
150  return r;
151  }
152 
153  inline MFEM_ALWAYS_INLINE AutoSIMD operator-(const double &e) const
154  {
155  AutoSIMD r;
156  r.m512d = _mm512_sub_pd(m512d, _mm512_set1_pd(e));
157  return r;
158  }
159 
160  inline MFEM_ALWAYS_INLINE AutoSIMD operator*(const AutoSIMD &v) const
161  {
162  AutoSIMD r;
163  r.m512d = _mm512_mul_pd(m512d,v.m512d);
164  return r;
165  }
166 
167  inline MFEM_ALWAYS_INLINE AutoSIMD operator*(const double &e) const
168  {
169  AutoSIMD r;
170  r.m512d = _mm512_mul_pd(m512d, _mm512_set1_pd(e));
171  return r;
172  }
173 
174  inline MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const
175  {
176  AutoSIMD r;
177  r.m512d = _mm512_div_pd(m512d,v.m512d);
178  return r;
179  }
180 
181  inline MFEM_ALWAYS_INLINE AutoSIMD operator/(const double &e) const
182  {
183  AutoSIMD r;
184  r.m512d = _mm512_div_pd(m512d, _mm512_set1_pd(e));
185  return r;
186  }
187 
188  inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const AutoSIMD &v, const AutoSIMD &w)
189  {
190  m512d = _mm512_fmadd_pd(w.m512d,v.m512d,m512d);
191  return *this;
192  }
193 
194  inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const AutoSIMD &v, const double &e)
195  {
196  m512d = _mm512_fmadd_pd(_mm512_set1_pd(e),v.m512d,m512d);
197  return *this;
198  }
199 
200  inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const double &e, const AutoSIMD &v)
201  {
202  m512d = _mm512_fmadd_pd(v.m512d,_mm512_set1_pd(e),m512d);
203  return *this;
204  }
205 
206  inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const AutoSIMD &v, const AutoSIMD &w)
207  {
208  m512d = _mm512_mul_pd(v.m512d,w.m512d);
209  return *this;
210  }
211 
212  inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const AutoSIMD &v, const double &e)
213  {
214  m512d = _mm512_mul_pd(v.m512d,_mm512_set1_pd(e));
215  return *this;
216  }
217 
218  inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const double &e, const AutoSIMD &v)
219  {
220  m512d = _mm512_mul_pd(_mm512_set1_pd(e),v.m512d);
221  return *this;
222  }
223 };
224 
225 inline MFEM_ALWAYS_INLINE
227  const AutoSIMD<double,8,64> &v)
228 {
230  r.m512d = _mm512_add_pd(_mm512_set1_pd(e),v.m512d);
231  return r;
232 }
233 
234 inline MFEM_ALWAYS_INLINE
236  const AutoSIMD<double,8,64> &v)
237 {
239  r.m512d = _mm512_sub_pd(_mm512_set1_pd(e),v.m512d);
240  return r;
241 }
242 
243 inline MFEM_ALWAYS_INLINE
245  const AutoSIMD<double,8,64> &v)
246 {
248  r.m512d = _mm512_mul_pd(_mm512_set1_pd(e),v.m512d);
249  return r;
250 }
251 
252 inline MFEM_ALWAYS_INLINE
254  const AutoSIMD<double,8,64> &v)
255 {
257  r.m512d = _mm512_div_pd(_mm512_set1_pd(e),v.m512d);
258  return r;
259 }
260 
261 } // namespace mfem
262 
263 #endif // __AVX512F__
264 
265 #endif // MFEM_SIMD_M512_HPP
MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const
Definition: m512.hpp:132
MFEM_ALWAYS_INLINE AutoSIMD & fma(const double &e, const AutoSIMD &v)
Definition: m512.hpp:200
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const double &e)
Definition: m512.hpp:62
MFEM_ALWAYS_INLINE AutoSIMD & fma(const AutoSIMD &v, const double &e)
Definition: m512.hpp:194
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 & mul(const AutoSIMD &v, const AutoSIMD &w)
Definition: m512.hpp:206
static const int size
Definition: auto.hpp:27
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const double &e)
Definition: m512.hpp:110
MFEM_ALWAYS_INLINE AutoSIMD operator*(const double &e) const
Definition: m512.hpp:167
MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const
Definition: m512.hpp:146
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const AutoSIMD &v)
Definition: m512.hpp:68
MFEM_ALWAYS_INLINE AutoSIMD & fma(const AutoSIMD &v, const AutoSIMD &w)
Definition: m512.hpp:188
scalar_t vec[size]
Definition: auto.hpp:30
MFEM_ALWAYS_INLINE const double & operator[](int i) const
Definition: m512.hpp:51
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 double &e) const
Definition: m512.hpp:139
MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const
Definition: m512.hpp:174
MFEM_ALWAYS_INLINE AutoSIMD operator-() const
Definition: m512.hpp:116
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const double &e)
Definition: m512.hpp:212
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const double &e)
Definition: m512.hpp:74
static const int align_bytes
Definition: auto.hpp:28
MFEM_ALWAYS_INLINE AutoSIMD operator+() const
Definition: m512.hpp:127
MFEM_ALWAYS_INLINE double & operator[](int i)
Definition: m512.hpp:46
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const AutoSIMD &v)
Definition: m512.hpp:80
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const AutoSIMD &v)
Definition: m512.hpp:104
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const AutoSIMD &v)
Definition: m512.hpp:56
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const AutoSIMD &v)
Definition: m512.hpp:92
MFEM_ALWAYS_INLINE AutoSIMD & mul(const double &e, const AutoSIMD &v)
Definition: m512.hpp:218
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const double &e)
Definition: m512.hpp:98
MFEM_ALWAYS_INLINE AutoSIMD operator*(const AutoSIMD &v) const
Definition: m512.hpp:160
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const double &e)
Definition: m512.hpp:86
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 AutoSIMD operator/(const double &e) const
Definition: m512.hpp:181
MFEM_ALWAYS_INLINE AutoSIMD operator-(const double &e) const
Definition: m512.hpp:153