XGC1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
simd.hpp
Go to the documentation of this file.
1 #ifndef SIMD_HPP
2 #define SIMD_HPP
3 #include <Kokkos_Core.hpp>
4 
5 /*** SIMD structures ****/
6 
7 // Use simd pragma on CPU
8 #ifdef USE_GPU
9 #define FORCE_SIMD
10 #else
11 #define FORCE_SIMD _Pragma("omp simd")
12 #endif
13 
14 
15 
16 // A 1-dimension array of size SIMD_SIZE and type T
17 template<typename T>
18 struct Simd{
19  T x[SIMD_SIZE];
20 
21  // Constructors
22  KOKKOS_INLINE_FUNCTION Simd<T>(){}
23  KOKKOS_INLINE_FUNCTION Simd<T>(T initval){
24  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) x[i_simd] = initval;
25  }
26 
27  // Allows array-like access pattern
28  KOKKOS_INLINE_FUNCTION T operator [](int i) const {return x[i];}
29  KOKKOS_INLINE_FUNCTION T& operator [](int i) {return x[i];}
30 
31  // Basic operations
32  // Assignment from scalar
33  template<typename Trhs>
34  KOKKOS_INLINE_FUNCTION void operator = (const Trhs rhs) {
35  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) x[i_simd] = rhs;
36  // Void return, chaining not enabled
37  }
38 
39  KOKKOS_INLINE_FUNCTION Simd<T> operator - () const {
40  Simd<T> out;
41  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = -x[i_simd];
42  return out;
43  }
44 
45  template<typename Trhs>
46  KOKKOS_INLINE_FUNCTION Simd<T> operator - (const Simd<Trhs>& rhs) const {
47  Simd<T> out;
48  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = x[i_simd] - rhs[i_simd];
49  return out;
50  }
51 
52  template<typename Trhs>
53  KOKKOS_INLINE_FUNCTION Simd<T> operator + (const Simd<Trhs>& rhs) const {
54  Simd<T> out;
55  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = x[i_simd] + rhs[i_simd];
56  return out;
57  }
58 
59  template<typename Trhs>
60  KOKKOS_INLINE_FUNCTION Simd<T> operator * (const Simd<Trhs>& rhs) const {
61  Simd<T> out;
62  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = x[i_simd] * rhs[i_simd];
63  return out;
64  }
65 
66  template<typename Trhs>
67  KOKKOS_INLINE_FUNCTION Simd<T> operator / (const Simd<Trhs>& rhs) const {
68  Simd<T> out;
69  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = x[i_simd] / rhs[i_simd];
70  return out;
71  }
72 
73  // Other operations
74 
75  // Sets values to 0.0
76  KOKKOS_INLINE_FUNCTION void zero(){
77  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) x[i_simd] = 0.0;
78  }
79 };
80 
81 // Operators with non-Simd argument
82 template<typename T>
83 KOKKOS_INLINE_FUNCTION Simd<T> operator - (const Simd<T>& lhs, const T rhs) {
84  Simd<T> out;
85  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = lhs.x[i_simd] - rhs;
86  return out;
87 }
88 
89 template<typename T>
90 KOKKOS_INLINE_FUNCTION Simd<T> operator - (const T lhs, const Simd<T>& rhs) {
91  Simd<T> out;
92  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = lhs - rhs.x[i_simd];
93  return out;
94 }
95 
96 template<typename T>
97 KOKKOS_INLINE_FUNCTION Simd<T> operator + (const Simd<T>& lhs, const T rhs) {
98  Simd<T> out;
99  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = lhs.x[i_simd] + rhs;
100  return out;
101 }
102 
103 template<typename T>
104 KOKKOS_INLINE_FUNCTION Simd<T> operator + (const T lhs, const Simd<T>& rhs) {
105  Simd<T> out;
106  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = lhs + rhs.x[i_simd];
107  return out;
108 }
109 
110 template<typename T>
111 KOKKOS_INLINE_FUNCTION Simd<T> operator * (const Simd<T>& lhs, const T rhs) {
112  Simd<T> out;
113  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = lhs.x[i_simd] * rhs;
114  return out;
115 }
116 
117 template<typename T>
118 KOKKOS_INLINE_FUNCTION Simd<T> operator * (const T lhs, const Simd<T>& rhs) {
119  Simd<T> out;
120  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = lhs * rhs.x[i_simd];
121  return out;
122 }
123 
124 template<typename T>
125 KOKKOS_INLINE_FUNCTION Simd<T> operator / (const Simd<T>& lhs, const T rhs) {
126  Simd<T> out;
127  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = lhs.x[i_simd] / rhs;
128  return out;
129 }
130 
131 template<typename T>
132 KOKKOS_INLINE_FUNCTION Simd<T> operator / (const T lhs, const Simd<T>& rhs) {
133  Simd<T> out;
134  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++) out.x[i_simd] = lhs / rhs.x[i_simd];
135  return out;
136 }
137 
138 
142 
143  // Get magnitude of a single 2D vector
144  KOKKOS_INLINE_FUNCTION double magnitude(const int i_simd) const{
145  return sqrt(r[i_simd]*r[i_simd] + z[i_simd]*z[i_simd]);
146  }
147 };
148 
149 struct SimdVector{
153 
154  /* Returns a SimdVector2D alias to r and z
155  * */
156  KOKKOS_INLINE_FUNCTION SimdVector2D& x() {
157  return *(reinterpret_cast<SimdVector2D*>(this));
158  }
159 
160  /* Returns a SimdVector2D alias to r and z
161  * */
162  KOKKOS_INLINE_FUNCTION const SimdVector2D& x() const {
163  return *(reinterpret_cast<const SimdVector2D*>(this));
164  }
165 
166  // Vector operation, sets SimdVector to 0.0
167  KOKKOS_INLINE_FUNCTION void zero(){
168  for (int i_simd = 0; i_simd<SIMD_SIZE; i_simd++){
169  r[i_simd] = 0.0;
170  z[i_simd] = 0.0;
171  phi[i_simd] = 0.0;
172  }
173  }
174 
175  // Get magnitude of a single vector
176  KOKKOS_INLINE_FUNCTION double magnitude(const int i_simd) const{
177  return sqrt(r[i_simd]*r[i_simd] + z[i_simd]*z[i_simd] + phi[i_simd]*phi[i_simd]);
178  }
179 
180  // Get magnitude of a single vector projected onto a poloidal plane
181  KOKKOS_INLINE_FUNCTION double poloidal_magnitude(const int i_simd) const{
182  return x().magnitude(i_simd);
183  }
184 };
185 
186 #endif
Simd< double > r
Definition: simd.hpp:150
Definition: simd.hpp:149
KOKKOS_INLINE_FUNCTION void operator=(const Trhs rhs)
Definition: simd.hpp:34
KOKKOS_INLINE_FUNCTION T operator[](int i) const
Definition: simd.hpp:28
KOKKOS_INLINE_FUNCTION Simd< T > operator/(const Simd< T > &lhs, const T rhs)
Definition: simd.hpp:125
KOKKOS_INLINE_FUNCTION Simd< T > operator/(const Simd< Trhs > &rhs) const
Definition: simd.hpp:67
KOKKOS_INLINE_FUNCTION SimdVector2D & x()
Definition: simd.hpp:156
KOKKOS_INLINE_FUNCTION double poloidal_magnitude(const int i_simd) const
Definition: simd.hpp:181
KOKKOS_INLINE_FUNCTION Simd< T > operator*(const Simd< T > &lhs, const T rhs)
Definition: simd.hpp:111
Simd< double > z
Definition: simd.hpp:141
T x[SIMD_SIZE]
Definition: simd.hpp:19
KOKKOS_INLINE_FUNCTION Simd< T > operator-() const
Definition: simd.hpp:39
Simd< double > phi
Definition: simd.hpp:152
KOKKOS_INLINE_FUNCTION const SimdVector2D & x() const
Definition: simd.hpp:162
Simd< double > z
Definition: simd.hpp:151
KOKKOS_INLINE_FUNCTION void zero()
Definition: simd.hpp:76
Simd< double > r
Definition: simd.hpp:140
KOKKOS_INLINE_FUNCTION Simd< T > operator-(const Simd< T > &lhs, const T rhs)
Definition: simd.hpp:83
Definition: simd.hpp:18
Definition: simd.hpp:139
KOKKOS_INLINE_FUNCTION void zero()
Definition: simd.hpp:167
KOKKOS_INLINE_FUNCTION Simd< T > operator+(const Simd< Trhs > &rhs) const
Definition: simd.hpp:53
KOKKOS_INLINE_FUNCTION double magnitude(const int i_simd) const
Definition: simd.hpp:176
KOKKOS_INLINE_FUNCTION double magnitude(const int i_simd) const
Definition: simd.hpp:144
KOKKOS_INLINE_FUNCTION Simd< T > operator*(const Simd< Trhs > &rhs) const
Definition: simd.hpp:60
KOKKOS_INLINE_FUNCTION Simd< T > operator+(const Simd< T > &lhs, const T rhs)
Definition: simd.hpp:97