HIP: Heterogenous-computing Interface for Portability
hip_complex.h
1 /*
2 Copyright (c) 2015 - present Advanced Micro Devices, Inc. All rights reserved.
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 */
22 
23 #ifndef HIP_INCLUDE_HIP_HCC_DETAIL_HIP_COMPLEX_H
24 #define HIP_INCLUDE_HIP_HCC_DETAIL_HIP_COMPLEX_H
25 
27 #include <math.h>
28 
29 #if __cplusplus
30 #define COMPLEX_ADD_OP_OVERLOAD(type) \
31 __device__ __host__ static inline type operator + (const type& lhs, const type& rhs) { \
32  type ret; \
33  ret.x = lhs.x + rhs.x ; \
34  ret.y = lhs.y + rhs.y ; \
35  return ret; \
36 }
37 
38 #define COMPLEX_SUB_OP_OVERLOAD(type) \
39 __device__ __host__ static inline type operator - (const type& lhs, const type& rhs) { \
40  type ret; \
41  ret.x = lhs.x - rhs.x; \
42  ret.y = lhs.y - rhs.y; \
43  return ret; \
44 }
45 
46 #define COMPLEX_MUL_OP_OVERLOAD(type) \
47 __device__ __host__ static inline type operator * (const type& lhs, const type& rhs) { \
48  type ret; \
49  ret.x = lhs.x * rhs.x - lhs.y * rhs.y; \
50  ret.y = lhs.x * rhs.y + lhs.y * rhs.x; \
51  return ret; \
52 }
53 
54 #define COMPLEX_DIV_OP_OVERLOAD(type) \
55 __device__ __host__ static inline type operator / (const type& lhs, const type& rhs) { \
56  type ret; \
57  ret.x = (lhs.x * rhs.x + lhs.y * rhs.y); \
58  ret.y = (rhs.x * lhs.y - lhs.x * rhs.y); \
59  ret.x = ret.x / (rhs.x * rhs.x + rhs.y * rhs.y); \
60  ret.y = ret.y / (rhs.x * rhs.x + rhs.y * rhs.y); \
61  return ret; \
62 }
63 
64 #define COMPLEX_ADD_PREOP_OVERLOAD(type) \
65 __device__ __host__ static inline type& operator += (type& lhs, const type& rhs) { \
66  lhs.x += rhs.x; \
67  lhs.y += rhs.y; \
68  return lhs; \
69 }
70 
71 #define COMPLEX_SUB_PREOP_OVERLOAD(type) \
72 __device__ __host__ static inline type& operator -= (type& lhs, const type& rhs) { \
73  lhs.x -= rhs.x; \
74  lhs.y -= rhs.y; \
75  return lhs; \
76 }
77 
78 #define COMPLEX_MUL_PREOP_OVERLOAD(type) \
79 __device__ __host__ static inline type& operator *= (type& lhs, const type& rhs) { \
80  lhs = lhs * rhs; \
81  return lhs; \
82 }
83 
84 #define COMPLEX_DIV_PREOP_OVERLOAD(type) \
85 __device__ __host__ static inline type& operator /= (type& lhs, const type& rhs) { \
86  lhs = lhs / rhs; \
87  return lhs; \
88 }
89 
90 #define COMPLEX_SCALAR_PRODUCT(type, type1) \
91 __device__ __host__ static inline type operator * (const type& lhs, type1 rhs) { \
92  type ret; \
93  ret.x = lhs.x * rhs; \
94  ret.y = lhs.y * rhs; \
95  return ret; \
96 }
97 
98 #endif
99 
101  #ifdef __cplusplus
102  public:
103  __device__ __host__ hipFloatComplex() : x(0.0f), y(0.0f) {}
104  __device__ __host__ hipFloatComplex(float x) : x(x), y(0.0f) {}
105  __device__ __host__ hipFloatComplex(float x, float y) : x(x), y(y) {}
106  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, unsigned short)
107  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, signed short)
108  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, unsigned int)
109  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, signed int)
110  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, double)
111  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, unsigned long)
112  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, signed long)
113  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, unsigned long long)
114  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, signed long long)
115  #endif
116  float x, y;
117 } __attribute__((aligned(8)));
118 
120  #ifdef __cplusplus
121  public:
122  __device__ __host__ hipDoubleComplex() : x(0.0f), y(0.0f) {}
123  __device__ __host__ hipDoubleComplex(double x) : x(x), y(0.0f) {}
124  __device__ __host__ hipDoubleComplex(double x, double y) : x(x), y(y) {}
125  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, unsigned short)
126  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, signed short)
127  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, unsigned int)
128  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, signed int)
129  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, float)
130  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, unsigned long)
131  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, signed long)
132  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, unsigned long long)
133  MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, signed long long)
134  #endif
135  double x, y;
136 } __attribute__((aligned(16)));
137 
138 #if __cplusplus
139 
140 COMPLEX_ADD_OP_OVERLOAD(hipFloatComplex)
141 COMPLEX_SUB_OP_OVERLOAD(hipFloatComplex)
142 COMPLEX_MUL_OP_OVERLOAD(hipFloatComplex)
143 COMPLEX_DIV_OP_OVERLOAD(hipFloatComplex)
144 COMPLEX_ADD_PREOP_OVERLOAD(hipFloatComplex)
145 COMPLEX_SUB_PREOP_OVERLOAD(hipFloatComplex)
146 COMPLEX_MUL_PREOP_OVERLOAD(hipFloatComplex)
147 COMPLEX_DIV_PREOP_OVERLOAD(hipFloatComplex)
148 COMPLEX_SCALAR_PRODUCT(hipFloatComplex, unsigned short)
149 COMPLEX_SCALAR_PRODUCT(hipFloatComplex, signed short)
150 COMPLEX_SCALAR_PRODUCT(hipFloatComplex, unsigned int)
151 COMPLEX_SCALAR_PRODUCT(hipFloatComplex, signed int)
152 COMPLEX_SCALAR_PRODUCT(hipFloatComplex, float)
153 COMPLEX_SCALAR_PRODUCT(hipFloatComplex, unsigned long)
154 COMPLEX_SCALAR_PRODUCT(hipFloatComplex, signed long)
155 COMPLEX_SCALAR_PRODUCT(hipFloatComplex, double)
156 COMPLEX_SCALAR_PRODUCT(hipFloatComplex, signed long long)
157 COMPLEX_SCALAR_PRODUCT(hipFloatComplex, unsigned long long)
158 
159 COMPLEX_ADD_OP_OVERLOAD(hipDoubleComplex)
160 COMPLEX_SUB_OP_OVERLOAD(hipDoubleComplex)
161 COMPLEX_MUL_OP_OVERLOAD(hipDoubleComplex)
162 COMPLEX_DIV_OP_OVERLOAD(hipDoubleComplex)
163 COMPLEX_ADD_PREOP_OVERLOAD(hipDoubleComplex)
164 COMPLEX_SUB_PREOP_OVERLOAD(hipDoubleComplex)
165 COMPLEX_MUL_PREOP_OVERLOAD(hipDoubleComplex)
166 COMPLEX_DIV_PREOP_OVERLOAD(hipDoubleComplex)
167 COMPLEX_SCALAR_PRODUCT(hipDoubleComplex, unsigned short)
168 COMPLEX_SCALAR_PRODUCT(hipDoubleComplex, signed short)
169 COMPLEX_SCALAR_PRODUCT(hipDoubleComplex, unsigned int)
170 COMPLEX_SCALAR_PRODUCT(hipDoubleComplex, signed int)
171 COMPLEX_SCALAR_PRODUCT(hipDoubleComplex, float)
172 COMPLEX_SCALAR_PRODUCT(hipDoubleComplex, unsigned long)
173 COMPLEX_SCALAR_PRODUCT(hipDoubleComplex, signed long)
174 COMPLEX_SCALAR_PRODUCT(hipDoubleComplex, double)
175 COMPLEX_SCALAR_PRODUCT(hipDoubleComplex, signed long long)
176 COMPLEX_SCALAR_PRODUCT(hipDoubleComplex, unsigned long long)
177 
178 #endif
179 
180 __device__ __host__ static inline float hipCrealf(hipFloatComplex z){
181  return z.x;
182 }
183 
184 __device__ __host__ static inline float hipCimagf(hipFloatComplex z){
185  return z.y;
186 }
187 
188 __device__ __host__ static inline hipFloatComplex make_hipFloatComplex(float a, float b){
189  hipFloatComplex z;
190  z.x = a;
191  z.y = b;
192  return z;
193 }
194 
195 __device__ __host__ static inline hipFloatComplex hipConjf(hipFloatComplex z){
196  hipFloatComplex ret;
197  ret.x = z.x;
198  ret.y = -z.y;
199  return ret;
200 }
201 
202 __device__ __host__ static inline float hipCsqabsf(hipFloatComplex z){
203  return z.x * z.x + z.y * z.y;
204 }
205 
206 __device__ __host__ static inline hipFloatComplex hipCaddf(hipFloatComplex p, hipFloatComplex q){
207  return make_hipFloatComplex(p.x + q.x, p.y + q.y);
208 }
209 
210 __device__ __host__ static inline hipFloatComplex hipCsubf(hipFloatComplex p, hipFloatComplex q){
211  return make_hipFloatComplex(p.x - q.x, p.y - q.y);
212 }
213 
214 __device__ __host__ static inline hipFloatComplex hipCmulf(hipFloatComplex p, hipFloatComplex q){
215  return make_hipFloatComplex(p.x * q.x - p.y * q.y, p.y * q.x + p.x * q.y);
216 }
217 
218 __device__ __host__ static inline hipFloatComplex hipCdivf(hipFloatComplex p, hipFloatComplex q){
219  float sqabs = hipCsqabsf(q);
220  hipFloatComplex ret;
221  ret.x = (p.x * q.x + p.y * q.y)/sqabs;
222  ret.y = (p.y * q.x - p.x * q.y)/sqabs;
223  return ret;
224 }
225 
226 __device__ __host__ static inline float hipCabsf(hipFloatComplex z){
227  return sqrtf(hipCsqabsf(z));
228 }
229 
230 
231 
232 __device__ __host__ static inline double hipCreal(hipDoubleComplex z){
233  return z.x;
234 }
235 
236 __device__ __host__ static inline double hipCimag(hipDoubleComplex z){
237  return z.y;
238 }
239 
240 __device__ __host__ static inline hipDoubleComplex make_hipDoubleComplex(double a, double b){
242  z.x = a;
243  z.y = b;
244  return z;
245 }
246 
247 __device__ __host__ static inline hipDoubleComplex hipConj(hipDoubleComplex z){
248  hipDoubleComplex ret;
249  ret.x = z.x;
250  ret.y = z.y;
251  return ret;
252 }
253 
254 __device__ __host__ static inline double hipCsqabs(hipDoubleComplex z){
255  return z.x * z.x + z.y * z.y;
256 }
257 
258 __device__ __host__ static inline hipDoubleComplex hipCadd(hipDoubleComplex p, hipDoubleComplex q){
259  return make_hipDoubleComplex(p.x + q.x, p.y + q.y);
260 }
261 
262 __device__ __host__ static inline hipDoubleComplex hipCsub(hipDoubleComplex p, hipDoubleComplex q){
263  return make_hipDoubleComplex(p.x - q.x, p.y - q.y);
264 }
265 
266 __device__ __host__ static inline hipDoubleComplex hipCmul(hipDoubleComplex p, hipDoubleComplex q){
267  return make_hipDoubleComplex(p.x * q.x - p.y * q.y, p.y * q.x + p.x * q.y);
268 }
269 
270 __device__ __host__ static inline hipDoubleComplex hipCdiv(hipDoubleComplex p, hipDoubleComplex q){
271  double sqabs = hipCsqabs(q);
272  hipDoubleComplex ret;
273  ret.x = (p.x * q.x + p.y * q.y)/sqabs;
274  ret.y = (p.y * q.x - p.x * q.y)/sqabs;
275  return ret;
276 }
277 
278 __device__ __host__ static inline double hipCabs(hipDoubleComplex z){
279  return sqrtf(hipCsqabs(z));
280 }
281 
283 
284 __device__ __host__ static inline hipComplex make_hipComplex(float x,
285  float y){
286  return make_hipFloatComplex(x, y);
287 }
288 
289 __device__ __host__ static inline hipFloatComplex hipComplexDoubleToFloat
290 (hipDoubleComplex z){
291  return make_hipFloatComplex((float)z.x, (float)z.y);
292 }
293 
294 __device__ __host__ static inline hipDoubleComplex hipComplexFloatToDouble
295 (hipFloatComplex z){
296  return make_hipDoubleComplex((double)z.x, (double)z.y);
297 }
298 
299 __device__ __host__ static inline hipComplex hipCfmaf(hipComplex p, hipComplex q, hipComplex r){
300  float real = (p.x * q.x) + r.x;
301  float imag = (q.x * p.y) + r.y;
302 
303  real = -(p.y * q.y) + real;
304  imag = (p.x * q.y) + imag;
305 
306  return make_hipComplex(real, imag);
307 }
308 
309 __device__ __host__ static inline hipDoubleComplex hipCfma(hipDoubleComplex p, hipDoubleComplex q, hipDoubleComplex r){
310  float real = (p.x * q.x) + r.x;
311  float imag = (q.x * p.y) + r.y;
312 
313  real = -(p.y * q.y) + real;
314  imag = (p.x * q.y) + imag;
315 
316  return make_hipDoubleComplex(real, imag);
317 }
318 
319 #endif
Definition: hip_complex.h:100
#define __host__
Definition: host_defines.h:41
Definition: hip_complex.h:119
Defines the different newt vector types for HIP runtime.