Path: blob/main/contrib/llvm-project/clang/lib/Headers/__clang_hip_cmath.h
35233 views
/*===---- __clang_hip_cmath.h - HIP cmath decls -----------------------------===1*2* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3* See https://llvm.org/LICENSE.txt for license information.4* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5*6*===-----------------------------------------------------------------------===7*/89#ifndef __CLANG_HIP_CMATH_H__10#define __CLANG_HIP_CMATH_H__1112#if !defined(__HIP__) && !defined(__OPENMP_AMDGCN__)13#error "This file is for HIP and OpenMP AMDGCN device compilation only."14#endif1516#if !defined(__HIPCC_RTC__)17#if defined(__cplusplus)18#include <limits>19#include <type_traits>20#include <utility>21#endif22#include <limits.h>23#include <stdint.h>24#endif // !defined(__HIPCC_RTC__)2526#pragma push_macro("__DEVICE__")27#pragma push_macro("__CONSTEXPR__")28#ifdef __OPENMP_AMDGCN__29#define __DEVICE__ static __attribute__((always_inline, nothrow))30#define __CONSTEXPR__ constexpr31#else32#define __DEVICE__ static __device__ inline __attribute__((always_inline))33#define __CONSTEXPR__34#endif // __OPENMP_AMDGCN__3536// Start with functions that cannot be defined by DEF macros below.37#if defined(__cplusplus)38#if defined __OPENMP_AMDGCN__39__DEVICE__ __CONSTEXPR__ float fabs(float __x) { return ::fabsf(__x); }40__DEVICE__ __CONSTEXPR__ float sin(float __x) { return ::sinf(__x); }41__DEVICE__ __CONSTEXPR__ float cos(float __x) { return ::cosf(__x); }42#endif43__DEVICE__ __CONSTEXPR__ double abs(double __x) { return ::fabs(__x); }44__DEVICE__ __CONSTEXPR__ float abs(float __x) { return ::fabsf(__x); }45__DEVICE__ __CONSTEXPR__ long long abs(long long __n) { return ::llabs(__n); }46__DEVICE__ __CONSTEXPR__ long abs(long __n) { return ::labs(__n); }47__DEVICE__ __CONSTEXPR__ float fma(float __x, float __y, float __z) {48return ::fmaf(__x, __y, __z);49}50#if !defined(__HIPCC_RTC__)51// The value returned by fpclassify is platform dependent, therefore it is not52// supported by hipRTC.53__DEVICE__ __CONSTEXPR__ int fpclassify(float __x) {54return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,55FP_ZERO, __x);56}57__DEVICE__ __CONSTEXPR__ int fpclassify(double __x) {58return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,59FP_ZERO, __x);60}61#endif // !defined(__HIPCC_RTC__)6263__DEVICE__ __CONSTEXPR__ float frexp(float __arg, int *__exp) {64return ::frexpf(__arg, __exp);65}6667#if defined(__OPENMP_AMDGCN__)68// For OpenMP we work around some old system headers that have non-conforming69// `isinf(float)` and `isnan(float)` implementations that return an `int`. We do70// this by providing two versions of these functions, differing only in the71// return type. To avoid conflicting definitions we disable implicit base72// function generation. That means we will end up with two specializations, one73// per type, but only one has a base function defined by the system header.74#pragma omp begin declare variant match( \75implementation = {extension(disable_implicit_base)})7677// FIXME: We lack an extension to customize the mangling of the variants, e.g.,78// add a suffix. This means we would clash with the names of the variants79// (note that we do not create implicit base functions here). To avoid80// this clash we add a new trait to some of them that is always true81// (this is LLVM after all ;)). It will only influence the mangled name82// of the variants inside the inner region and avoid the clash.83#pragma omp begin declare variant match(implementation = {vendor(llvm)})8485__DEVICE__ __CONSTEXPR__ int isinf(float __x) { return ::__isinff(__x); }86__DEVICE__ __CONSTEXPR__ int isinf(double __x) { return ::__isinf(__x); }87__DEVICE__ __CONSTEXPR__ int isfinite(float __x) { return ::__finitef(__x); }88__DEVICE__ __CONSTEXPR__ int isfinite(double __x) { return ::__finite(__x); }89__DEVICE__ __CONSTEXPR__ int isnan(float __x) { return ::__isnanf(__x); }90__DEVICE__ __CONSTEXPR__ int isnan(double __x) { return ::__isnan(__x); }9192#pragma omp end declare variant93#endif // defined(__OPENMP_AMDGCN__)9495__DEVICE__ __CONSTEXPR__ bool isinf(float __x) { return ::__isinff(__x); }96__DEVICE__ __CONSTEXPR__ bool isinf(double __x) { return ::__isinf(__x); }97__DEVICE__ __CONSTEXPR__ bool isfinite(float __x) { return ::__finitef(__x); }98__DEVICE__ __CONSTEXPR__ bool isfinite(double __x) { return ::__finite(__x); }99__DEVICE__ __CONSTEXPR__ bool isnan(float __x) { return ::__isnanf(__x); }100__DEVICE__ __CONSTEXPR__ bool isnan(double __x) { return ::__isnan(__x); }101102#if defined(__OPENMP_AMDGCN__)103#pragma omp end declare variant104#endif // defined(__OPENMP_AMDGCN__)105106__DEVICE__ __CONSTEXPR__ bool isgreater(float __x, float __y) {107return __builtin_isgreater(__x, __y);108}109__DEVICE__ __CONSTEXPR__ bool isgreater(double __x, double __y) {110return __builtin_isgreater(__x, __y);111}112__DEVICE__ __CONSTEXPR__ bool isgreaterequal(float __x, float __y) {113return __builtin_isgreaterequal(__x, __y);114}115__DEVICE__ __CONSTEXPR__ bool isgreaterequal(double __x, double __y) {116return __builtin_isgreaterequal(__x, __y);117}118__DEVICE__ __CONSTEXPR__ bool isless(float __x, float __y) {119return __builtin_isless(__x, __y);120}121__DEVICE__ __CONSTEXPR__ bool isless(double __x, double __y) {122return __builtin_isless(__x, __y);123}124__DEVICE__ __CONSTEXPR__ bool islessequal(float __x, float __y) {125return __builtin_islessequal(__x, __y);126}127__DEVICE__ __CONSTEXPR__ bool islessequal(double __x, double __y) {128return __builtin_islessequal(__x, __y);129}130__DEVICE__ __CONSTEXPR__ bool islessgreater(float __x, float __y) {131return __builtin_islessgreater(__x, __y);132}133__DEVICE__ __CONSTEXPR__ bool islessgreater(double __x, double __y) {134return __builtin_islessgreater(__x, __y);135}136__DEVICE__ __CONSTEXPR__ bool isnormal(float __x) {137return __builtin_isnormal(__x);138}139__DEVICE__ __CONSTEXPR__ bool isnormal(double __x) {140return __builtin_isnormal(__x);141}142__DEVICE__ __CONSTEXPR__ bool isunordered(float __x, float __y) {143return __builtin_isunordered(__x, __y);144}145__DEVICE__ __CONSTEXPR__ bool isunordered(double __x, double __y) {146return __builtin_isunordered(__x, __y);147}148__DEVICE__ __CONSTEXPR__ float modf(float __x, float *__iptr) {149return ::modff(__x, __iptr);150}151__DEVICE__ __CONSTEXPR__ float pow(float __base, int __iexp) {152return ::powif(__base, __iexp);153}154__DEVICE__ __CONSTEXPR__ double pow(double __base, int __iexp) {155return ::powi(__base, __iexp);156}157__DEVICE__ __CONSTEXPR__ float remquo(float __x, float __y, int *__quo) {158return ::remquof(__x, __y, __quo);159}160__DEVICE__ __CONSTEXPR__ float scalbln(float __x, long int __n) {161return ::scalblnf(__x, __n);162}163__DEVICE__ __CONSTEXPR__ bool signbit(float __x) { return ::__signbitf(__x); }164__DEVICE__ __CONSTEXPR__ bool signbit(double __x) { return ::__signbit(__x); }165166// Notably missing above is nexttoward. We omit it because167// ocml doesn't provide an implementation, and we don't want to be in the168// business of implementing tricky libm functions in this header.169170// Other functions.171__DEVICE__ __CONSTEXPR__ _Float16 fma(_Float16 __x, _Float16 __y,172_Float16 __z) {173return __builtin_fmaf16(__x, __y, __z);174}175__DEVICE__ __CONSTEXPR__ _Float16 pow(_Float16 __base, int __iexp) {176return __ocml_pown_f16(__base, __iexp);177}178179#ifndef __OPENMP_AMDGCN__180// BEGIN DEF_FUN and HIP_OVERLOAD181182// BEGIN DEF_FUN183184#pragma push_macro("__DEF_FUN1")185#pragma push_macro("__DEF_FUN2")186#pragma push_macro("__DEF_FUN2_FI")187188// Define cmath functions with float argument and returns __retty.189#define __DEF_FUN1(__retty, __func) \190__DEVICE__ __CONSTEXPR__ __retty __func(float __x) { return __func##f(__x); }191192// Define cmath functions with two float arguments and returns __retty.193#define __DEF_FUN2(__retty, __func) \194__DEVICE__ __CONSTEXPR__ __retty __func(float __x, float __y) { \195return __func##f(__x, __y); \196}197198// Define cmath functions with a float and an int argument and returns __retty.199#define __DEF_FUN2_FI(__retty, __func) \200__DEVICE__ __CONSTEXPR__ __retty __func(float __x, int __y) { \201return __func##f(__x, __y); \202}203204__DEF_FUN1(float, acos)205__DEF_FUN1(float, acosh)206__DEF_FUN1(float, asin)207__DEF_FUN1(float, asinh)208__DEF_FUN1(float, atan)209__DEF_FUN2(float, atan2)210__DEF_FUN1(float, atanh)211__DEF_FUN1(float, cbrt)212__DEF_FUN1(float, ceil)213__DEF_FUN2(float, copysign)214__DEF_FUN1(float, cos)215__DEF_FUN1(float, cosh)216__DEF_FUN1(float, erf)217__DEF_FUN1(float, erfc)218__DEF_FUN1(float, exp)219__DEF_FUN1(float, exp2)220__DEF_FUN1(float, expm1)221__DEF_FUN1(float, fabs)222__DEF_FUN2(float, fdim)223__DEF_FUN1(float, floor)224__DEF_FUN2(float, fmax)225__DEF_FUN2(float, fmin)226__DEF_FUN2(float, fmod)227__DEF_FUN2(float, hypot)228__DEF_FUN1(int, ilogb)229__DEF_FUN2_FI(float, ldexp)230__DEF_FUN1(float, lgamma)231__DEF_FUN1(float, log)232__DEF_FUN1(float, log10)233__DEF_FUN1(float, log1p)234__DEF_FUN1(float, log2)235__DEF_FUN1(float, logb)236__DEF_FUN1(long long, llrint)237__DEF_FUN1(long long, llround)238__DEF_FUN1(long, lrint)239__DEF_FUN1(long, lround)240__DEF_FUN1(float, nearbyint)241__DEF_FUN2(float, nextafter)242__DEF_FUN2(float, pow)243__DEF_FUN2(float, remainder)244__DEF_FUN1(float, rint)245__DEF_FUN1(float, round)246__DEF_FUN2_FI(float, scalbn)247__DEF_FUN1(float, sin)248__DEF_FUN1(float, sinh)249__DEF_FUN1(float, sqrt)250__DEF_FUN1(float, tan)251__DEF_FUN1(float, tanh)252__DEF_FUN1(float, tgamma)253__DEF_FUN1(float, trunc)254255#pragma pop_macro("__DEF_FUN1")256#pragma pop_macro("__DEF_FUN2")257#pragma pop_macro("__DEF_FUN2_FI")258259// END DEF_FUN260261// BEGIN HIP_OVERLOAD262263#pragma push_macro("__HIP_OVERLOAD1")264#pragma push_macro("__HIP_OVERLOAD2")265266// __hip_enable_if::type is a type function which returns __T if __B is true.267template <bool __B, class __T = void> struct __hip_enable_if {};268269template <class __T> struct __hip_enable_if<true, __T> { typedef __T type; };270271namespace __hip {272template <class _Tp> struct is_integral {273enum { value = 0 };274};275template <> struct is_integral<bool> {276enum { value = 1 };277};278template <> struct is_integral<char> {279enum { value = 1 };280};281template <> struct is_integral<signed char> {282enum { value = 1 };283};284template <> struct is_integral<unsigned char> {285enum { value = 1 };286};287template <> struct is_integral<wchar_t> {288enum { value = 1 };289};290template <> struct is_integral<short> {291enum { value = 1 };292};293template <> struct is_integral<unsigned short> {294enum { value = 1 };295};296template <> struct is_integral<int> {297enum { value = 1 };298};299template <> struct is_integral<unsigned int> {300enum { value = 1 };301};302template <> struct is_integral<long> {303enum { value = 1 };304};305template <> struct is_integral<unsigned long> {306enum { value = 1 };307};308template <> struct is_integral<long long> {309enum { value = 1 };310};311template <> struct is_integral<unsigned long long> {312enum { value = 1 };313};314315// ToDo: specializes is_arithmetic<_Float16>316template <class _Tp> struct is_arithmetic {317enum { value = 0 };318};319template <> struct is_arithmetic<bool> {320enum { value = 1 };321};322template <> struct is_arithmetic<char> {323enum { value = 1 };324};325template <> struct is_arithmetic<signed char> {326enum { value = 1 };327};328template <> struct is_arithmetic<unsigned char> {329enum { value = 1 };330};331template <> struct is_arithmetic<wchar_t> {332enum { value = 1 };333};334template <> struct is_arithmetic<short> {335enum { value = 1 };336};337template <> struct is_arithmetic<unsigned short> {338enum { value = 1 };339};340template <> struct is_arithmetic<int> {341enum { value = 1 };342};343template <> struct is_arithmetic<unsigned int> {344enum { value = 1 };345};346template <> struct is_arithmetic<long> {347enum { value = 1 };348};349template <> struct is_arithmetic<unsigned long> {350enum { value = 1 };351};352template <> struct is_arithmetic<long long> {353enum { value = 1 };354};355template <> struct is_arithmetic<unsigned long long> {356enum { value = 1 };357};358template <> struct is_arithmetic<float> {359enum { value = 1 };360};361template <> struct is_arithmetic<double> {362enum { value = 1 };363};364365struct true_type {366static const __constant__ bool value = true;367};368struct false_type {369static const __constant__ bool value = false;370};371372template <typename __T, typename __U> struct is_same : public false_type {};373template <typename __T> struct is_same<__T, __T> : public true_type {};374375template <typename __T> struct add_rvalue_reference { typedef __T &&type; };376377template <typename __T> typename add_rvalue_reference<__T>::type declval();378379// decltype is only available in C++11 and above.380#if __cplusplus >= 201103L381// __hip_promote382template <class _Tp> struct __numeric_type {383static void __test(...);384static _Float16 __test(_Float16);385static float __test(float);386static double __test(char);387static double __test(int);388static double __test(unsigned);389static double __test(long);390static double __test(unsigned long);391static double __test(long long);392static double __test(unsigned long long);393static double __test(double);394// No support for long double, use double instead.395static double __test(long double);396397typedef decltype(__test(declval<_Tp>())) type;398static const bool value = !is_same<type, void>::value;399};400401template <> struct __numeric_type<void> { static const bool value = true; };402403template <class _A1, class _A2 = void, class _A3 = void,404bool = __numeric_type<_A1>::value &&__numeric_type<_A2>::value405&&__numeric_type<_A3>::value>406class __promote_imp {407public:408static const bool value = false;409};410411template <class _A1, class _A2, class _A3>412class __promote_imp<_A1, _A2, _A3, true> {413private:414typedef typename __promote_imp<_A1>::type __type1;415typedef typename __promote_imp<_A2>::type __type2;416typedef typename __promote_imp<_A3>::type __type3;417418public:419typedef decltype(__type1() + __type2() + __type3()) type;420static const bool value = true;421};422423template <class _A1, class _A2> class __promote_imp<_A1, _A2, void, true> {424private:425typedef typename __promote_imp<_A1>::type __type1;426typedef typename __promote_imp<_A2>::type __type2;427428public:429typedef decltype(__type1() + __type2()) type;430static const bool value = true;431};432433template <class _A1> class __promote_imp<_A1, void, void, true> {434public:435typedef typename __numeric_type<_A1>::type type;436static const bool value = true;437};438439template <class _A1, class _A2 = void, class _A3 = void>440class __promote : public __promote_imp<_A1, _A2, _A3> {};441#endif //__cplusplus >= 201103L442} // namespace __hip443444// __HIP_OVERLOAD1 is used to resolve function calls with integer argument to445// avoid compilation error due to ambibuity. e.g. floor(5) is resolved with446// floor(double).447#define __HIP_OVERLOAD1(__retty, __fn) \448template <typename __T> \449__DEVICE__ __CONSTEXPR__ \450typename __hip_enable_if<__hip::is_integral<__T>::value, __retty>::type \451__fn(__T __x) { \452return ::__fn((double)__x); \453}454455// __HIP_OVERLOAD2 is used to resolve function calls with mixed float/double456// or integer argument to avoid compilation error due to ambibuity. e.g.457// max(5.0f, 6.0) is resolved with max(double, double).458#if __cplusplus >= 201103L459#define __HIP_OVERLOAD2(__retty, __fn) \460template <typename __T1, typename __T2> \461__DEVICE__ __CONSTEXPR__ typename __hip_enable_if< \462__hip::is_arithmetic<__T1>::value && __hip::is_arithmetic<__T2>::value, \463typename __hip::__promote<__T1, __T2>::type>::type \464__fn(__T1 __x, __T2 __y) { \465typedef typename __hip::__promote<__T1, __T2>::type __result_type; \466return __fn((__result_type)__x, (__result_type)__y); \467}468#else469#define __HIP_OVERLOAD2(__retty, __fn) \470template <typename __T1, typename __T2> \471__DEVICE__ __CONSTEXPR__ \472typename __hip_enable_if<__hip::is_arithmetic<__T1>::value && \473__hip::is_arithmetic<__T2>::value, \474__retty>::type \475__fn(__T1 __x, __T2 __y) { \476return __fn((double)__x, (double)__y); \477}478#endif479480__HIP_OVERLOAD1(double, acos)481__HIP_OVERLOAD1(double, acosh)482__HIP_OVERLOAD1(double, asin)483__HIP_OVERLOAD1(double, asinh)484__HIP_OVERLOAD1(double, atan)485__HIP_OVERLOAD2(double, atan2)486__HIP_OVERLOAD1(double, atanh)487__HIP_OVERLOAD1(double, cbrt)488__HIP_OVERLOAD1(double, ceil)489__HIP_OVERLOAD2(double, copysign)490__HIP_OVERLOAD1(double, cos)491__HIP_OVERLOAD1(double, cosh)492__HIP_OVERLOAD1(double, erf)493__HIP_OVERLOAD1(double, erfc)494__HIP_OVERLOAD1(double, exp)495__HIP_OVERLOAD1(double, exp2)496__HIP_OVERLOAD1(double, expm1)497__HIP_OVERLOAD1(double, fabs)498__HIP_OVERLOAD2(double, fdim)499__HIP_OVERLOAD1(double, floor)500__HIP_OVERLOAD2(double, fmax)501__HIP_OVERLOAD2(double, fmin)502__HIP_OVERLOAD2(double, fmod)503#if !defined(__HIPCC_RTC__)504__HIP_OVERLOAD1(int, fpclassify)505#endif // !defined(__HIPCC_RTC__)506__HIP_OVERLOAD2(double, hypot)507__HIP_OVERLOAD1(int, ilogb)508__HIP_OVERLOAD1(bool, isfinite)509__HIP_OVERLOAD2(bool, isgreater)510__HIP_OVERLOAD2(bool, isgreaterequal)511__HIP_OVERLOAD1(bool, isinf)512__HIP_OVERLOAD2(bool, isless)513__HIP_OVERLOAD2(bool, islessequal)514__HIP_OVERLOAD2(bool, islessgreater)515__HIP_OVERLOAD1(bool, isnan)516__HIP_OVERLOAD1(bool, isnormal)517__HIP_OVERLOAD2(bool, isunordered)518__HIP_OVERLOAD1(double, lgamma)519__HIP_OVERLOAD1(double, log)520__HIP_OVERLOAD1(double, log10)521__HIP_OVERLOAD1(double, log1p)522__HIP_OVERLOAD1(double, log2)523__HIP_OVERLOAD1(double, logb)524__HIP_OVERLOAD1(long long, llrint)525__HIP_OVERLOAD1(long long, llround)526__HIP_OVERLOAD1(long, lrint)527__HIP_OVERLOAD1(long, lround)528__HIP_OVERLOAD1(double, nearbyint)529__HIP_OVERLOAD2(double, nextafter)530__HIP_OVERLOAD2(double, pow)531__HIP_OVERLOAD2(double, remainder)532__HIP_OVERLOAD1(double, rint)533__HIP_OVERLOAD1(double, round)534__HIP_OVERLOAD1(bool, signbit)535__HIP_OVERLOAD1(double, sin)536__HIP_OVERLOAD1(double, sinh)537__HIP_OVERLOAD1(double, sqrt)538__HIP_OVERLOAD1(double, tan)539__HIP_OVERLOAD1(double, tanh)540__HIP_OVERLOAD1(double, tgamma)541__HIP_OVERLOAD1(double, trunc)542543// Overload these but don't add them to std, they are not part of cmath.544__HIP_OVERLOAD2(double, max)545__HIP_OVERLOAD2(double, min)546547// Additional Overloads that don't quite match HIP_OVERLOAD.548#if __cplusplus >= 201103L549template <typename __T1, typename __T2, typename __T3>550__DEVICE__ __CONSTEXPR__ typename __hip_enable_if<551__hip::is_arithmetic<__T1>::value && __hip::is_arithmetic<__T2>::value &&552__hip::is_arithmetic<__T3>::value,553typename __hip::__promote<__T1, __T2, __T3>::type>::type554fma(__T1 __x, __T2 __y, __T3 __z) {555typedef typename __hip::__promote<__T1, __T2, __T3>::type __result_type;556return ::fma((__result_type)__x, (__result_type)__y, (__result_type)__z);557}558#else559template <typename __T1, typename __T2, typename __T3>560__DEVICE__ __CONSTEXPR__561typename __hip_enable_if<__hip::is_arithmetic<__T1>::value &&562__hip::is_arithmetic<__T2>::value &&563__hip::is_arithmetic<__T3>::value,564double>::type565fma(__T1 __x, __T2 __y, __T3 __z) {566return ::fma((double)__x, (double)__y, (double)__z);567}568#endif569570template <typename __T>571__DEVICE__ __CONSTEXPR__572typename __hip_enable_if<__hip::is_integral<__T>::value, double>::type573frexp(__T __x, int *__exp) {574return ::frexp((double)__x, __exp);575}576577template <typename __T>578__DEVICE__ __CONSTEXPR__579typename __hip_enable_if<__hip::is_integral<__T>::value, double>::type580ldexp(__T __x, int __exp) {581return ::ldexp((double)__x, __exp);582}583584template <typename __T>585__DEVICE__ __CONSTEXPR__586typename __hip_enable_if<__hip::is_integral<__T>::value, double>::type587modf(__T __x, double *__exp) {588return ::modf((double)__x, __exp);589}590591#if __cplusplus >= 201103L592template <typename __T1, typename __T2>593__DEVICE__ __CONSTEXPR__594typename __hip_enable_if<__hip::is_arithmetic<__T1>::value &&595__hip::is_arithmetic<__T2>::value,596typename __hip::__promote<__T1, __T2>::type>::type597remquo(__T1 __x, __T2 __y, int *__quo) {598typedef typename __hip::__promote<__T1, __T2>::type __result_type;599return ::remquo((__result_type)__x, (__result_type)__y, __quo);600}601#else602template <typename __T1, typename __T2>603__DEVICE__ __CONSTEXPR__604typename __hip_enable_if<__hip::is_arithmetic<__T1>::value &&605__hip::is_arithmetic<__T2>::value,606double>::type607remquo(__T1 __x, __T2 __y, int *__quo) {608return ::remquo((double)__x, (double)__y, __quo);609}610#endif611612template <typename __T>613__DEVICE__ __CONSTEXPR__614typename __hip_enable_if<__hip::is_integral<__T>::value, double>::type615scalbln(__T __x, long int __exp) {616return ::scalbln((double)__x, __exp);617}618619template <typename __T>620__DEVICE__ __CONSTEXPR__621typename __hip_enable_if<__hip::is_integral<__T>::value, double>::type622scalbn(__T __x, int __exp) {623return ::scalbn((double)__x, __exp);624}625626#pragma pop_macro("__HIP_OVERLOAD1")627#pragma pop_macro("__HIP_OVERLOAD2")628629// END HIP_OVERLOAD630631// END DEF_FUN and HIP_OVERLOAD632633#endif // ifndef __OPENMP_AMDGCN__634#endif // defined(__cplusplus)635636#ifndef __OPENMP_AMDGCN__637// Define these overloads inside the namespace our standard library uses.638#if !defined(__HIPCC_RTC__)639#ifdef _LIBCPP_BEGIN_NAMESPACE_STD640_LIBCPP_BEGIN_NAMESPACE_STD641#else642namespace std {643#ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION644_GLIBCXX_BEGIN_NAMESPACE_VERSION645#endif // _GLIBCXX_BEGIN_NAMESPACE_VERSION646#endif // _LIBCPP_BEGIN_NAMESPACE_STD647648// Pull the new overloads we defined above into namespace std.649// using ::abs; - This may be considered for C++.650using ::acos;651using ::acosh;652using ::asin;653using ::asinh;654using ::atan;655using ::atan2;656using ::atanh;657using ::cbrt;658using ::ceil;659using ::copysign;660using ::cos;661using ::cosh;662using ::erf;663using ::erfc;664using ::exp;665using ::exp2;666using ::expm1;667using ::fabs;668using ::fdim;669using ::floor;670using ::fma;671using ::fmax;672using ::fmin;673using ::fmod;674using ::fpclassify;675using ::frexp;676using ::hypot;677using ::ilogb;678using ::isfinite;679using ::isgreater;680using ::isgreaterequal;681using ::isless;682using ::islessequal;683using ::islessgreater;684using ::isnormal;685using ::isunordered;686using ::ldexp;687using ::lgamma;688using ::llrint;689using ::llround;690using ::log;691using ::log10;692using ::log1p;693using ::log2;694using ::logb;695using ::lrint;696using ::lround;697using ::modf;698// using ::nan; - This may be considered for C++.699// using ::nanf; - This may be considered for C++.700// using ::nanl; - This is not yet defined.701using ::nearbyint;702using ::nextafter;703// using ::nexttoward; - Omit this since we do not have a definition.704using ::pow;705using ::remainder;706using ::remquo;707using ::rint;708using ::round;709using ::scalbln;710using ::scalbn;711using ::signbit;712using ::sin;713using ::sinh;714using ::sqrt;715using ::tan;716using ::tanh;717using ::tgamma;718using ::trunc;719720// Well this is fun: We need to pull these symbols in for libc++, but we can't721// pull them in with libstdc++, because its ::isinf and ::isnan are different722// than its std::isinf and std::isnan.723#ifndef __GLIBCXX__724using ::isinf;725using ::isnan;726#endif727728// Finally, pull the "foobarf" functions that HIP defines into std.729using ::acosf;730using ::acoshf;731using ::asinf;732using ::asinhf;733using ::atan2f;734using ::atanf;735using ::atanhf;736using ::cbrtf;737using ::ceilf;738using ::copysignf;739using ::cosf;740using ::coshf;741using ::erfcf;742using ::erff;743using ::exp2f;744using ::expf;745using ::expm1f;746using ::fabsf;747using ::fdimf;748using ::floorf;749using ::fmaf;750using ::fmaxf;751using ::fminf;752using ::fmodf;753using ::frexpf;754using ::hypotf;755using ::ilogbf;756using ::ldexpf;757using ::lgammaf;758using ::llrintf;759using ::llroundf;760using ::log10f;761using ::log1pf;762using ::log2f;763using ::logbf;764using ::logf;765using ::lrintf;766using ::lroundf;767using ::modff;768using ::nearbyintf;769using ::nextafterf;770// using ::nexttowardf; - Omit this since we do not have a definition.771using ::powf;772using ::remainderf;773using ::remquof;774using ::rintf;775using ::roundf;776using ::scalblnf;777using ::scalbnf;778using ::sinf;779using ::sinhf;780using ::sqrtf;781using ::tanf;782using ::tanhf;783using ::tgammaf;784using ::truncf;785786#ifdef _LIBCPP_END_NAMESPACE_STD787_LIBCPP_END_NAMESPACE_STD788#else789#ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION790_GLIBCXX_END_NAMESPACE_VERSION791#endif // _GLIBCXX_BEGIN_NAMESPACE_VERSION792} // namespace std793#endif // _LIBCPP_END_NAMESPACE_STD794#endif // !defined(__HIPCC_RTC__)795796// Define device-side math functions from <ymath.h> on MSVC.797#if !defined(__HIPCC_RTC__)798#if defined(_MSC_VER)799800// Before VS2019, `<ymath.h>` is also included in `<limits>` and other headers.801// But, from VS2019, it's only included in `<complex>`. Need to include802// `<ymath.h>` here to ensure C functions declared there won't be markded as803// `__host__` and `__device__` through `<complex>` wrapper.804#include <ymath.h>805806#if defined(__cplusplus)807extern "C" {808#endif // defined(__cplusplus)809__DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) double _Cosh(double x,810double y) {811return cosh(x) * y;812}813__DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) float _FCosh(float x,814float y) {815return coshf(x) * y;816}817__DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) short _Dtest(double *p) {818return fpclassify(*p);819}820__DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) short _FDtest(float *p) {821return fpclassify(*p);822}823__DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) double _Sinh(double x,824double y) {825return sinh(x) * y;826}827__DEVICE__ __CONSTEXPR__ __attribute__((overloadable)) float _FSinh(float x,828float y) {829return sinhf(x) * y;830}831#if defined(__cplusplus)832}833#endif // defined(__cplusplus)834#endif // defined(_MSC_VER)835#endif // !defined(__HIPCC_RTC__)836#endif // ifndef __OPENMP_AMDGCN__837838#pragma pop_macro("__DEVICE__")839#pragma pop_macro("__CONSTEXPR__")840841#endif // __CLANG_HIP_CMATH_H__842843844