MFEM  v4.5.2
Finite element discretization library
auto.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, 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 
15 #include "../../config/tconfig.hpp"
16 
17 namespace 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 
23 template <typename scalar_t, int S, int align_bytes_>
24 struct 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 
236 template <typename scalar_t, int S, int A>
237 inline 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 
247 template <typename scalar_t, int S, int A>
248 inline 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 
258 template <typename scalar_t, int S, int A>
259 inline 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 
269 template <typename scalar_t, int S, int A>
270 inline 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
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const scalar_t &e)
Definition: auto.hpp:81
scalar_t scalar_type
Definition: auto.hpp:26
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const scalar_t &e)
Definition: auto.hpp:95
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:169
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const AutoSIMD &v)
Definition: auto.hpp:74
MFEM_ALWAYS_INLINE AutoSIMD operator+() const
Definition: auto.hpp:124
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) const
Definition: auto.hpp:161
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const AutoSIMD &v)
Definition: auto.hpp:60
MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const
Definition: auto.hpp:177
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const AutoSIMD &v)
Definition: auto.hpp:88
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const AutoSIMD &v)
Definition: auto.hpp:46
MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const
Definition: auto.hpp:145
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const scalar_t &e)
Definition: auto.hpp:109
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const AutoSIMD &w)
Definition: auto.hpp:214
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const scalar_t &e)
Definition: auto.hpp:67
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const scalar_t &e)
Definition: auto.hpp:221
MFEM_ALWAYS_INLINE AutoSIMD operator-() const
Definition: auto.hpp:116
MFEM_ALWAYS_INLINE scalar_t & operator[](int i)
Definition: auto.hpp:36
MFEM_ALWAYS_INLINE AutoSIMD & fma(const scalar_t &e, const AutoSIMD &v)
Definition: auto.hpp:207
MFEM_ALWAYS_INLINE const scalar_t & operator[](int i) const
Definition: auto.hpp:41
MFEM_ALWAYS_INLINE AutoSIMD & mul(const scalar_t &e, const AutoSIMD &v)
Definition: auto.hpp:228
MFEM_ALWAYS_INLINE AutoSIMD operator-(const scalar_t &e) const
Definition: auto.hpp:153
MFEM_ALWAYS_INLINE AutoSIMD & fma(const AutoSIMD &v, const AutoSIMD &w)
Definition: auto.hpp:193
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 & fma(const AutoSIMD &v, const scalar_t &e)
Definition: auto.hpp:200
MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const
Definition: auto.hpp:129
MFEM_ALWAYS_INLINE AutoSIMD operator/(const scalar_t &e) const
Definition: auto.hpp:185
MemoryClass operator*(MemoryClass mc1, MemoryClass mc2)
Return a suitable MemoryClass from a pair of MemoryClasses.
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const scalar_t &e)
Definition: auto.hpp:53
MFEM_ALWAYS_INLINE AutoSIMD< scalar_t, S, A > operator-(const scalar_t &e, const AutoSIMD< scalar_t, S, A > &v)
Definition: auto.hpp:249