3#include <AMReX_Config.H>
21# include <sycl/sycl.hpp>
26inline namespace disabled {
62#if (defined(__FINITE_MATH_ONLY__) && (__FINITE_MATH_ONLY__ == 1)) \
63 || defined(__FAST_MATH__) || defined(_M_FP_FAST) || defined(_WIN32) \
65# define AMREX_MATH_ISNAN_BITS 1
74 U fp_opaque (U v)
noexcept
76#if defined(AMREX_MATH_ISNAN_BITS) && (defined(__GNUC__) || defined(__clang__))
77# if defined(__HIP_DEVICE_COMPILE__)
78 __asm__(
"" :
"+v"(v));
87 using fp_uint_t = std::conditional_t<
sizeof(T) == 8, std::uint64_t, std::uint32_t>;
92 constexpr fp_uint_t<T> fp_exp_mask ()
noexcept
94 return (
sizeof(T) == 8) ? fp_uint_t<T>(0x7ff0'0000'0000'0000ULL)
95 : fp_uint_t<T>(0x7f80'0000U);
99 template <
bool opaque = true,
typename T>
101 fp_uint_t<T> fp_abs_bits (T
x)
noexcept
103 using U = fp_uint_t<T>;
104 auto bits = std::bit_cast<U>(
x);
105 if constexpr (opaque) { bits = fp_opaque(bits); }
106 return bits & (~U(0) >> 1);
109 template <
typename T>
110 concept FloatOrDouble = std::same_as<T,float> || std::same_as<T,double>;
119#if defined(AMREX_USE_SYCL)
120 return sycl::isnan(
x);
122#if defined(AMREX_MATH_ISNAN_BITS)
123 if constexpr (detail::FloatOrDouble<T>) {
124 return detail::fp_abs_bits(
x) > detail::fp_exp_mask<T>();
128 return std::isnan(
x);
138#if defined(AMREX_USE_SYCL)
139 return sycl::isinf(
x);
141#if defined(AMREX_MATH_ISNAN_BITS)
142 if constexpr (detail::FloatOrDouble<T>) {
143 return detail::fp_abs_bits(
x) == detail::fp_exp_mask<T>();
147 return std::isinf(
x);
157#if defined(AMREX_USE_SYCL)
158 return sycl::isfinite(
x);
160#if defined(AMREX_MATH_ISNAN_BITS)
161 if constexpr (detail::FloatOrDouble<T>) {
162 return detail::fp_abs_bits(
x) < detail::fp_exp_mask<T>();
166 return std::isfinite(
x);
176 template <
typename T>
182 T operator() (T x)
const noexcept
184 if constexpr (FloatOrDouble<T>) {
185 auto const a = fp_abs_bits<false>(x);
186 return (a < fp_exp_mask<T>()) ? std::bit_cast<T>(a) : inf;
187 }
else if constexpr (std::is_floating_point_v<T>) {
196 static T make_inf () noexcept
198 if constexpr (FloatOrDouble<T>) {
199 return std::bit_cast<T>(fp_opaque(fp_exp_mask<T>()));
200 }
else if constexpr (std::is_floating_point_v<T>) {
201 return std::numeric_limits<T>::infinity();
210template <std::
floating_po
int T>
213 return std::numbers::pi_v<T>;
220#if defined(AMREX_USE_SYCL)
221 return sycl::cospi(
x);
232#if defined(AMREX_USE_SYCL)
233 return sycl::cospi(
x);
244#if defined(AMREX_USE_SYCL)
245 return sycl::sinpi(
x);
256#if defined(AMREX_USE_SYCL)
257 return sycl::sinpi(
x);
267#if defined(_GNU_SOURCE) && !defined(__APPLE__)
268 ::sincos(x, sinx, cosx);
276#if defined(_GNU_SOURCE) && !defined(__APPLE__)
277 ::sincosf(x, sinx, cosx);
288template<
typename T_Real>
289requires (amrex::simd::stdx::is_simd_v<T_Real>)
291std::pair<T_Real,T_Real>
sincos (T_Real
x)
294 std::pair<T_Real,T_Real> r;
305 std::pair<double,double> r;
306#if defined(AMREX_USE_SYCL)
307 r.first = sycl::sincos(
x, sycl::private_ptr<double>(&r.second));
319 std::pair<float,float> r;
320#if defined(AMREX_USE_SYCL)
321 r.first = sycl::sincos(
x, sycl::private_ptr<float>(&r.second));
331template<
typename T_Real>
332requires (amrex::simd::stdx::is_simd_v<T_Real>)
334std::pair<T_Real,T_Real>
sincospi (T_Real
x)
337 T_Real
const px = pi<typename T_Real::value_type>() *
x;
338 std::pair<T_Real,T_Real> r;
349 std::pair<double,double> r;
350#if defined(AMREX_USE_SYCL)
363 std::pair<float,float> r;
364#if defined(AMREX_USE_SYCL)
374template <
int Power,
typename T>
375requires (!std::integral<T> || Power >= 0)
379 if constexpr (Power < 0) {
380 return T(1)/
powi<-Power>(
x);
381 }
else if constexpr (Power == 0) {
384 }
else if constexpr (Power == 1) {
386 }
else if constexpr (Power == 2) {
388 }
else if constexpr (Power%2 == 0) {
389 return powi<2>(powi<Power/2>(
x));
391 return x*
powi<Power-1>(
x);
397#if defined(AMREX_USE_CUDA)
420#if defined(AMREX_USE_SYCL)
421 return sycl::pown(
x, n);
422#elif defined(AMREX_USE_HIP)
425#elif defined(AMREX_USE_CUDA)
429 return std::pow(
x,
static_cast<float>(n));
434double powi (
double x,
int n)
noexcept
436#if defined(AMREX_USE_SYCL)
437 return sycl::pown(
x, n);
438#elif defined(AMREX_USE_HIP)
441#elif defined(AMREX_USE_CUDA)
445 return std::pow(
x, n);
449#if defined(AMREX_INT128_SUPPORTED)
451std::uint64_t umulhi (std::uint64_t a, std::uint64_t b)
453#if defined(AMREX_USE_SYCL)
454 return sycl::mul_hi(a,b);
458 auto tmp = amrex::UInt128_t(a) * amrex::UInt128_t(b);
459 return std::uint64_t(tmp >> 64);
469 if (std::abs(k) == T(1)) {
470 return std::numeric_limits<T>::infinity();
474 T tol = std::numeric_limits<T>::epsilon();
477 T g0 = std::sqrt((T(1)+k)*(T(1)-k));
482 while(std::abs(a0 - g0) > tol) {
483 a = T(0.5)*(a0 + g0);
484 g = std::sqrt(a0 * g0);
490 return T(0.5)*pi<T>()/a;
497 if (std::abs(k) == T(1)) {
502 T Kcomp = amrex::Math::comp_ellint_1<T>(k);
503 T tol = std::numeric_limits<T>::epsilon();
507 T g0 = std::sqrt((T(1)+k)*(T(1)-k));
508 T cn = std::sqrt(a0*a0 - g0*g0);
512 T a = T(0.5) * (a0 + g0);
513 T g = std::sqrt(a0*g0);
514 cn = T(0.25)*cn*cn/a;
520 while(std::abs(cn*cn) > tol) {
522 a = T(0.5) * (a0 + g0);
523 g = std::sqrt(a0*g0);
524 cn = T(0.25)*cn*cn/a;
534 return Kcomp*sum_val;
542#if defined(AMREX_USE_SYCL)
556#if defined(AMREX_USE_SYCL)
570#if defined(AMREX_USE_SYCL)
584#if defined(AMREX_USE_SYCL)
644#ifdef AMREX_INT128_SUPPORTED
645 std::uint64_t multiplier = 1U;
646 unsigned int shift_right = 0;
647 unsigned int round_up = 0;
654 static std::uint32_t integer_log2 (std::uint64_t
x)
670 shift_right = integer_log2(
divisor);
676 std::uint64_t power_of_two = (std::uint64_t(1) << shift_right);
677 auto n = amrex::UInt128_t(power_of_two) << 64;
678 std::uint64_t multiplier_lo = n /
divisor;
681 round_up = (multiplier_lo == multiplier ? 1 : 0);
697 std::uint64_t
divide (std::uint64_t dividend)
const
699#if defined(AMREX_INT128_SUPPORTED)
702 x = amrex::Math::umulhi(dividend + round_up, multiplier);
704 return (
x >> shift_right);
712 std::uint64_t
modulus (std::uint64_t quotient, std::uint64_t dividend)
const
714 return dividend - quotient *
divisor;
719 std::uint64_t
divmod (std::uint64_t &remainder, std::uint64_t dividend)
const
721 auto quotient =
divide(dividend);
722 remainder =
modulus(quotient, dividend);
729 void operator() (std::uint64_t "ient, std::uint64_t &remainder, std::uint64_t dividend)
const
731 quotient =
divmod(remainder, dividend);
Compiler- and backend-specific extension macros (e.g., restrict, SIMD, inline).
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:124
#define AMREX_IF_ON_DEVICE(CODE)
Definition AMReX_GpuQualifiers.H:56
#define AMREX_IF_ON_HOST(CODE)
Definition AMReX_GpuQualifiers.H:58
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
__device__ double __nv_powi(double, int)
__device__ float __nv_powif(float, int)
Definition AMReX_Math.H:42
constexpr T pi()
Definition AMReX_Math.H:211
constexpr T powi(T x) noexcept
Return pow(x, Power), where Power is an integer known at compile time.
Definition AMReX_Math.H:377
__host__ __device__ bool isinf(T x) noexcept
Return true if x is +/-infinity. Works under fast math.
Definition AMReX_Math.H:136
__host__ __device__ double sinpi(double x)
Return sin(x*pi) given x.
Definition AMReX_Math.H:242
__host__ __device__ std::pair< double, double > sincospi(double x)
Return sin(pi*x) and cos(pi*x) given x.
Definition AMReX_Math.H:347
__host__ __device__ double cospi(double x)
Return cos(x*pi) given x.
Definition AMReX_Math.H:218
__host__ __device__ bool isnan(T x) noexcept
Return true if x is NaN. Works under fast math.
Definition AMReX_Math.H:117
__host__ __device__ double exp10(double x)
Return 10**x.
Definition AMReX_Math.H:567
__host__ __device__ T comp_ellint_1(T k)
Definition AMReX_Math.H:467
__host__ __device__ std::pair< double, double > sincos(double x)
Return sine and cosine of given number.
Definition AMReX_Math.H:303
__host__ __device__ T comp_ellint_2(T k)
Definition AMReX_Math.H:495
__host__ __device__ double rsqrt(double x)
Return inverse square root of x.
Definition AMReX_Math.H:539
__host__ __device__ bool isfinite(T x) noexcept
Return true if x is neither NaN nor infinity. Works under fast math.
Definition AMReX_Math.H:155
Definition AMReX_SIMD.H:25
Definition AMReX_Amr.cpp:50
__host__ __device__ T abs(const GpuComplex< T > &a_z) noexcept
Return the absolute value of a complex number.
Definition AMReX_GpuComplex.H:361
Definition AMReX_Math.H:641
__host__ __device__ std::uint64_t divide(std::uint64_t dividend) const
Returns the quotient of floor(dividend / divisor)
Definition AMReX_Math.H:697
__host__ __device__ std::uint64_t divmod(std::uint64_t &remainder, std::uint64_t dividend) const
Returns the quotient of floor(dividend / divisor) and computes the remainder.
Definition AMReX_Math.H:719
__host__ __device__ void operator()(std::uint64_t "ient, std::uint64_t &remainder, std::uint64_t dividend) const
Definition AMReX_Math.H:729
__host__ __device__ std::uint64_t modulus(std::uint64_t quotient, std::uint64_t dividend) const
Computes the remainder given a computed quotient and dividend.
Definition AMReX_Math.H:712
std::uint64_t divisor
Definition AMReX_Math.H:642
FastDivmodU64(std::uint64_t divisor_)
Definition AMReX_Math.H:688
FastDivmodU64()=default
Default construct an invalid FastDivmodU64.