MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
auto.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_AUTO_HPP
13#define MFEM_SIMD_AUTO_HPP
14
16
17namespace mfem
18{
19
20// Use this macro as a workaround for astyle formatting issue with 'alignas'
21#define MFEM_AUTOSIMD_ALIGN__ alignas(align_bytes_)
22
23template <typename scalar_t, int S, int align_bytes_>
24struct MFEM_AUTOSIMD_ALIGN__ AutoSIMD
25{
26 typedef scalar_t scalar_type;
27 static const int size = S;
28 static const int align_bytes = align_bytes_;
29
30 scalar_t vec[size];
31
32 AutoSIMD() = default;
33
34 AutoSIMD(const AutoSIMD &) = default;
35
36 inline MFEM_ALWAYS_INLINE scalar_t &operator[](int i)
37 {
38 return vec[i];
39 }
40
41 inline MFEM_ALWAYS_INLINE const scalar_t &operator[](int i) const
42 {
43 return vec[i];
44 }
45
46 inline MFEM_ALWAYS_INLINE AutoSIMD &operator=(const AutoSIMD &v)
47 {
48 MFEM_VECTORIZE_LOOP
49 for (int i = 0; i < size; i++) { vec[i] = v[i]; }
50 return *this;
51 }
52
53 inline MFEM_ALWAYS_INLINE AutoSIMD &operator=(const scalar_t &e)
54 {
55 MFEM_VECTORIZE_LOOP
56 for (int i = 0; i < size; i++) { vec[i] = e; }
57 return *this;
58 }
59
60 inline MFEM_ALWAYS_INLINE AutoSIMD &operator+=(const AutoSIMD &v)
61 {
62 MFEM_VECTORIZE_LOOP
63 for (int i = 0; i < size; i++) { vec[i] += v[i]; }
64 return *this;
65 }
66
67 inline MFEM_ALWAYS_INLINE AutoSIMD &operator+=(const scalar_t &e)
68 {
69 MFEM_VECTORIZE_LOOP
70 for (int i = 0; i < size; i++) { vec[i] += e; }
71 return *this;
72 }
73
74 inline MFEM_ALWAYS_INLINE AutoSIMD &operator-=(const AutoSIMD &v)
75 {
76 MFEM_VECTORIZE_LOOP
77 for (int i = 0; i < size; i++) { vec[i] -= v[i]; }
78 return *this;
79 }
80
81 inline MFEM_ALWAYS_INLINE AutoSIMD &operator-=(const scalar_t &e)
82 {
83 MFEM_VECTORIZE_LOOP
84 for (int i = 0; i < size; i++) { vec[i] -= e; }
85 return *this;
86 }
87
88 inline MFEM_ALWAYS_INLINE AutoSIMD &operator*=(const AutoSIMD &v)
89 {
90 MFEM_VECTORIZE_LOOP
91 for (int i = 0; i < size; i++) { vec[i] *= v[i]; }
92 return *this;
93 }
94
95 inline MFEM_ALWAYS_INLINE AutoSIMD &operator*=(const scalar_t &e)
96 {
97 MFEM_VECTORIZE_LOOP
98 for (int i = 0; i < size; i++) { vec[i] *= e; }
99 return *this;
100 }
101
102 inline MFEM_ALWAYS_INLINE AutoSIMD &operator/=(const AutoSIMD &v)
103 {
104 MFEM_VECTORIZE_LOOP
105 for (int i = 0; i < size; i++) { vec[i] /= v[i]; }
106 return *this;
107 }
108
109 inline MFEM_ALWAYS_INLINE AutoSIMD &operator/=(const scalar_t &e)
110 {
111 MFEM_VECTORIZE_LOOP
112 for (int i = 0; i < size; i++) { vec[i] /= e; }
113 return *this;
114 }
115
116 inline MFEM_ALWAYS_INLINE AutoSIMD operator-() const
117 {
118 AutoSIMD r;
119 MFEM_VECTORIZE_LOOP
120 for (int i = 0; i < size; i++) { r[i] = -vec[i]; }
121 return r;
122 }
123
124 inline MFEM_ALWAYS_INLINE AutoSIMD operator+() const
125 {
126 return *this;
127 }
128
129 inline MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const
130 {
131 AutoSIMD r;
132 MFEM_VECTORIZE_LOOP
133 for (int i = 0; i < size; i++) { r[i] = vec[i] + v[i]; }
134 return r;
135 }
136
137 inline MFEM_ALWAYS_INLINE AutoSIMD operator+(const scalar_t &e) const
138 {
139 AutoSIMD r;
140 MFEM_VECTORIZE_LOOP
141 for (int i = 0; i < size; i++) { r[i] = vec[i] + e; }
142 return r;
143 }
144
145 inline MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const
146 {
147 AutoSIMD r;
148 MFEM_VECTORIZE_LOOP
149 for (int i = 0; i < size; i++) { r[i] = vec[i] - v[i]; }
150 return r;
151 }
152
153 inline MFEM_ALWAYS_INLINE AutoSIMD operator-(const scalar_t &e) const
154 {
155 AutoSIMD r;
156 MFEM_VECTORIZE_LOOP
157 for (int i = 0; i < size; i++) { r[i] = vec[i] - e; }
158 return r;
159 }
160
161 inline MFEM_ALWAYS_INLINE AutoSIMD operator*(const AutoSIMD &v) const
162 {
163 AutoSIMD r;
164 MFEM_VECTORIZE_LOOP
165 for (int i = 0; i < size; i++) { r[i] = vec[i] * v[i]; }
166 return r;
167 }
168
169 inline MFEM_ALWAYS_INLINE AutoSIMD operator*(const scalar_t &e) const
170 {
171 AutoSIMD r;
172 MFEM_VECTORIZE_LOOP
173 for (int i = 0; i < size; i++) { r[i] = vec[i] * e; }
174 return r;
175 }
176
177 inline MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const
178 {
179 AutoSIMD r;
180 MFEM_VECTORIZE_LOOP
181 for (int i = 0; i < size; i++) { r[i] = vec[i] / v[i]; }
182 return r;
183 }
184
185 inline MFEM_ALWAYS_INLINE AutoSIMD operator/(const scalar_t &e) const
186 {
187 AutoSIMD r;
188 MFEM_VECTORIZE_LOOP
189 for (int i = 0; i < size; i++) { r[i] = vec[i] / e; }
190 return r;
191 }
192
193 inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const AutoSIMD &v, const AutoSIMD &w)
194 {
195 MFEM_VECTORIZE_LOOP
196 for (int i = 0; i < size; i++) { vec[i] += v[i] * w[i]; }
197 return *this;
198 }
199
200 inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const AutoSIMD &v, const scalar_t &e)
201 {
202 MFEM_VECTORIZE_LOOP
203 for (int i = 0; i < size; i++) { vec[i] += v[i] * e; }
204 return *this;
205 }
206
207 inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const scalar_t &e, const AutoSIMD &v)
208 {
209 MFEM_VECTORIZE_LOOP
210 for (int i = 0; i < size; i++) { vec[i] += e * v[i]; }
211 return *this;
212 }
213
214 inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const AutoSIMD &v, const AutoSIMD &w)
215 {
216 MFEM_VECTORIZE_LOOP
217 for (int i = 0; i < size; i++) { vec[i] = v[i] * w[i]; }
218 return *this;
219 }
220
221 inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const AutoSIMD &v, const scalar_t &e)
222 {
223 MFEM_VECTORIZE_LOOP
224 for (int i = 0; i < size; i++) { vec[i] = v[i] * e; }
225 return *this;
226 }
227
228 inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const scalar_t &e, const AutoSIMD &v)
229 {
230 MFEM_VECTORIZE_LOOP
231 for (int i = 0; i < size; i++) { vec[i] = e * v[i]; }
232 return *this;
233 }
234};
235
236template <typename scalar_t, int S, int A>
237inline MFEM_ALWAYS_INLINE
239 const AutoSIMD<scalar_t,S,A> &v)
240{
242 MFEM_VECTORIZE_LOOP
243 for (int i = 0; i < S; i++) { r[i] = e + v[i]; }
244 return r;
245}
246
247template <typename scalar_t, int S, int A>
248inline MFEM_ALWAYS_INLINE
250 const AutoSIMD<scalar_t,S,A> &v)
251{
253 MFEM_VECTORIZE_LOOP
254 for (int i = 0; i < S; i++) { r[i] = e - v[i]; }
255 return r;
256}
257
258template <typename scalar_t, int S, int A>
259inline MFEM_ALWAYS_INLINE
261 const AutoSIMD<scalar_t,S,A> &v)
262{
264 MFEM_VECTORIZE_LOOP
265 for (int i = 0; i < S; i++) { r[i] = e * v[i]; }
266 return r;
267}
268
269template <typename scalar_t, int S, int A>
270inline MFEM_ALWAYS_INLINE
272 const AutoSIMD<scalar_t,S,A> &v)
273{
275 MFEM_VECTORIZE_LOOP
276 for (int i = 0; i < S; i++) { r[i] = e / v[i]; }
277 return r;
278}
279
280} // namespace mfem
281
282#endif // MFEM_SIMD_AUTO_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 scalar_t &e) const
Definition auto.hpp:153
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const scalar_t &e)
Definition auto.hpp:53
AutoSIMD()=default
MFEM_ALWAYS_INLINE AutoSIMD operator*(const AutoSIMD &v) const
Definition auto.hpp:161
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const AutoSIMD &v)
Definition auto.hpp:102
MFEM_ALWAYS_INLINE AutoSIMD operator+(const scalar_t &e) const
Definition auto.hpp:137
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const scalar_t &e)
Definition auto.hpp:67
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const AutoSIMD &v)
Definition auto.hpp:46
MFEM_ALWAYS_INLINE AutoSIMD operator-() const
Definition auto.hpp:116
AutoSIMD(const AutoSIMD &)=default
MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const
Definition auto.hpp:129
scalar_t scalar_type
Definition auto.hpp:26
MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const
Definition auto.hpp:145
MFEM_ALWAYS_INLINE AutoSIMD & fma(const AutoSIMD &v, const AutoSIMD &w)
Definition auto.hpp:193
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const scalar_t &e)
Definition auto.hpp:95
MFEM_ALWAYS_INLINE scalar_t & operator[](int i)
Definition auto.hpp:36
MFEM_ALWAYS_INLINE AutoSIMD & fma(const AutoSIMD &v, const scalar_t &e)
Definition auto.hpp:200
MFEM_ALWAYS_INLINE AutoSIMD & fma(const scalar_t &e, const AutoSIMD &v)
Definition auto.hpp:207
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const AutoSIMD &v)
Definition auto.hpp:74
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const scalar_t &e)
Definition auto.hpp:81
MFEM_ALWAYS_INLINE AutoSIMD operator+() const
Definition auto.hpp:124
MFEM_ALWAYS_INLINE AutoSIMD & mul(const scalar_t &e, const AutoSIMD &v)
Definition auto.hpp:228
MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const
Definition auto.hpp:177
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const AutoSIMD &v)
Definition auto.hpp:60
MFEM_ALWAYS_INLINE AutoSIMD operator/(const scalar_t &e) const
Definition auto.hpp:185
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const AutoSIMD &w)
Definition auto.hpp:214
MFEM_ALWAYS_INLINE const scalar_t & operator[](int i) const
Definition auto.hpp:41
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const AutoSIMD &v)
Definition auto.hpp:88
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const scalar_t &e)
Definition auto.hpp:221
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const scalar_t &e)
Definition auto.hpp:109
MFEM_ALWAYS_INLINE AutoSIMD operator*(const scalar_t &e) const
Definition auto.hpp:169