1*a9ac8606Spatrick /*===---- __clang_hip_cmath.h - HIP cmath decls -----------------------------===
2*a9ac8606Spatrick  *
3*a9ac8606Spatrick  * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*a9ac8606Spatrick  * See https://llvm.org/LICENSE.txt for license information.
5*a9ac8606Spatrick  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*a9ac8606Spatrick  *
7*a9ac8606Spatrick  *===-----------------------------------------------------------------------===
8*a9ac8606Spatrick  */
9*a9ac8606Spatrick 
10*a9ac8606Spatrick #ifndef __CLANG_HIP_CMATH_H__
11*a9ac8606Spatrick #define __CLANG_HIP_CMATH_H__
12*a9ac8606Spatrick 
13*a9ac8606Spatrick #if !defined(__HIP__) && !defined(__OPENMP_AMDGCN__)
14*a9ac8606Spatrick #error "This file is for HIP and OpenMP AMDGCN device compilation only."
15*a9ac8606Spatrick #endif
16*a9ac8606Spatrick 
17*a9ac8606Spatrick #if !defined(__HIPCC_RTC__)
18*a9ac8606Spatrick #if defined(__cplusplus)
19*a9ac8606Spatrick #include <limits>
20*a9ac8606Spatrick #include <type_traits>
21*a9ac8606Spatrick #include <utility>
22*a9ac8606Spatrick #endif
23*a9ac8606Spatrick #include <limits.h>
24*a9ac8606Spatrick #include <stdint.h>
25*a9ac8606Spatrick #endif // !defined(__HIPCC_RTC__)
26*a9ac8606Spatrick 
27*a9ac8606Spatrick #pragma push_macro("__DEVICE__")
28*a9ac8606Spatrick #pragma push_macro("__CONSTEXPR__")
29*a9ac8606Spatrick #ifdef __OPENMP_AMDGCN__
30*a9ac8606Spatrick #define __DEVICE__ static __attribute__((always_inline, nothrow))
31*a9ac8606Spatrick #define __CONSTEXPR__ constexpr
32*a9ac8606Spatrick #else
33*a9ac8606Spatrick #define __DEVICE__ static __device__ inline __attribute__((always_inline))
34*a9ac8606Spatrick #define __CONSTEXPR__
35*a9ac8606Spatrick #endif // __OPENMP_AMDGCN__
36*a9ac8606Spatrick 
37*a9ac8606Spatrick // Start with functions that cannot be defined by DEF macros below.
38*a9ac8606Spatrick #if defined(__cplusplus)
39*a9ac8606Spatrick #if defined __OPENMP_AMDGCN__
fabs(float __x)40*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ float fabs(float __x) { return ::fabsf(__x); }
sin(float __x)41*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ float sin(float __x) { return ::sinf(__x); }
cos(float __x)42*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ float cos(float __x) { return ::cosf(__x); }
43*a9ac8606Spatrick #endif
abs(double __x)44*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ double abs(double __x) { return ::fabs(__x); }
abs(float __x)45*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ float abs(float __x) { return ::fabsf(__x); }
abs(long long __n)46*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ long long abs(long long __n) { return ::llabs(__n); }
abs(long __n)47*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ long abs(long __n) { return ::labs(__n); }
fma(float __x,float __y,float __z)48*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ float fma(float __x, float __y, float __z) {
49*a9ac8606Spatrick   return ::fmaf(__x, __y, __z);
50*a9ac8606Spatrick }
51*a9ac8606Spatrick #if !defined(__HIPCC_RTC__)
52*a9ac8606Spatrick // The value returned by fpclassify is platform dependent, therefore it is not
53*a9ac8606Spatrick // supported by hipRTC.
fpclassify(float __x)54*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ int fpclassify(float __x) {
55*a9ac8606Spatrick   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
56*a9ac8606Spatrick                               FP_ZERO, __x);
57*a9ac8606Spatrick }
fpclassify(double __x)58*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ int fpclassify(double __x) {
59*a9ac8606Spatrick   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
60*a9ac8606Spatrick                               FP_ZERO, __x);
61*a9ac8606Spatrick }
62*a9ac8606Spatrick #endif // !defined(__HIPCC_RTC__)
63*a9ac8606Spatrick 
frexp(float __arg,int * __exp)64*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ float frexp(float __arg, int *__exp) {
65*a9ac8606Spatrick   return ::frexpf(__arg, __exp);
66*a9ac8606Spatrick }
67*a9ac8606Spatrick 
68*a9ac8606Spatrick #if defined(__OPENMP_AMDGCN__)
69*a9ac8606Spatrick // For OpenMP we work around some old system headers that have non-conforming
70*a9ac8606Spatrick // `isinf(float)` and `isnan(float)` implementations that return an `int`. We do
71*a9ac8606Spatrick // this by providing two versions of these functions, differing only in the
72*a9ac8606Spatrick // return type. To avoid conflicting definitions we disable implicit base
73*a9ac8606Spatrick // function generation. That means we will end up with two specializations, one
74*a9ac8606Spatrick // per type, but only one has a base function defined by the system header.
75*a9ac8606Spatrick #pragma omp begin declare variant match(                                       \
76*a9ac8606Spatrick     implementation = {extension(disable_implicit_base)})
77*a9ac8606Spatrick 
78*a9ac8606Spatrick // FIXME: We lack an extension to customize the mangling of the variants, e.g.,
79*a9ac8606Spatrick //        add a suffix. This means we would clash with the names of the variants
80*a9ac8606Spatrick //        (note that we do not create implicit base functions here). To avoid
81*a9ac8606Spatrick //        this clash we add a new trait to some of them that is always true
82*a9ac8606Spatrick //        (this is LLVM after all ;)). It will only influence the mangled name
83*a9ac8606Spatrick //        of the variants inside the inner region and avoid the clash.
84*a9ac8606Spatrick #pragma omp begin declare variant match(implementation = {vendor(llvm)})
85*a9ac8606Spatrick 
isinf(float __x)86*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ int isinf(float __x) { return ::__isinff(__x); }
isinf(double __x)87*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ int isinf(double __x) { return ::__isinf(__x); }
isfinite(float __x)88*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ int isfinite(float __x) { return ::__finitef(__x); }
isfinite(double __x)89*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ int isfinite(double __x) { return ::__finite(__x); }
isnan(float __x)90*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ int isnan(float __x) { return ::__isnanf(__x); }
isnan(double __x)91*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ int isnan(double __x) { return ::__isnan(__x); }
92*a9ac8606Spatrick 
93*a9ac8606Spatrick #pragma omp end declare variant
94*a9ac8606Spatrick #endif // defined(__OPENMP_AMDGCN__)
95*a9ac8606Spatrick 
isinf(float __x)96*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isinf(float __x) { return ::__isinff(__x); }
isinf(double __x)97*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isinf(double __x) { return ::__isinf(__x); }
isfinite(float __x)98*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isfinite(float __x) { return ::__finitef(__x); }
isfinite(double __x)99*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isfinite(double __x) { return ::__finite(__x); }
isnan(float __x)100*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isnan(float __x) { return ::__isnanf(__x); }
isnan(double __x)101*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isnan(double __x) { return ::__isnan(__x); }
102*a9ac8606Spatrick 
103*a9ac8606Spatrick #if defined(__OPENMP_AMDGCN__)
104*a9ac8606Spatrick #pragma omp end declare variant
105*a9ac8606Spatrick #endif // defined(__OPENMP_AMDGCN__)
106*a9ac8606Spatrick 
isgreater(float __x,float __y)107*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isgreater(float __x, float __y) {
108*a9ac8606Spatrick   return __builtin_isgreater(__x, __y);
109*a9ac8606Spatrick }
isgreater(double __x,double __y)110*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isgreater(double __x, double __y) {
111*a9ac8606Spatrick   return __builtin_isgreater(__x, __y);
112*a9ac8606Spatrick }
isgreaterequal(float __x,float __y)113*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isgreaterequal(float __x, float __y) {
114*a9ac8606Spatrick   return __builtin_isgreaterequal(__x, __y);
115*a9ac8606Spatrick }
isgreaterequal(double __x,double __y)116*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isgreaterequal(double __x, double __y) {
117*a9ac8606Spatrick   return __builtin_isgreaterequal(__x, __y);
118*a9ac8606Spatrick }
isless(float __x,float __y)119*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isless(float __x, float __y) {
120*a9ac8606Spatrick   return __builtin_isless(__x, __y);
121*a9ac8606Spatrick }
isless(double __x,double __y)122*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isless(double __x, double __y) {
123*a9ac8606Spatrick   return __builtin_isless(__x, __y);
124*a9ac8606Spatrick }
islessequal(float __x,float __y)125*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool islessequal(float __x, float __y) {
126*a9ac8606Spatrick   return __builtin_islessequal(__x, __y);
127*a9ac8606Spatrick }
islessequal(double __x,double __y)128*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool islessequal(double __x, double __y) {
129*a9ac8606Spatrick   return __builtin_islessequal(__x, __y);
130*a9ac8606Spatrick }
islessgreater(float __x,float __y)131*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool islessgreater(float __x, float __y) {
132*a9ac8606Spatrick   return __builtin_islessgreater(__x, __y);
133*a9ac8606Spatrick }
islessgreater(double __x,double __y)134*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool islessgreater(double __x, double __y) {
135*a9ac8606Spatrick   return __builtin_islessgreater(__x, __y);
136*a9ac8606Spatrick }
isnormal(float __x)137*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isnormal(float __x) {
138*a9ac8606Spatrick   return __builtin_isnormal(__x);
139*a9ac8606Spatrick }
isnormal(double __x)140*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isnormal(double __x) {
141*a9ac8606Spatrick   return __builtin_isnormal(__x);
142*a9ac8606Spatrick }
isunordered(float __x,float __y)143*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isunordered(float __x, float __y) {
144*a9ac8606Spatrick   return __builtin_isunordered(__x, __y);
145*a9ac8606Spatrick }
isunordered(double __x,double __y)146*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool isunordered(double __x, double __y) {
147*a9ac8606Spatrick   return __builtin_isunordered(__x, __y);
148*a9ac8606Spatrick }
modf(float __x,float * __iptr)149*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ float modf(float __x, float *__iptr) {
150*a9ac8606Spatrick   return ::modff(__x, __iptr);
151*a9ac8606Spatrick }
pow(float __base,int __iexp)152*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ float pow(float __base, int __iexp) {
153*a9ac8606Spatrick   return ::powif(__base, __iexp);
154*a9ac8606Spatrick }
pow(double __base,int __iexp)155*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ double pow(double __base, int __iexp) {
156*a9ac8606Spatrick   return ::powi(__base, __iexp);
157*a9ac8606Spatrick }
remquo(float __x,float __y,int * __quo)158*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ float remquo(float __x, float __y, int *__quo) {
159*a9ac8606Spatrick   return ::remquof(__x, __y, __quo);
160*a9ac8606Spatrick }
scalbln(float __x,long int __n)161*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ float scalbln(float __x, long int __n) {
162*a9ac8606Spatrick   return ::scalblnf(__x, __n);
163*a9ac8606Spatrick }
signbit(float __x)164*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool signbit(float __x) { return ::__signbitf(__x); }
signbit(double __x)165*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ bool signbit(double __x) { return ::__signbit(__x); }
166*a9ac8606Spatrick 
167*a9ac8606Spatrick // Notably missing above is nexttoward.  We omit it because
168*a9ac8606Spatrick // ocml doesn't provide an implementation, and we don't want to be in the
169*a9ac8606Spatrick // business of implementing tricky libm functions in this header.
170*a9ac8606Spatrick 
171*a9ac8606Spatrick // Other functions.
fma(_Float16 __x,_Float16 __y,_Float16 __z)172*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ _Float16 fma(_Float16 __x, _Float16 __y,
173*a9ac8606Spatrick                                       _Float16 __z) {
174*a9ac8606Spatrick   return __ocml_fma_f16(__x, __y, __z);
175*a9ac8606Spatrick }
pow(_Float16 __base,int __iexp)176*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ _Float16 pow(_Float16 __base, int __iexp) {
177*a9ac8606Spatrick   return __ocml_pown_f16(__base, __iexp);
178*a9ac8606Spatrick }
179*a9ac8606Spatrick 
180*a9ac8606Spatrick #ifndef __OPENMP_AMDGCN__
181*a9ac8606Spatrick // BEGIN DEF_FUN and HIP_OVERLOAD
182*a9ac8606Spatrick 
183*a9ac8606Spatrick // BEGIN DEF_FUN
184*a9ac8606Spatrick 
185*a9ac8606Spatrick #pragma push_macro("__DEF_FUN1")
186*a9ac8606Spatrick #pragma push_macro("__DEF_FUN2")
187*a9ac8606Spatrick #pragma push_macro("__DEF_FUN2_FI")
188*a9ac8606Spatrick 
189*a9ac8606Spatrick // Define cmath functions with float argument and returns __retty.
190*a9ac8606Spatrick #define __DEF_FUN1(__retty, __func)                                            \
191*a9ac8606Spatrick   __DEVICE__ __CONSTEXPR__ __retty __func(float __x) { return __func##f(__x); }
192*a9ac8606Spatrick 
193*a9ac8606Spatrick // Define cmath functions with two float arguments and returns __retty.
194*a9ac8606Spatrick #define __DEF_FUN2(__retty, __func)                                            \
195*a9ac8606Spatrick   __DEVICE__ __CONSTEXPR__ __retty __func(float __x, float __y) {              \
196*a9ac8606Spatrick     return __func##f(__x, __y);                                                \
197*a9ac8606Spatrick   }
198*a9ac8606Spatrick 
199*a9ac8606Spatrick // Define cmath functions with a float and an int argument and returns __retty.
200*a9ac8606Spatrick #define __DEF_FUN2_FI(__retty, __func)                                         \
201*a9ac8606Spatrick   __DEVICE__ __CONSTEXPR__ __retty __func(float __x, int __y) {                \
202*a9ac8606Spatrick     return __func##f(__x, __y);                                                \
203*a9ac8606Spatrick   }
204*a9ac8606Spatrick 
205*a9ac8606Spatrick __DEF_FUN1(float, acos)
206*a9ac8606Spatrick __DEF_FUN1(float, acosh)
207*a9ac8606Spatrick __DEF_FUN1(float, asin)
208*a9ac8606Spatrick __DEF_FUN1(float, asinh)
209*a9ac8606Spatrick __DEF_FUN1(float, atan)
210*a9ac8606Spatrick __DEF_FUN2(float, atan2)
211*a9ac8606Spatrick __DEF_FUN1(float, atanh)
212*a9ac8606Spatrick __DEF_FUN1(float, cbrt)
213*a9ac8606Spatrick __DEF_FUN1(float, ceil)
214*a9ac8606Spatrick __DEF_FUN2(float, copysign)
215*a9ac8606Spatrick __DEF_FUN1(float, cos)
216*a9ac8606Spatrick __DEF_FUN1(float, cosh)
217*a9ac8606Spatrick __DEF_FUN1(float, erf)
218*a9ac8606Spatrick __DEF_FUN1(float, erfc)
219*a9ac8606Spatrick __DEF_FUN1(float, exp)
220*a9ac8606Spatrick __DEF_FUN1(float, exp2)
221*a9ac8606Spatrick __DEF_FUN1(float, expm1)
222*a9ac8606Spatrick __DEF_FUN1(float, fabs)
223*a9ac8606Spatrick __DEF_FUN2(float, fdim)
224*a9ac8606Spatrick __DEF_FUN1(float, floor)
225*a9ac8606Spatrick __DEF_FUN2(float, fmax)
226*a9ac8606Spatrick __DEF_FUN2(float, fmin)
227*a9ac8606Spatrick __DEF_FUN2(float, fmod)
228*a9ac8606Spatrick __DEF_FUN2(float, hypot)
229*a9ac8606Spatrick __DEF_FUN1(int, ilogb)
230*a9ac8606Spatrick __DEF_FUN2_FI(float, ldexp)
231*a9ac8606Spatrick __DEF_FUN1(float, lgamma)
232*a9ac8606Spatrick __DEF_FUN1(float, log)
233*a9ac8606Spatrick __DEF_FUN1(float, log10)
234*a9ac8606Spatrick __DEF_FUN1(float, log1p)
235*a9ac8606Spatrick __DEF_FUN1(float, log2)
236*a9ac8606Spatrick __DEF_FUN1(float, logb)
237*a9ac8606Spatrick __DEF_FUN1(long long, llrint)
238*a9ac8606Spatrick __DEF_FUN1(long long, llround)
239*a9ac8606Spatrick __DEF_FUN1(long, lrint)
240*a9ac8606Spatrick __DEF_FUN1(long, lround)
241*a9ac8606Spatrick __DEF_FUN1(float, nearbyint)
242*a9ac8606Spatrick __DEF_FUN2(float, nextafter)
243*a9ac8606Spatrick __DEF_FUN2(float, pow)
244*a9ac8606Spatrick __DEF_FUN2(float, remainder)
245*a9ac8606Spatrick __DEF_FUN1(float, rint)
246*a9ac8606Spatrick __DEF_FUN1(float, round)
247*a9ac8606Spatrick __DEF_FUN2_FI(float, scalbn)
248*a9ac8606Spatrick __DEF_FUN1(float, sin)
249*a9ac8606Spatrick __DEF_FUN1(float, sinh)
250*a9ac8606Spatrick __DEF_FUN1(float, sqrt)
251*a9ac8606Spatrick __DEF_FUN1(float, tan)
252*a9ac8606Spatrick __DEF_FUN1(float, tanh)
253*a9ac8606Spatrick __DEF_FUN1(float, tgamma)
254*a9ac8606Spatrick __DEF_FUN1(float, trunc)
255*a9ac8606Spatrick 
256*a9ac8606Spatrick #pragma pop_macro("__DEF_FUN1")
257*a9ac8606Spatrick #pragma pop_macro("__DEF_FUN2")
258*a9ac8606Spatrick #pragma pop_macro("__DEF_FUN2_FI")
259*a9ac8606Spatrick 
260*a9ac8606Spatrick // END DEF_FUN
261*a9ac8606Spatrick 
262*a9ac8606Spatrick // BEGIN HIP_OVERLOAD
263*a9ac8606Spatrick 
264*a9ac8606Spatrick #pragma push_macro("__HIP_OVERLOAD1")
265*a9ac8606Spatrick #pragma push_macro("__HIP_OVERLOAD2")
266*a9ac8606Spatrick 
267*a9ac8606Spatrick // __hip_enable_if::type is a type function which returns __T if __B is true.
268*a9ac8606Spatrick template <bool __B, class __T = void> struct __hip_enable_if {};
269*a9ac8606Spatrick 
270*a9ac8606Spatrick template <class __T> struct __hip_enable_if<true, __T> { typedef __T type; };
271*a9ac8606Spatrick 
272*a9ac8606Spatrick namespace __hip {
273*a9ac8606Spatrick template <class _Tp> struct is_integral {
274*a9ac8606Spatrick   enum { value = 0 };
275*a9ac8606Spatrick };
276*a9ac8606Spatrick template <> struct is_integral<bool> {
277*a9ac8606Spatrick   enum { value = 1 };
278*a9ac8606Spatrick };
279*a9ac8606Spatrick template <> struct is_integral<char> {
280*a9ac8606Spatrick   enum { value = 1 };
281*a9ac8606Spatrick };
282*a9ac8606Spatrick template <> struct is_integral<signed char> {
283*a9ac8606Spatrick   enum { value = 1 };
284*a9ac8606Spatrick };
285*a9ac8606Spatrick template <> struct is_integral<unsigned char> {
286*a9ac8606Spatrick   enum { value = 1 };
287*a9ac8606Spatrick };
288*a9ac8606Spatrick template <> struct is_integral<wchar_t> {
289*a9ac8606Spatrick   enum { value = 1 };
290*a9ac8606Spatrick };
291*a9ac8606Spatrick template <> struct is_integral<short> {
292*a9ac8606Spatrick   enum { value = 1 };
293*a9ac8606Spatrick };
294*a9ac8606Spatrick template <> struct is_integral<unsigned short> {
295*a9ac8606Spatrick   enum { value = 1 };
296*a9ac8606Spatrick };
297*a9ac8606Spatrick template <> struct is_integral<int> {
298*a9ac8606Spatrick   enum { value = 1 };
299*a9ac8606Spatrick };
300*a9ac8606Spatrick template <> struct is_integral<unsigned int> {
301*a9ac8606Spatrick   enum { value = 1 };
302*a9ac8606Spatrick };
303*a9ac8606Spatrick template <> struct is_integral<long> {
304*a9ac8606Spatrick   enum { value = 1 };
305*a9ac8606Spatrick };
306*a9ac8606Spatrick template <> struct is_integral<unsigned long> {
307*a9ac8606Spatrick   enum { value = 1 };
308*a9ac8606Spatrick };
309*a9ac8606Spatrick template <> struct is_integral<long long> {
310*a9ac8606Spatrick   enum { value = 1 };
311*a9ac8606Spatrick };
312*a9ac8606Spatrick template <> struct is_integral<unsigned long long> {
313*a9ac8606Spatrick   enum { value = 1 };
314*a9ac8606Spatrick };
315*a9ac8606Spatrick 
316*a9ac8606Spatrick // ToDo: specializes is_arithmetic<_Float16>
317*a9ac8606Spatrick template <class _Tp> struct is_arithmetic {
318*a9ac8606Spatrick   enum { value = 0 };
319*a9ac8606Spatrick };
320*a9ac8606Spatrick template <> struct is_arithmetic<bool> {
321*a9ac8606Spatrick   enum { value = 1 };
322*a9ac8606Spatrick };
323*a9ac8606Spatrick template <> struct is_arithmetic<char> {
324*a9ac8606Spatrick   enum { value = 1 };
325*a9ac8606Spatrick };
326*a9ac8606Spatrick template <> struct is_arithmetic<signed char> {
327*a9ac8606Spatrick   enum { value = 1 };
328*a9ac8606Spatrick };
329*a9ac8606Spatrick template <> struct is_arithmetic<unsigned char> {
330*a9ac8606Spatrick   enum { value = 1 };
331*a9ac8606Spatrick };
332*a9ac8606Spatrick template <> struct is_arithmetic<wchar_t> {
333*a9ac8606Spatrick   enum { value = 1 };
334*a9ac8606Spatrick };
335*a9ac8606Spatrick template <> struct is_arithmetic<short> {
336*a9ac8606Spatrick   enum { value = 1 };
337*a9ac8606Spatrick };
338*a9ac8606Spatrick template <> struct is_arithmetic<unsigned short> {
339*a9ac8606Spatrick   enum { value = 1 };
340*a9ac8606Spatrick };
341*a9ac8606Spatrick template <> struct is_arithmetic<int> {
342*a9ac8606Spatrick   enum { value = 1 };
343*a9ac8606Spatrick };
344*a9ac8606Spatrick template <> struct is_arithmetic<unsigned int> {
345*a9ac8606Spatrick   enum { value = 1 };
346*a9ac8606Spatrick };
347*a9ac8606Spatrick template <> struct is_arithmetic<long> {
348*a9ac8606Spatrick   enum { value = 1 };
349*a9ac8606Spatrick };
350*a9ac8606Spatrick template <> struct is_arithmetic<unsigned long> {
351*a9ac8606Spatrick   enum { value = 1 };
352*a9ac8606Spatrick };
353*a9ac8606Spatrick template <> struct is_arithmetic<long long> {
354*a9ac8606Spatrick   enum { value = 1 };
355*a9ac8606Spatrick };
356*a9ac8606Spatrick template <> struct is_arithmetic<unsigned long long> {
357*a9ac8606Spatrick   enum { value = 1 };
358*a9ac8606Spatrick };
359*a9ac8606Spatrick template <> struct is_arithmetic<float> {
360*a9ac8606Spatrick   enum { value = 1 };
361*a9ac8606Spatrick };
362*a9ac8606Spatrick template <> struct is_arithmetic<double> {
363*a9ac8606Spatrick   enum { value = 1 };
364*a9ac8606Spatrick };
365*a9ac8606Spatrick 
366*a9ac8606Spatrick struct true_type {
367*a9ac8606Spatrick   static const __constant__ bool value = true;
368*a9ac8606Spatrick };
369*a9ac8606Spatrick struct false_type {
370*a9ac8606Spatrick   static const __constant__ bool value = false;
371*a9ac8606Spatrick };
372*a9ac8606Spatrick 
373*a9ac8606Spatrick template <typename __T, typename __U> struct is_same : public false_type {};
374*a9ac8606Spatrick template <typename __T> struct is_same<__T, __T> : public true_type {};
375*a9ac8606Spatrick 
376*a9ac8606Spatrick template <typename __T> struct add_rvalue_reference { typedef __T &&type; };
377*a9ac8606Spatrick 
378*a9ac8606Spatrick template <typename __T> typename add_rvalue_reference<__T>::type declval();
379*a9ac8606Spatrick 
380*a9ac8606Spatrick // decltype is only available in C++11 and above.
381*a9ac8606Spatrick #if __cplusplus >= 201103L
382*a9ac8606Spatrick // __hip_promote
383*a9ac8606Spatrick template <class _Tp> struct __numeric_type {
384*a9ac8606Spatrick   static void __test(...);
385*a9ac8606Spatrick   static _Float16 __test(_Float16);
386*a9ac8606Spatrick   static float __test(float);
387*a9ac8606Spatrick   static double __test(char);
388*a9ac8606Spatrick   static double __test(int);
389*a9ac8606Spatrick   static double __test(unsigned);
390*a9ac8606Spatrick   static double __test(long);
391*a9ac8606Spatrick   static double __test(unsigned long);
392*a9ac8606Spatrick   static double __test(long long);
393*a9ac8606Spatrick   static double __test(unsigned long long);
394*a9ac8606Spatrick   static double __test(double);
395*a9ac8606Spatrick   // No support for long double, use double instead.
396*a9ac8606Spatrick   static double __test(long double);
397*a9ac8606Spatrick 
398*a9ac8606Spatrick   typedef decltype(__test(declval<_Tp>())) type;
399*a9ac8606Spatrick   static const bool value = !is_same<type, void>::value;
400*a9ac8606Spatrick };
401*a9ac8606Spatrick 
402*a9ac8606Spatrick template <> struct __numeric_type<void> { static const bool value = true; };
403*a9ac8606Spatrick 
404*a9ac8606Spatrick template <class _A1, class _A2 = void, class _A3 = void,
405*a9ac8606Spatrick           bool = __numeric_type<_A1>::value &&__numeric_type<_A2>::value
406*a9ac8606Spatrick               &&__numeric_type<_A3>::value>
407*a9ac8606Spatrick class __promote_imp {
408*a9ac8606Spatrick public:
409*a9ac8606Spatrick   static const bool value = false;
410*a9ac8606Spatrick };
411*a9ac8606Spatrick 
412*a9ac8606Spatrick template <class _A1, class _A2, class _A3>
413*a9ac8606Spatrick class __promote_imp<_A1, _A2, _A3, true> {
414*a9ac8606Spatrick private:
415*a9ac8606Spatrick   typedef typename __promote_imp<_A1>::type __type1;
416*a9ac8606Spatrick   typedef typename __promote_imp<_A2>::type __type2;
417*a9ac8606Spatrick   typedef typename __promote_imp<_A3>::type __type3;
418*a9ac8606Spatrick 
419*a9ac8606Spatrick public:
420*a9ac8606Spatrick   typedef decltype(__type1() + __type2() + __type3()) type;
421*a9ac8606Spatrick   static const bool value = true;
422*a9ac8606Spatrick };
423*a9ac8606Spatrick 
424*a9ac8606Spatrick template <class _A1, class _A2> class __promote_imp<_A1, _A2, void, true> {
425*a9ac8606Spatrick private:
426*a9ac8606Spatrick   typedef typename __promote_imp<_A1>::type __type1;
427*a9ac8606Spatrick   typedef typename __promote_imp<_A2>::type __type2;
428*a9ac8606Spatrick 
429*a9ac8606Spatrick public:
430*a9ac8606Spatrick   typedef decltype(__type1() + __type2()) type;
431*a9ac8606Spatrick   static const bool value = true;
432*a9ac8606Spatrick };
433*a9ac8606Spatrick 
434*a9ac8606Spatrick template <class _A1> class __promote_imp<_A1, void, void, true> {
435*a9ac8606Spatrick public:
436*a9ac8606Spatrick   typedef typename __numeric_type<_A1>::type type;
437*a9ac8606Spatrick   static const bool value = true;
438*a9ac8606Spatrick };
439*a9ac8606Spatrick 
440*a9ac8606Spatrick template <class _A1, class _A2 = void, class _A3 = void>
441*a9ac8606Spatrick class __promote : public __promote_imp<_A1, _A2, _A3> {};
442*a9ac8606Spatrick #endif //__cplusplus >= 201103L
443*a9ac8606Spatrick } // namespace __hip
444*a9ac8606Spatrick 
445*a9ac8606Spatrick // __HIP_OVERLOAD1 is used to resolve function calls with integer argument to
446*a9ac8606Spatrick // avoid compilation error due to ambibuity. e.g. floor(5) is resolved with
447*a9ac8606Spatrick // floor(double).
448*a9ac8606Spatrick #define __HIP_OVERLOAD1(__retty, __fn)                                         \
449*a9ac8606Spatrick   template <typename __T>                                                      \
450*a9ac8606Spatrick   __DEVICE__ __CONSTEXPR__                                                     \
451*a9ac8606Spatrick       typename __hip_enable_if<__hip::is_integral<__T>::value, __retty>::type  \
452*a9ac8606Spatrick       __fn(__T __x) {                                                          \
453*a9ac8606Spatrick     return ::__fn((double)__x);                                                \
454*a9ac8606Spatrick   }
455*a9ac8606Spatrick 
456*a9ac8606Spatrick // __HIP_OVERLOAD2 is used to resolve function calls with mixed float/double
457*a9ac8606Spatrick // or integer argument to avoid compilation error due to ambibuity. e.g.
458*a9ac8606Spatrick // max(5.0f, 6.0) is resolved with max(double, double).
459*a9ac8606Spatrick #if __cplusplus >= 201103L
460*a9ac8606Spatrick #define __HIP_OVERLOAD2(__retty, __fn)                                         \
461*a9ac8606Spatrick   template <typename __T1, typename __T2>                                      \
462*a9ac8606Spatrick   __DEVICE__ __CONSTEXPR__ typename __hip_enable_if<                           \
463*a9ac8606Spatrick       __hip::is_arithmetic<__T1>::value && __hip::is_arithmetic<__T2>::value,  \
464*a9ac8606Spatrick       typename __hip::__promote<__T1, __T2>::type>::type                       \
465*a9ac8606Spatrick   __fn(__T1 __x, __T2 __y) {                                                   \
466*a9ac8606Spatrick     typedef typename __hip::__promote<__T1, __T2>::type __result_type;         \
467*a9ac8606Spatrick     return __fn((__result_type)__x, (__result_type)__y);                       \
468*a9ac8606Spatrick   }
469*a9ac8606Spatrick #else
470*a9ac8606Spatrick #define __HIP_OVERLOAD2(__retty, __fn)                                         \
471*a9ac8606Spatrick   template <typename __T1, typename __T2>                                      \
472*a9ac8606Spatrick   __DEVICE__ __CONSTEXPR__                                                     \
473*a9ac8606Spatrick       typename __hip_enable_if<__hip::is_arithmetic<__T1>::value &&            \
474*a9ac8606Spatrick                                    __hip::is_arithmetic<__T2>::value,          \
475*a9ac8606Spatrick                                __retty>::type                                  \
476*a9ac8606Spatrick       __fn(__T1 __x, __T2 __y) {                                               \
477*a9ac8606Spatrick     return __fn((double)__x, (double)__y);                                     \
478*a9ac8606Spatrick   }
479*a9ac8606Spatrick #endif
480*a9ac8606Spatrick 
481*a9ac8606Spatrick __HIP_OVERLOAD1(double, acos)
482*a9ac8606Spatrick __HIP_OVERLOAD1(double, acosh)
483*a9ac8606Spatrick __HIP_OVERLOAD1(double, asin)
484*a9ac8606Spatrick __HIP_OVERLOAD1(double, asinh)
485*a9ac8606Spatrick __HIP_OVERLOAD1(double, atan)
486*a9ac8606Spatrick __HIP_OVERLOAD2(double, atan2)
487*a9ac8606Spatrick __HIP_OVERLOAD1(double, atanh)
488*a9ac8606Spatrick __HIP_OVERLOAD1(double, cbrt)
489*a9ac8606Spatrick __HIP_OVERLOAD1(double, ceil)
490*a9ac8606Spatrick __HIP_OVERLOAD2(double, copysign)
491*a9ac8606Spatrick __HIP_OVERLOAD1(double, cos)
492*a9ac8606Spatrick __HIP_OVERLOAD1(double, cosh)
493*a9ac8606Spatrick __HIP_OVERLOAD1(double, erf)
494*a9ac8606Spatrick __HIP_OVERLOAD1(double, erfc)
495*a9ac8606Spatrick __HIP_OVERLOAD1(double, exp)
496*a9ac8606Spatrick __HIP_OVERLOAD1(double, exp2)
497*a9ac8606Spatrick __HIP_OVERLOAD1(double, expm1)
498*a9ac8606Spatrick __HIP_OVERLOAD1(double, fabs)
499*a9ac8606Spatrick __HIP_OVERLOAD2(double, fdim)
500*a9ac8606Spatrick __HIP_OVERLOAD1(double, floor)
501*a9ac8606Spatrick __HIP_OVERLOAD2(double, fmax)
502*a9ac8606Spatrick __HIP_OVERLOAD2(double, fmin)
503*a9ac8606Spatrick __HIP_OVERLOAD2(double, fmod)
504*a9ac8606Spatrick #if !defined(__HIPCC_RTC__)
505*a9ac8606Spatrick __HIP_OVERLOAD1(int, fpclassify)
506*a9ac8606Spatrick #endif // !defined(__HIPCC_RTC__)
507*a9ac8606Spatrick __HIP_OVERLOAD2(double, hypot)
508*a9ac8606Spatrick __HIP_OVERLOAD1(int, ilogb)
509*a9ac8606Spatrick __HIP_OVERLOAD1(bool, isfinite)
510*a9ac8606Spatrick __HIP_OVERLOAD2(bool, isgreater)
511*a9ac8606Spatrick __HIP_OVERLOAD2(bool, isgreaterequal)
512*a9ac8606Spatrick __HIP_OVERLOAD1(bool, isinf)
513*a9ac8606Spatrick __HIP_OVERLOAD2(bool, isless)
514*a9ac8606Spatrick __HIP_OVERLOAD2(bool, islessequal)
515*a9ac8606Spatrick __HIP_OVERLOAD2(bool, islessgreater)
516*a9ac8606Spatrick __HIP_OVERLOAD1(bool, isnan)
517*a9ac8606Spatrick __HIP_OVERLOAD1(bool, isnormal)
518*a9ac8606Spatrick __HIP_OVERLOAD2(bool, isunordered)
519*a9ac8606Spatrick __HIP_OVERLOAD1(double, lgamma)
520*a9ac8606Spatrick __HIP_OVERLOAD1(double, log)
521*a9ac8606Spatrick __HIP_OVERLOAD1(double, log10)
522*a9ac8606Spatrick __HIP_OVERLOAD1(double, log1p)
523*a9ac8606Spatrick __HIP_OVERLOAD1(double, log2)
524*a9ac8606Spatrick __HIP_OVERLOAD1(double, logb)
525*a9ac8606Spatrick __HIP_OVERLOAD1(long long, llrint)
526*a9ac8606Spatrick __HIP_OVERLOAD1(long long, llround)
527*a9ac8606Spatrick __HIP_OVERLOAD1(long, lrint)
528*a9ac8606Spatrick __HIP_OVERLOAD1(long, lround)
529*a9ac8606Spatrick __HIP_OVERLOAD1(double, nearbyint)
530*a9ac8606Spatrick __HIP_OVERLOAD2(double, nextafter)
531*a9ac8606Spatrick __HIP_OVERLOAD2(double, pow)
532*a9ac8606Spatrick __HIP_OVERLOAD2(double, remainder)
533*a9ac8606Spatrick __HIP_OVERLOAD1(double, rint)
534*a9ac8606Spatrick __HIP_OVERLOAD1(double, round)
535*a9ac8606Spatrick __HIP_OVERLOAD1(bool, signbit)
536*a9ac8606Spatrick __HIP_OVERLOAD1(double, sin)
537*a9ac8606Spatrick __HIP_OVERLOAD1(double, sinh)
538*a9ac8606Spatrick __HIP_OVERLOAD1(double, sqrt)
539*a9ac8606Spatrick __HIP_OVERLOAD1(double, tan)
540*a9ac8606Spatrick __HIP_OVERLOAD1(double, tanh)
541*a9ac8606Spatrick __HIP_OVERLOAD1(double, tgamma)
542*a9ac8606Spatrick __HIP_OVERLOAD1(double, trunc)
543*a9ac8606Spatrick 
544*a9ac8606Spatrick // Overload these but don't add them to std, they are not part of cmath.
545*a9ac8606Spatrick __HIP_OVERLOAD2(double, max)
546*a9ac8606Spatrick __HIP_OVERLOAD2(double, min)
547*a9ac8606Spatrick 
548*a9ac8606Spatrick // Additional Overloads that don't quite match HIP_OVERLOAD.
549*a9ac8606Spatrick #if __cplusplus >= 201103L
550*a9ac8606Spatrick template <typename __T1, typename __T2, typename __T3>
551*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ typename __hip_enable_if<
552*a9ac8606Spatrick     __hip::is_arithmetic<__T1>::value && __hip::is_arithmetic<__T2>::value &&
553*a9ac8606Spatrick         __hip::is_arithmetic<__T3>::value,
554*a9ac8606Spatrick     typename __hip::__promote<__T1, __T2, __T3>::type>::type
555*a9ac8606Spatrick fma(__T1 __x, __T2 __y, __T3 __z) {
556*a9ac8606Spatrick   typedef typename __hip::__promote<__T1, __T2, __T3>::type __result_type;
557*a9ac8606Spatrick   return ::fma((__result_type)__x, (__result_type)__y, (__result_type)__z);
558*a9ac8606Spatrick }
559*a9ac8606Spatrick #else
560*a9ac8606Spatrick template <typename __T1, typename __T2, typename __T3>
561*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__
562*a9ac8606Spatrick     typename __hip_enable_if<__hip::is_arithmetic<__T1>::value &&
563*a9ac8606Spatrick                                  __hip::is_arithmetic<__T2>::value &&
564*a9ac8606Spatrick                                  __hip::is_arithmetic<__T3>::value,
565*a9ac8606Spatrick                              double>::type
566*a9ac8606Spatrick     fma(__T1 __x, __T2 __y, __T3 __z) {
567*a9ac8606Spatrick   return ::fma((double)__x, (double)__y, (double)__z);
568*a9ac8606Spatrick }
569*a9ac8606Spatrick #endif
570*a9ac8606Spatrick 
571*a9ac8606Spatrick template <typename __T>
572*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__
573*a9ac8606Spatrick     typename __hip_enable_if<__hip::is_integral<__T>::value, double>::type
574*a9ac8606Spatrick     frexp(__T __x, int *__exp) {
575*a9ac8606Spatrick   return ::frexp((double)__x, __exp);
576*a9ac8606Spatrick }
577*a9ac8606Spatrick 
578*a9ac8606Spatrick template <typename __T>
579*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__
580*a9ac8606Spatrick     typename __hip_enable_if<__hip::is_integral<__T>::value, double>::type
581*a9ac8606Spatrick     ldexp(__T __x, int __exp) {
582*a9ac8606Spatrick   return ::ldexp((double)__x, __exp);
583*a9ac8606Spatrick }
584*a9ac8606Spatrick 
585*a9ac8606Spatrick template <typename __T>
586*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__
587*a9ac8606Spatrick     typename __hip_enable_if<__hip::is_integral<__T>::value, double>::type
588*a9ac8606Spatrick     modf(__T __x, double *__exp) {
589*a9ac8606Spatrick   return ::modf((double)__x, __exp);
590*a9ac8606Spatrick }
591*a9ac8606Spatrick 
592*a9ac8606Spatrick #if __cplusplus >= 201103L
593*a9ac8606Spatrick template <typename __T1, typename __T2>
594*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__
595*a9ac8606Spatrick     typename __hip_enable_if<__hip::is_arithmetic<__T1>::value &&
596*a9ac8606Spatrick                                  __hip::is_arithmetic<__T2>::value,
597*a9ac8606Spatrick                              typename __hip::__promote<__T1, __T2>::type>::type
598*a9ac8606Spatrick     remquo(__T1 __x, __T2 __y, int *__quo) {
599*a9ac8606Spatrick   typedef typename __hip::__promote<__T1, __T2>::type __result_type;
600*a9ac8606Spatrick   return ::remquo((__result_type)__x, (__result_type)__y, __quo);
601*a9ac8606Spatrick }
602*a9ac8606Spatrick #else
603*a9ac8606Spatrick template <typename __T1, typename __T2>
604*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__
605*a9ac8606Spatrick     typename __hip_enable_if<__hip::is_arithmetic<__T1>::value &&
606*a9ac8606Spatrick                                  __hip::is_arithmetic<__T2>::value,
607*a9ac8606Spatrick                              double>::type
608*a9ac8606Spatrick     remquo(__T1 __x, __T2 __y, int *__quo) {
609*a9ac8606Spatrick   return ::remquo((double)__x, (double)__y, __quo);
610*a9ac8606Spatrick }
611*a9ac8606Spatrick #endif
612*a9ac8606Spatrick 
613*a9ac8606Spatrick template <typename __T>
614*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__
615*a9ac8606Spatrick     typename __hip_enable_if<__hip::is_integral<__T>::value, double>::type
616*a9ac8606Spatrick     scalbln(__T __x, long int __exp) {
617*a9ac8606Spatrick   return ::scalbln((double)__x, __exp);
618*a9ac8606Spatrick }
619*a9ac8606Spatrick 
620*a9ac8606Spatrick template <typename __T>
621*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__
622*a9ac8606Spatrick     typename __hip_enable_if<__hip::is_integral<__T>::value, double>::type
623*a9ac8606Spatrick     scalbn(__T __x, int __exp) {
624*a9ac8606Spatrick   return ::scalbn((double)__x, __exp);
625*a9ac8606Spatrick }
626*a9ac8606Spatrick 
627*a9ac8606Spatrick #pragma pop_macro("__HIP_OVERLOAD1")
628*a9ac8606Spatrick #pragma pop_macro("__HIP_OVERLOAD2")
629*a9ac8606Spatrick 
630*a9ac8606Spatrick // END HIP_OVERLOAD
631*a9ac8606Spatrick 
632*a9ac8606Spatrick // END DEF_FUN and HIP_OVERLOAD
633*a9ac8606Spatrick 
634*a9ac8606Spatrick #endif // ifndef __OPENMP_AMDGCN__
635*a9ac8606Spatrick #endif // defined(__cplusplus)
636*a9ac8606Spatrick 
637*a9ac8606Spatrick #ifndef __OPENMP_AMDGCN__
638*a9ac8606Spatrick // Define these overloads inside the namespace our standard library uses.
639*a9ac8606Spatrick #if !defined(__HIPCC_RTC__)
640*a9ac8606Spatrick #ifdef _LIBCPP_BEGIN_NAMESPACE_STD
641*a9ac8606Spatrick _LIBCPP_BEGIN_NAMESPACE_STD
642*a9ac8606Spatrick #else
643*a9ac8606Spatrick namespace std {
644*a9ac8606Spatrick #ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
645*a9ac8606Spatrick _GLIBCXX_BEGIN_NAMESPACE_VERSION
646*a9ac8606Spatrick #endif // _GLIBCXX_BEGIN_NAMESPACE_VERSION
647*a9ac8606Spatrick #endif // _LIBCPP_BEGIN_NAMESPACE_STD
648*a9ac8606Spatrick 
649*a9ac8606Spatrick // Pull the new overloads we defined above into namespace std.
650*a9ac8606Spatrick // using ::abs; - This may be considered for C++.
651*a9ac8606Spatrick using ::acos;
652*a9ac8606Spatrick using ::acosh;
653*a9ac8606Spatrick using ::asin;
654*a9ac8606Spatrick using ::asinh;
655*a9ac8606Spatrick using ::atan;
656*a9ac8606Spatrick using ::atan2;
657*a9ac8606Spatrick using ::atanh;
658*a9ac8606Spatrick using ::cbrt;
659*a9ac8606Spatrick using ::ceil;
660*a9ac8606Spatrick using ::copysign;
661*a9ac8606Spatrick using ::cos;
662*a9ac8606Spatrick using ::cosh;
663*a9ac8606Spatrick using ::erf;
664*a9ac8606Spatrick using ::erfc;
665*a9ac8606Spatrick using ::exp;
666*a9ac8606Spatrick using ::exp2;
667*a9ac8606Spatrick using ::expm1;
668*a9ac8606Spatrick using ::fabs;
669*a9ac8606Spatrick using ::fdim;
670*a9ac8606Spatrick using ::floor;
671*a9ac8606Spatrick using ::fma;
672*a9ac8606Spatrick using ::fmax;
673*a9ac8606Spatrick using ::fmin;
674*a9ac8606Spatrick using ::fmod;
675*a9ac8606Spatrick using ::fpclassify;
676*a9ac8606Spatrick using ::frexp;
677*a9ac8606Spatrick using ::hypot;
678*a9ac8606Spatrick using ::ilogb;
679*a9ac8606Spatrick using ::isfinite;
680*a9ac8606Spatrick using ::isgreater;
681*a9ac8606Spatrick using ::isgreaterequal;
682*a9ac8606Spatrick using ::isless;
683*a9ac8606Spatrick using ::islessequal;
684*a9ac8606Spatrick using ::islessgreater;
685*a9ac8606Spatrick using ::isnormal;
686*a9ac8606Spatrick using ::isunordered;
687*a9ac8606Spatrick using ::ldexp;
688*a9ac8606Spatrick using ::lgamma;
689*a9ac8606Spatrick using ::llrint;
690*a9ac8606Spatrick using ::llround;
691*a9ac8606Spatrick using ::log;
692*a9ac8606Spatrick using ::log10;
693*a9ac8606Spatrick using ::log1p;
694*a9ac8606Spatrick using ::log2;
695*a9ac8606Spatrick using ::logb;
696*a9ac8606Spatrick using ::lrint;
697*a9ac8606Spatrick using ::lround;
698*a9ac8606Spatrick using ::modf;
699*a9ac8606Spatrick // using ::nan; - This may be considered for C++.
700*a9ac8606Spatrick // using ::nanf; - This may be considered for C++.
701*a9ac8606Spatrick // using ::nanl; - This is not yet defined.
702*a9ac8606Spatrick using ::nearbyint;
703*a9ac8606Spatrick using ::nextafter;
704*a9ac8606Spatrick // using ::nexttoward; - Omit this since we do not have a definition.
705*a9ac8606Spatrick using ::pow;
706*a9ac8606Spatrick using ::remainder;
707*a9ac8606Spatrick using ::remquo;
708*a9ac8606Spatrick using ::rint;
709*a9ac8606Spatrick using ::round;
710*a9ac8606Spatrick using ::scalbln;
711*a9ac8606Spatrick using ::scalbn;
712*a9ac8606Spatrick using ::signbit;
713*a9ac8606Spatrick using ::sin;
714*a9ac8606Spatrick using ::sinh;
715*a9ac8606Spatrick using ::sqrt;
716*a9ac8606Spatrick using ::tan;
717*a9ac8606Spatrick using ::tanh;
718*a9ac8606Spatrick using ::tgamma;
719*a9ac8606Spatrick using ::trunc;
720*a9ac8606Spatrick 
721*a9ac8606Spatrick // Well this is fun: We need to pull these symbols in for libc++, but we can't
722*a9ac8606Spatrick // pull them in with libstdc++, because its ::isinf and ::isnan are different
723*a9ac8606Spatrick // than its std::isinf and std::isnan.
724*a9ac8606Spatrick #ifndef __GLIBCXX__
725*a9ac8606Spatrick using ::isinf;
726*a9ac8606Spatrick using ::isnan;
727*a9ac8606Spatrick #endif
728*a9ac8606Spatrick 
729*a9ac8606Spatrick // Finally, pull the "foobarf" functions that HIP defines into std.
730*a9ac8606Spatrick using ::acosf;
731*a9ac8606Spatrick using ::acoshf;
732*a9ac8606Spatrick using ::asinf;
733*a9ac8606Spatrick using ::asinhf;
734*a9ac8606Spatrick using ::atan2f;
735*a9ac8606Spatrick using ::atanf;
736*a9ac8606Spatrick using ::atanhf;
737*a9ac8606Spatrick using ::cbrtf;
738*a9ac8606Spatrick using ::ceilf;
739*a9ac8606Spatrick using ::copysignf;
740*a9ac8606Spatrick using ::cosf;
741*a9ac8606Spatrick using ::coshf;
742*a9ac8606Spatrick using ::erfcf;
743*a9ac8606Spatrick using ::erff;
744*a9ac8606Spatrick using ::exp2f;
745*a9ac8606Spatrick using ::expf;
746*a9ac8606Spatrick using ::expm1f;
747*a9ac8606Spatrick using ::fabsf;
748*a9ac8606Spatrick using ::fdimf;
749*a9ac8606Spatrick using ::floorf;
750*a9ac8606Spatrick using ::fmaf;
751*a9ac8606Spatrick using ::fmaxf;
752*a9ac8606Spatrick using ::fminf;
753*a9ac8606Spatrick using ::fmodf;
754*a9ac8606Spatrick using ::frexpf;
755*a9ac8606Spatrick using ::hypotf;
756*a9ac8606Spatrick using ::ilogbf;
757*a9ac8606Spatrick using ::ldexpf;
758*a9ac8606Spatrick using ::lgammaf;
759*a9ac8606Spatrick using ::llrintf;
760*a9ac8606Spatrick using ::llroundf;
761*a9ac8606Spatrick using ::log10f;
762*a9ac8606Spatrick using ::log1pf;
763*a9ac8606Spatrick using ::log2f;
764*a9ac8606Spatrick using ::logbf;
765*a9ac8606Spatrick using ::logf;
766*a9ac8606Spatrick using ::lrintf;
767*a9ac8606Spatrick using ::lroundf;
768*a9ac8606Spatrick using ::modff;
769*a9ac8606Spatrick using ::nearbyintf;
770*a9ac8606Spatrick using ::nextafterf;
771*a9ac8606Spatrick // using ::nexttowardf; - Omit this since we do not have a definition.
772*a9ac8606Spatrick using ::powf;
773*a9ac8606Spatrick using ::remainderf;
774*a9ac8606Spatrick using ::remquof;
775*a9ac8606Spatrick using ::rintf;
776*a9ac8606Spatrick using ::roundf;
777*a9ac8606Spatrick using ::scalblnf;
778*a9ac8606Spatrick using ::scalbnf;
779*a9ac8606Spatrick using ::sinf;
780*a9ac8606Spatrick using ::sinhf;
781*a9ac8606Spatrick using ::sqrtf;
782*a9ac8606Spatrick using ::tanf;
783*a9ac8606Spatrick using ::tanhf;
784*a9ac8606Spatrick using ::tgammaf;
785*a9ac8606Spatrick using ::truncf;
786*a9ac8606Spatrick 
787*a9ac8606Spatrick #ifdef _LIBCPP_END_NAMESPACE_STD
788*a9ac8606Spatrick _LIBCPP_END_NAMESPACE_STD
789*a9ac8606Spatrick #else
790*a9ac8606Spatrick #ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
791*a9ac8606Spatrick _GLIBCXX_END_NAMESPACE_VERSION
792*a9ac8606Spatrick #endif // _GLIBCXX_BEGIN_NAMESPACE_VERSION
793*a9ac8606Spatrick } // namespace std
794*a9ac8606Spatrick #endif // _LIBCPP_END_NAMESPACE_STD
795*a9ac8606Spatrick #endif // !defined(__HIPCC_RTC__)
796*a9ac8606Spatrick 
797*a9ac8606Spatrick // Define device-side math functions from <ymath.h> on MSVC.
798*a9ac8606Spatrick #if !defined(__HIPCC_RTC__)
799*a9ac8606Spatrick #if defined(_MSC_VER)
800*a9ac8606Spatrick 
801*a9ac8606Spatrick // Before VS2019, `<ymath.h>` is also included in `<limits>` and other headers.
802*a9ac8606Spatrick // But, from VS2019, it's only included in `<complex>`. Need to include
803*a9ac8606Spatrick // `<ymath.h>` here to ensure C functions declared there won't be markded as
804*a9ac8606Spatrick // `__host__` and `__device__` through `<complex>` wrapper.
805*a9ac8606Spatrick #include <ymath.h>
806*a9ac8606Spatrick 
807*a9ac8606Spatrick #if defined(__cplusplus)
808*a9ac8606Spatrick extern "C" {
809*a9ac8606Spatrick #endif // defined(__cplusplus)
810*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) double _Cosh(double x,
811*a9ac8606Spatrick                                                                     double y) {
812*a9ac8606Spatrick   return cosh(x) * y;
813*a9ac8606Spatrick }
814*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) float _FCosh(float x,
815*a9ac8606Spatrick                                                                     float y) {
816*a9ac8606Spatrick   return coshf(x) * y;
817*a9ac8606Spatrick }
818*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) short _Dtest(double *p) {
819*a9ac8606Spatrick   return fpclassify(*p);
820*a9ac8606Spatrick }
821*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) short _FDtest(float *p) {
822*a9ac8606Spatrick   return fpclassify(*p);
823*a9ac8606Spatrick }
824*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) double _Sinh(double x,
825*a9ac8606Spatrick                                                                     double y) {
826*a9ac8606Spatrick   return sinh(x) * y;
827*a9ac8606Spatrick }
828*a9ac8606Spatrick __DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) float _FSinh(float x,
829*a9ac8606Spatrick                                                                     float y) {
830*a9ac8606Spatrick   return sinhf(x) * y;
831*a9ac8606Spatrick }
832*a9ac8606Spatrick #if defined(__cplusplus)
833*a9ac8606Spatrick }
834*a9ac8606Spatrick #endif // defined(__cplusplus)
835*a9ac8606Spatrick #endif // defined(_MSC_VER)
836*a9ac8606Spatrick #endif // !defined(__HIPCC_RTC__)
837*a9ac8606Spatrick #endif // ifndef __OPENMP_AMDGCN__
838*a9ac8606Spatrick 
839*a9ac8606Spatrick #pragma pop_macro("__DEVICE__")
840*a9ac8606Spatrick #pragma pop_macro("__CONSTEXPR__")
841*a9ac8606Spatrick 
842*a9ac8606Spatrick #endif // __CLANG_HIP_CMATH_H__
843