MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
m512.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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
25namespace mfem
26{
27
28template <typename, int, int> struct AutoSIMD;
29
30template <> 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
225inline 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
234inline 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
243inline 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
252inline 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
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:238
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< 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 double &e)
Definition: m512.hpp:98
AutoSIMD(const AutoSIMD &)=default
MFEM_ALWAYS_INLINE const double & operator[](int i) const
Definition: m512.hpp:51
MFEM_ALWAYS_INLINE AutoSIMD operator+() const
Definition: m512.hpp:127
MFEM_ALWAYS_INLINE AutoSIMD & fma(const double &e, const AutoSIMD &v)
Definition: m512.hpp:200
MFEM_ALWAYS_INLINE AutoSIMD operator*(const AutoSIMD &v) const
Definition: m512.hpp:160
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const AutoSIMD &v)
Definition: m512.hpp:56
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const AutoSIMD &v)
Definition: m512.hpp:80
MFEM_ALWAYS_INLINE AutoSIMD & fma(const AutoSIMD &v, const AutoSIMD &w)
Definition: m512.hpp:188
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const double &e)
Definition: m512.hpp:86
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const double &e)
Definition: m512.hpp:74
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const AutoSIMD &v)
Definition: m512.hpp:68
MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const
Definition: m512.hpp:132
MFEM_ALWAYS_INLINE AutoSIMD operator/(const double &e) const
Definition: m512.hpp:181
MFEM_ALWAYS_INLINE AutoSIMD & fma(const AutoSIMD &v, const double &e)
Definition: m512.hpp:194
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const double &e)
Definition: m512.hpp:62
MFEM_ALWAYS_INLINE double & operator[](int i)
Definition: m512.hpp:46
MFEM_ALWAYS_INLINE AutoSIMD operator+(const double &e) const
Definition: m512.hpp:139
MFEM_ALWAYS_INLINE AutoSIMD operator-() const
Definition: m512.hpp:116
MFEM_ALWAYS_INLINE AutoSIMD operator*(const double &e) const
Definition: m512.hpp:167
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const AutoSIMD &v)
Definition: m512.hpp:92
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const double &e)
Definition: m512.hpp:110
MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const
Definition: m512.hpp:146
MFEM_ALWAYS_INLINE AutoSIMD operator-(const double &e) const
Definition: m512.hpp:153
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const AutoSIMD &v)
Definition: m512.hpp:104
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const double &e)
Definition: m512.hpp:212
MFEM_ALWAYS_INLINE AutoSIMD & mul(const double &e, const AutoSIMD &v)
Definition: m512.hpp:218
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const AutoSIMD &w)
Definition: m512.hpp:206
MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const
Definition: m512.hpp:174
scalar_t vec[size]
Definition: auto.hpp:30
static const int size
Definition: auto.hpp:27
static const int align_bytes
Definition: auto.hpp:28