HCC
HCC is a single-source, C/C++ compiler for heterogeneous computing. It's optimized with HSA (http://www.hsafoundation.com/).
hc_math.hpp
1 #pragma once
2 
3 #include "hc.hpp"
4 #include <cmath>
5 
6 // Math functions with integer overloads will be converted to
7 // this floating point type.
8 #define HC_IMPLICIT_FLOAT_CONV double
9 
10 #ifdef __KALMAR_ACCELERATOR__
11 
12 #define HC_MATH_WRAPPER_1(function, arg1) \
13 template<typename T> \
14 inline T function(T arg1) __attribute__((hc,cpu)) { \
15  return hc::precise_math::function(arg1); \
16 }
17 
18 #define KALMAR_MATH_WRAPPER_1(function, arg1) HC_MATH_WRAPPER_1(function, arg1)
19 
20 #define HC_MATH_WRAPPER_FP_OVERLOAD_1(function, arg1) \
21 template<typename T> \
22 inline \
23 typename std::enable_if<std::is_integral<T>::value,HC_IMPLICIT_FLOAT_CONV>::type \
24  function(T arg1) __attribute__((hc,cpu)) { \
25  return hc::precise_math::function(static_cast<HC_IMPLICIT_FLOAT_CONV>(arg1)); \
26 } \
27 template<typename T> \
28 inline \
29 typename std::enable_if<std::is_floating_point <T>::value,T>::type \
30  function(T arg1) __attribute__((hc,cpu)) { \
31  return hc::precise_math::function(arg1); \
32 }
33 
34 #define KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(function, arg1) HC_MATH_WRAPPER_FP_OVERLOAD_1(function, arg1)
35 
36 #define HC_MATH_WRAPPER_2(function, arg1, arg2) \
37 template<typename T> \
38 inline T function(T arg1, T arg2) __attribute__((hc,cpu)) { \
39  return hc::precise_math::function(arg1, arg2); \
40 }
41 
42 #define HC_MATH_ALIAS_2(alias, function, arg1, arg2) \
43 template<typename T> \
44 inline T alias(T arg1, T arg2) __attribute__((hc,cpu)) { \
45  return hc::precise_math::function(arg1, arg2); \
46 }
47 
48 #define HC_MATH_WRAPPER_3(function, arg1, arg2, arg3) \
49 template<typename T> \
50 inline T function(T arg1, T arg2, T arg3) __attribute__((hc,cpu)) { \
51  return hc::precise_math::function(arg1, arg2, arg3); \
52 }
53 
54 #define HC_MATH_WRAPPER_TQ(function, arg1) \
55 template<typename T, typename Q> \
56 inline T function(Q arg1) __attribute__((hc,cpu)) { \
57  return hc::precise_math::function(arg1); \
58 }
59 
60 #define HC_MATH_WRAPPER_FP_OVERLOAD_TQ(function, T, arg1) \
61 template<typename Q> \
62 inline \
63 typename std::enable_if<std::is_integral<Q>::value,T>::type \
64 function(Q arg1) __attribute__((hc,cpu)) { \
65  return hc::precise_math::function(static_cast<HC_IMPLICIT_FLOAT_CONV>(arg1)); \
66 }\
67 template<typename Q> \
68 inline \
69 typename std::enable_if<std::is_floating_point<Q>::value,T>::type \
70 function(Q arg1) __attribute__((hc,cpu)) { \
71  return hc::precise_math::function(arg1); \
72 }
73 
74 #define HC_MATH_WRAPPER_FP_OVERLOAD_TQ_STD(function, T, arg1) HC_MATH_WRAPPER_FP_OVERLOAD_TQ(function, T, arg1)
75 
76 #define HC_MATH_WRAPPER_TTQ(function, arg1, arg2) \
77 template<typename T, typename Q> \
78 inline T function(T arg1, Q arg2) __attribute__((hc,cpu)) { \
79  return hc::precise_math::function(arg1, arg2); \
80 }
81 
82 #define HC_MATH_WRAPPER_FP_OVERLOAD_TTQ(function, arg1, arg2) \
83 template<typename T, typename Q> \
84 inline \
85 typename std::enable_if<std::is_integral<T>::value||std::is_integral<Q>::value,HC_IMPLICIT_FLOAT_CONV>::type \
86 function(T arg1, Q arg2) __attribute__((hc,cpu)) { \
87  return hc::precise_math::function(static_cast<HC_IMPLICIT_FLOAT_CONV>(arg1),static_cast<HC_IMPLICIT_FLOAT_CONV>(arg2)); \
88 }\
89 template<typename T, typename Q> \
90 inline \
91 typename std::enable_if<std::is_floating_point<T>::value&&std::is_floating_point<Q>::value,T>::type \
92 function(T arg1, Q arg2) __attribute__((hc,cpu)) { \
93  return hc::precise_math::function(arg1,arg2); \
94 }
95 
96 #define HC_MATH_WRAPPER_TTTQ(function, arg1, arg2, arg3) \
97 template<typename T, typename Q> \
98 inline T function(T arg1, T arg2, Q arg3) __attribute__((hc,cpu)) { \
99  return hc::precise_math::function(arg1, arg2, arg3); \
100 }
101 
102 #define HC_MATH_WRAPPER_VTQQ(function, arg1, arg2, arg3) \
103 template<typename T, typename Q> \
104 inline void function(T arg1, Q arg2, Q arg3) __attribute__((hc,cpu)) { \
105  hc::precise_math::function(arg1, arg2, arg3); \
106 }
107 
108 #else
109 
110 #define HC_MATH_WRAPPER_1(function, arg1) \
111 template<typename T> \
112 inline T function(T arg1) __attribute__((hc,cpu)) { \
113  return ::function(arg1); \
114 }
115 
116 #define KALMAR_MATH_WRAPPER_1(function, arg1) \
117 template<typename T> \
118 inline T function(T arg1) __attribute__((hc,cpu)) { \
119  return hc::precise_math::function(arg1); \
120 }
121 
122 #define HC_MATH_WRAPPER_FP_OVERLOAD_1(function, arg1) \
123 template<typename T> \
124 inline \
125 typename std::enable_if<std::is_integral<T>::value,HC_IMPLICIT_FLOAT_CONV>::type \
126  function(T arg1) __attribute__((hc,cpu)) { \
127  return ::function(static_cast<HC_IMPLICIT_FLOAT_CONV>(arg1)); \
128 } \
129 template<typename T> \
130 inline \
131 typename std::enable_if<std::is_floating_point<T>::value,T>::type \
132  function(T arg1) __attribute__((hc,cpu)) { \
133  return ::function(arg1); \
134 }
135 
136 #define KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(function, arg1) \
137 template<typename T> \
138 inline \
139 typename std::enable_if<std::is_integral<T>::value,HC_IMPLICIT_FLOAT_CONV>::type \
140  function(T arg1) __attribute__((hc)) { \
141  return hc::precise_math::function(static_cast<HC_IMPLICIT_FLOAT_CONV>(arg1)); \
142 } \
143 template<typename T> \
144 inline \
145 typename std::enable_if<std::is_floating_point <T>::value,T>::type \
146  function(T arg1) __attribute__((hc)) { \
147  return hc::precise_math::function(arg1); \
148 }
149 
150 #define HC_MATH_WRAPPER_2(function, arg1, arg2) \
151 template<typename T> \
152 inline T function(T arg1, T arg2) __attribute__((hc,cpu)) { \
153  return ::function(arg1, arg2); \
154 }
155 
156 #define HC_MATH_ALIAS_2(alias, function, arg1, arg2) \
157 template<typename T> \
158 inline T alias(T arg1, T arg2) __attribute__((hc,cpu)) { \
159  return ::function(arg1, arg2); \
160 }
161 
162 #define HC_MATH_WRAPPER_3(function, arg1, arg2, arg3) \
163 template<typename T> \
164 inline T function(T arg1, T arg2, T arg3) __attribute__((hc,cpu)) { \
165  return ::function(arg1, arg2, arg3); \
166 }
167 
168 #define HC_MATH_WRAPPER_TQ(function, arg1) \
169 template<typename T, typename Q> \
170 inline T function(Q arg1) __attribute__((hc,cpu)) { \
171  return ::function(arg1); \
172 }
173 
174 #define HC_MATH_WRAPPER_FP_OVERLOAD_TQ(function, T, arg1) \
175 template<typename Q> \
176 inline \
177 typename std::enable_if<std::is_integral<Q>::value,T>::type \
178 function(Q arg1) __attribute__((hc)) { \
179  return ::function(static_cast<HC_IMPLICIT_FLOAT_CONV>(arg1)); \
180 }\
181 template<typename Q> \
182 inline \
183 typename std::enable_if<std::is_floating_point<Q>::value,T>::type \
184 function(Q arg1) __attribute__((hc)) { \
185  return ::function(arg1); \
186 }
187 
188 #define HC_MATH_WRAPPER_FP_OVERLOAD_TQ_STD(function, T, arg1) \
189 template<typename Q> \
190 inline \
191 typename std::enable_if<std::is_integral<Q>::value,T>::type \
192 function(Q arg1) __attribute__((hc)) { \
193  return std::function(static_cast<HC_IMPLICIT_FLOAT_CONV>(arg1)); \
194 }\
195 template<typename Q> \
196 inline \
197 typename std::enable_if<std::is_floating_point<Q>::value,T>::type \
198 function(Q arg1) __attribute__((hc)) { \
199  return std::function(arg1); \
200 }
201 
202 #define HC_MATH_WRAPPER_TTQ(function, arg1, arg2) \
203 template<typename T, typename Q> \
204 inline T function(T arg1, Q arg2) __attribute__((hc,cpu)) { \
205  return ::function(arg1, arg2); \
206 }
207 
208 #define HC_MATH_WRAPPER_FP_OVERLOAD_TTQ(function, arg1, arg2) \
209 template<typename T, typename Q> \
210 inline \
211 typename std::enable_if<std::is_integral<T>::value||std::is_integral<Q>::value,HC_IMPLICIT_FLOAT_CONV>::type \
212 function(T arg1, Q arg2) __attribute__((hc,cpu)) { \
213  return ::function(static_cast<HC_IMPLICIT_FLOAT_CONV>(arg1),static_cast<HC_IMPLICIT_FLOAT_CONV>(arg2)); \
214 }\
215 template<typename T, typename Q> \
216 inline \
217 typename std::enable_if<std::is_floating_point<T>::value&&std::is_floating_point<Q>::value,T>::type \
218 function(T arg1, Q arg2) __attribute__((hc,cpu)) { \
219  return ::function(arg1,arg2); \
220 }
221 
222 #define HC_MATH_WRAPPER_TTTQ(function, arg1, arg2, arg3) \
223 template<typename T, typename Q> \
224 inline T function(T arg1, T arg2, Q arg3) __attribute__((hc,cpu)) { \
225  return ::function(arg1, arg2, arg3); \
226 }
227 
228 #define HC_MATH_WRAPPER_VTQQ(function, arg1, arg2, arg3) \
229 template<typename T, typename Q> \
230 inline void function(T arg1, Q arg2, Q arg3) __attribute__((hc,cpu)) { \
231  ::function(arg1, arg2, arg3); \
232 }
233 
234 #endif
235 
236 
237 // override global math functions
238 namespace {
239 
240 // following math functions are NOT available because they don't have a GPU implementation
241 //
242 //
243 // following math functions are NOT available because they don't have a CPU implementation
244 //
245 //
246 
247 HC_MATH_WRAPPER_TQ(ilogbf, x)
248 HC_MATH_WRAPPER_FP_OVERLOAD_TQ(ilogb, int, x)
249 HC_MATH_WRAPPER_FP_OVERLOAD_TQ_STD(isfinite, bool, x)
250 HC_MATH_WRAPPER_FP_OVERLOAD_TQ_STD(isinf, bool, x)
251 HC_MATH_WRAPPER_FP_OVERLOAD_TQ_STD(isnan, bool, x)
252 HC_MATH_WRAPPER_FP_OVERLOAD_TQ_STD(isnormal, bool, x)
253 HC_MATH_WRAPPER_TQ(nanf, tagp)
254 HC_MATH_WRAPPER_TQ(nan, tagp)
255 HC_MATH_WRAPPER_TQ(signbitf, x)
256 HC_MATH_WRAPPER_TQ(signbit, x)
257 HC_MATH_WRAPPER_TTQ(frexpf, x, exp)
258 HC_MATH_WRAPPER_TTQ(frexp, x, exp)
259 HC_MATH_WRAPPER_TTQ(ldexpf, x, exp)
260 HC_MATH_WRAPPER_TTQ(ldexp, x, exp)
261 HC_MATH_WRAPPER_TTQ(modff, x, exp)
262 HC_MATH_WRAPPER_TTQ(modf, x, exp)
263 HC_MATH_WRAPPER_TTQ(scalbnf, x, exp)
264 HC_MATH_WRAPPER_TTQ(scalbn, x, exp)
265 HC_MATH_WRAPPER_TTTQ(remquof, x, y, quo)
266 HC_MATH_WRAPPER_TTTQ(remquo, x, y, quo)
267 HC_MATH_WRAPPER_VTQQ(sincosf, x, s, c)
268 HC_MATH_WRAPPER_VTQQ(sincos, x, s, c)
269 
270 HC_MATH_WRAPPER_1(acosf, x)
271 HC_MATH_WRAPPER_FP_OVERLOAD_1(acos, x)
272 HC_MATH_WRAPPER_1(acoshf, x)
273 HC_MATH_WRAPPER_FP_OVERLOAD_1(acosh, x)
274 HC_MATH_WRAPPER_1(asinf, x)
275 HC_MATH_WRAPPER_FP_OVERLOAD_1(asin, x)
276 HC_MATH_WRAPPER_1(asinhf, x)
277 HC_MATH_WRAPPER_FP_OVERLOAD_1(asinh, x)
278 HC_MATH_WRAPPER_1(atanf, x)
279 HC_MATH_WRAPPER_FP_OVERLOAD_1(atan, x)
280 HC_MATH_WRAPPER_1(atanhf, x)
281 HC_MATH_WRAPPER_FP_OVERLOAD_1(atanh, x)
282 HC_MATH_WRAPPER_2(atan2f, y, x)
283 HC_MATH_WRAPPER_2(atan2, y, x)
284 HC_MATH_WRAPPER_1(cbrtf, x)
285 HC_MATH_WRAPPER_FP_OVERLOAD_1(cbrt, x)
286 HC_MATH_WRAPPER_1(ceilf, x)
287 HC_MATH_WRAPPER_FP_OVERLOAD_1(ceil, x)
288 HC_MATH_WRAPPER_2(copysignf, x, y)
289 HC_MATH_WRAPPER_2(copysign, x, y)
290 HC_MATH_WRAPPER_1(cosf, x)
291 HC_MATH_WRAPPER_FP_OVERLOAD_1(cos, x)
292 HC_MATH_WRAPPER_1(coshf, x)
293 HC_MATH_WRAPPER_FP_OVERLOAD_1(cosh, x)
294 KALMAR_MATH_WRAPPER_1(cospif, x)
295 KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(cospi, x)
296 HC_MATH_WRAPPER_1(erff, x)
297 HC_MATH_WRAPPER_FP_OVERLOAD_1(erf, x)
298 HC_MATH_WRAPPER_1(erfcf, x)
299 HC_MATH_WRAPPER_FP_OVERLOAD_1(erfc, x)
300 KALMAR_MATH_WRAPPER_1(erfcinvf, x)
301 KALMAR_MATH_WRAPPER_1(erfcinv, x)
302 KALMAR_MATH_WRAPPER_1(erfinvf, x)
303 KALMAR_MATH_WRAPPER_1(erfinv, x)
304 HC_MATH_WRAPPER_1(expf, x)
305 HC_MATH_WRAPPER_FP_OVERLOAD_1(exp, x)
306 HC_MATH_WRAPPER_1(exp2f, x)
307 HC_MATH_WRAPPER_FP_OVERLOAD_1(exp2, x)
308 HC_MATH_WRAPPER_1(exp10f, x)
309 HC_MATH_WRAPPER_FP_OVERLOAD_1(exp10, x)
310 HC_MATH_WRAPPER_1(expm1f, x)
311 HC_MATH_WRAPPER_FP_OVERLOAD_1(expm1, x)
312 HC_MATH_WRAPPER_1(fabsf, x)
313 HC_MATH_WRAPPER_FP_OVERLOAD_1(fabs, x)
314 HC_MATH_WRAPPER_2(fdimf, x, y)
315 HC_MATH_WRAPPER_2(fdim, x, y)
316 HC_MATH_WRAPPER_1(floorf, x)
317 HC_MATH_WRAPPER_FP_OVERLOAD_1(floor, x)
318 HC_MATH_WRAPPER_3(fmaf, x, y, z)
319 HC_MATH_WRAPPER_3(fma, x, y, z)
320 HC_MATH_WRAPPER_2(fmaxf, x, y)
321 HC_MATH_WRAPPER_2(fmax, x, y)
322 HC_MATH_WRAPPER_2(fminf, x, y)
323 HC_MATH_WRAPPER_2(fmin, x, y)
324 HC_MATH_WRAPPER_2(fmodf, x, y)
325 HC_MATH_WRAPPER_2(fmod, x, y)
326 HC_MATH_WRAPPER_2(hypotf, x, y)
327 HC_MATH_WRAPPER_2(hypot, x, y)
328 HC_MATH_WRAPPER_1(lgammaf, x)
329 HC_MATH_WRAPPER_FP_OVERLOAD_1(lgamma, x)
330 HC_MATH_WRAPPER_1(logf, x)
331 HC_MATH_WRAPPER_FP_OVERLOAD_1(log, x)
332 HC_MATH_WRAPPER_1(log10f, x)
333 HC_MATH_WRAPPER_FP_OVERLOAD_1(log10, x)
334 HC_MATH_WRAPPER_1(log2f, x)
335 HC_MATH_WRAPPER_FP_OVERLOAD_1(log2, x)
336 HC_MATH_WRAPPER_1(log1pf, x)
337 HC_MATH_WRAPPER_FP_OVERLOAD_1(log1p, x)
338 HC_MATH_WRAPPER_1(logbf, x)
339 HC_MATH_WRAPPER_FP_OVERLOAD_1(logb, x)
340 HC_MATH_WRAPPER_1(nearbyintf, x)
341 HC_MATH_WRAPPER_FP_OVERLOAD_1(nearbyint, x)
342 HC_MATH_WRAPPER_2(nextafterf, x, y)
343 HC_MATH_WRAPPER_2(nextafter, x, y)
344 HC_MATH_WRAPPER_2(powf, x, y)
345 HC_MATH_WRAPPER_FP_OVERLOAD_TTQ(pow,x,y)
346 KALMAR_MATH_WRAPPER_1(rcbrtf, x)
347 KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(rcbrt, x)
348 HC_MATH_WRAPPER_2(remainderf, x, y)
349 HC_MATH_WRAPPER_2(remainder, x, y)
350 HC_MATH_WRAPPER_1(roundf, x)
351 HC_MATH_WRAPPER_FP_OVERLOAD_1(round, x)
352 KALMAR_MATH_WRAPPER_1(rsqrtf, x)
353 KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(rsqrt, x)
354 HC_MATH_WRAPPER_2(scalbf, x, exp)
355 HC_MATH_WRAPPER_2(scalb, x, exp)
356 HC_MATH_WRAPPER_1(sinf, x)
357 HC_MATH_WRAPPER_FP_OVERLOAD_1(sin, x)
358 HC_MATH_WRAPPER_1(sinhf, x)
359 HC_MATH_WRAPPER_FP_OVERLOAD_1(sinh, x)
360 KALMAR_MATH_WRAPPER_1(sinpif, x)
361 KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(sinpi, x)
362 HC_MATH_WRAPPER_1(sqrtf, x)
363 HC_MATH_WRAPPER_FP_OVERLOAD_1(sqrt, x)
364 HC_MATH_WRAPPER_1(tgammaf, x)
365 HC_MATH_WRAPPER_FP_OVERLOAD_1(tgamma, x)
366 HC_MATH_WRAPPER_1(tanf, x)
367 HC_MATH_WRAPPER_FP_OVERLOAD_1(tan, x)
368 HC_MATH_WRAPPER_1(tanhf, x)
369 HC_MATH_WRAPPER_FP_OVERLOAD_1(tanh, x)
370 KALMAR_MATH_WRAPPER_1(tanpif, x)
371 KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(tanpi, x)
372 HC_MATH_WRAPPER_1(truncf, x)
373 HC_MATH_WRAPPER_FP_OVERLOAD_1(trunc, x)
374 
375 } // namespace
Heterogeneous C++ (HC) API.