MFEM  v4.6.0
Finite element discretization library
vsx128.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_VSX128_HPP
13 #define MFEM_SIMD_VSX128_HPP
14 
15 #ifdef __VSX__
16 
17 #include "../../config/tconfig.hpp"
18 #include <altivec.h>
19 
20 #ifdef __GNUC__
21 #undef bool
22 #endif
23 
24 namespace mfem
25 {
26 
27 template <typename,int,int> struct AutoSIMD;
28 
29 template <> struct AutoSIMD<double,2,16>
30 {
31  typedef double scalar_type;
32  static constexpr int size = 2;
33  static constexpr int align_bytes = 16;
34 
35  union
36  {
37  vector double vd;
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  vd = v.vd;
58  return *this;
59  }
60 
61  inline MFEM_ALWAYS_INLINE AutoSIMD &operator=(const double &e)
62  {
63  vd = vec_splats(e);
64  return *this;
65  }
66 
67  inline MFEM_ALWAYS_INLINE AutoSIMD &operator+=(const AutoSIMD &v)
68  {
69  vd = vec_add(vd,v.vd);
70  return *this;
71  }
72 
73  inline MFEM_ALWAYS_INLINE AutoSIMD &operator+=(const double &e)
74  {
75  vd = vec_add(vd,vec_splats(e));
76  return *this;
77  }
78 
79  inline MFEM_ALWAYS_INLINE AutoSIMD &operator-=(const AutoSIMD &v)
80  {
81  vd = vec_sub(vd,v.vd);
82  return *this;
83  }
84 
85  inline MFEM_ALWAYS_INLINE AutoSIMD &operator-=(const double &e)
86  {
87  vd = vec_sub(vd,vec_splats(e));
88  return *this;
89  }
90 
91  inline MFEM_ALWAYS_INLINE AutoSIMD &operator*=(const AutoSIMD &v)
92  {
93  vd = vec_mul(vd,v.vd);
94  return *this;
95  }
96 
97  inline MFEM_ALWAYS_INLINE AutoSIMD &operator*=(const double &e)
98  {
99  vd = vec_mul(vd,vec_splats(e));
100  return *this;
101  }
102 
103  inline MFEM_ALWAYS_INLINE AutoSIMD &operator/=(const AutoSIMD &v)
104  {
105  vd = vec_div(vd,v.vd);
106  return *this;
107  }
108 
109  inline MFEM_ALWAYS_INLINE AutoSIMD &operator/=(const double &e)
110  {
111  vd = vec_div(vd,vec_splats(e));
112  return *this;
113  }
114 
115  inline MFEM_ALWAYS_INLINE AutoSIMD operator-() const
116  {
117  AutoSIMD r;
118 #ifndef __GNUC__
119  r.vd = vec_neg(vd);
120 #else
121  r.vd = vec_splats(0.0) - vd;
122 #endif
123  return r;
124  }
125 
126  inline MFEM_ALWAYS_INLINE AutoSIMD operator+() const
127  {
128  return *this;
129  }
130 
131  inline MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const
132  {
133  AutoSIMD r;
134  r.vd = vec_add(vd,v.vd);
135  return r;
136  }
137 
138  inline MFEM_ALWAYS_INLINE AutoSIMD operator+(const double &e) const
139  {
140  AutoSIMD r;
141  r.vd = vec_add(vd, vec_splats(e));
142  return r;
143  }
144 
145  inline MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const
146  {
147  AutoSIMD r;
148  r.vd = vec_sub(vd,v.vd);
149  return r;
150  }
151 
152  inline MFEM_ALWAYS_INLINE AutoSIMD operator-(const double &e) const
153  {
154  AutoSIMD r;
155  r.vd = vec_sub(vd, vec_splats(e));
156  return r;
157  }
158 
159  inline MFEM_ALWAYS_INLINE AutoSIMD operator*(const AutoSIMD &v) const
160  {
161  AutoSIMD r;
162  r.vd = vec_mul(vd,v.vd);
163  return r;
164  }
165 
166  inline MFEM_ALWAYS_INLINE AutoSIMD operator*(const double &e) const
167  {
168  AutoSIMD r;
169  r.vd = vec_mul(vd, vec_splats(e));
170  return r;
171  }
172 
173  inline MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const
174  {
175  AutoSIMD r;
176  r.vd = vec_div(vd,v.vd);
177  return r;
178  }
179 
180  inline MFEM_ALWAYS_INLINE AutoSIMD operator/(const double &e) const
181  {
182  AutoSIMD r;
183  r.vd = vec_div(vd, vec_splats(e));
184  return r;
185  }
186 
187  inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const AutoSIMD &v, const AutoSIMD &w)
188  {
189  vd = vec_madd(w.vd,vd,v.vd);
190  return *this;
191  }
192 
193  inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const AutoSIMD &v, const double &e)
194  {
195  vd = vec_madd(v.vd,vec_splats(e),vd);
196  return *this;
197  }
198 
199  inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const double &e, const AutoSIMD &v)
200  {
201  vd = vec_madd(vec_splats(e),v.vd,vd);
202  return *this;
203  }
204 
205  inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const AutoSIMD &v, const AutoSIMD &w)
206  {
207  vd = vec_mul(v.vd,w.vd);
208  return *this;
209  }
210 
211  inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const AutoSIMD &v, const double &e)
212  {
213  vd = vec_mul(v.vd,vec_splats(e));
214  return *this;
215  }
216 
217  inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const double &e, const AutoSIMD &v)
218  {
219  vd = vec_mul(vec_splats(e),v.vd);
220  return *this;
221  }
222 };
223 
224 inline MFEM_ALWAYS_INLINE
225 AutoSIMD<double,2,16> operator+(const double &e,
226  const AutoSIMD<double,2,16> &v)
227 {
228  AutoSIMD<double,2,16> r;
229  r.vd = vec_add(vec_splats(e),v.vd);
230  return r;
231 }
232 
233 inline MFEM_ALWAYS_INLINE
234 AutoSIMD<double,2,16> operator-(const double &e,
235  const AutoSIMD<double,2,16> &v)
236 {
237  AutoSIMD<double,2,16> r;
238  r.vd = vec_sub(vec_splats(e),v.vd);
239  return r;
240 }
241 
242 inline MFEM_ALWAYS_INLINE
243 AutoSIMD<double,2,16> operator*(const double &e,
244  const AutoSIMD<double,2,16> &v)
245 {
246  AutoSIMD<double,2,16> r;
247  r.vd = vec_mul(vec_splats(e),v.vd);
248  return r;
249 }
250 
251 inline MFEM_ALWAYS_INLINE
252 AutoSIMD<double,2,16> operator/(const double &e,
253  const AutoSIMD<double,2,16> &v)
254 {
255  AutoSIMD<double,2,16> r;
256  r.vd = vec_div(vec_splats(e),v.vd);
257  return r;
258 }
259 
260 } // namespace mfem
261 
262 #endif // __VSX__
263 
264 #endif // MFEM_SIMD_VSX128_HPP
MFEM_ALWAYS_INLINE AutoSIMD operator*(const double &e) const
Definition: vsx128.hpp:166
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const AutoSIMD &w)
Definition: vsx128.hpp:205
MFEM_ALWAYS_INLINE AutoSIMD operator/(const double &e) const
Definition: vsx128.hpp:180
MFEM_ALWAYS_INLINE AutoSIMD operator*(const AutoSIMD &v) const
Definition: vsx128.hpp:159
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const double &e)
Definition: vsx128.hpp:109
MFEM_ALWAYS_INLINE const double & operator[](int i) const
Definition: vsx128.hpp:50
MFEM_ALWAYS_INLINE AutoSIMD operator+(const double &e) const
Definition: vsx128.hpp:138
MFEM_ALWAYS_INLINE AutoSIMD & operator/=(const AutoSIMD &v)
Definition: vsx128.hpp:103
MFEM_ALWAYS_INLINE AutoSIMD & mul(const double &e, const AutoSIMD &v)
Definition: vsx128.hpp:217
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 & fma(const AutoSIMD &v, const AutoSIMD &w)
Definition: vsx128.hpp:187
static const int size
Definition: auto.hpp:27
MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const
Definition: vsx128.hpp:131
scalar_t vec[size]
Definition: auto.hpp:30
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)
Definition: vsx128.hpp:61
MFEM_ALWAYS_INLINE AutoSIMD & fma(const AutoSIMD &v, const double &e)
Definition: vsx128.hpp:193
MFEM_ALWAYS_INLINE AutoSIMD operator+() const
Definition: vsx128.hpp:126
static const int align_bytes
Definition: auto.hpp:28
MFEM_ALWAYS_INLINE AutoSIMD & fma(const double &e, const AutoSIMD &v)
Definition: vsx128.hpp:199
MFEM_ALWAYS_INLINE AutoSIMD operator-(const double &e) const
Definition: vsx128.hpp:152
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const double &e)
Definition: vsx128.hpp:97
MFEM_ALWAYS_INLINE double & operator[](int i)
Definition: vsx128.hpp:45
MFEM_ALWAYS_INLINE AutoSIMD operator-() const
Definition: vsx128.hpp:115
MFEM_ALWAYS_INLINE AutoSIMD & operator+=(const AutoSIMD &v)
Definition: vsx128.hpp:67
MFEM_ALWAYS_INLINE AutoSIMD & operator*=(const AutoSIMD &v)
Definition: vsx128.hpp:91
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const double &e)
Definition: vsx128.hpp:85
MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const
Definition: vsx128.hpp:145
MFEM_ALWAYS_INLINE AutoSIMD & operator=(const AutoSIMD &v)
Definition: vsx128.hpp:55
MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const
Definition: vsx128.hpp:173
MFEM_ALWAYS_INLINE AutoSIMD & operator-=(const AutoSIMD &v)
Definition: vsx128.hpp:79
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)
Definition: vsx128.hpp:73
MFEM_ALWAYS_INLINE AutoSIMD & mul(const AutoSIMD &v, const double &e)
Definition: vsx128.hpp:211