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