//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ // **** DO NOT EDIT THIS FILE!!! **** // This file is automatically generated by Math.h.in #ifndef vtk_m_Math_h #define vtk_m_Math_h #include #include #include #include // must be found with or without CUDA. #ifndef VTKM_CUDA #include #include #include #include #include #endif // !VTKM_CUDA #if !defined(VTKM_CUDA_DEVICE_PASS) #define VTKM_USE_STL #include #endif #ifdef VTKM_MSVC #include // For bitwise intrinsics (__popcnt, etc) #include // for types used by MSVC intrinsics. #ifndef VTKM_CUDA #include #endif // VTKM_CUDA #endif // VTKM_MSVC #define VTKM_CUDA_MATH_FUNCTION_32(func) func##f #define VTKM_CUDA_MATH_FUNCTION_64(func) func // clang-format off namespace vtkm { //----------------------------------------------------------------------------- namespace detail { template struct FloatingPointReturnType { using ctype = typename vtkm::VecTraits::ComponentType; using representable_as_float_type = std::integral_constant::value)>; using Type = typename std::conditional::type; }; } // namespace detail /// Returns the constant 2 times Pi in float32. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float32 TwoPif() { return 6.28318530717958647692528676655900576f; } /// Returns the constant Pi in float32. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float32 Pif() { return 3.14159265358979323846264338327950288f; } /// Returns the constant Pi halves in float32. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float32 Pi_2f() { return 1.57079632679489661923132169163975144f; } /// Returns the constant Pi thirds in float32. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float32 Pi_3f() { return 1.04719755119659774615421446109316762f; } /// Returns the constant Pi fourths in float32. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float32 Pi_4f() { return 0.78539816339744830961566084581987572f; } /// Returns the constant Pi one hundred and eightieth in float32. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float32 Pi_180f() { return 0.01745329251994329547437168059786927f; } /// Returns the constant 2 times Pi in float64. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float64 TwoPi() { return 6.28318530717958647692528676655900576; } /// Returns the constant Pi in float64. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float64 Pi() { return 3.14159265358979323846264338327950288; } /// Returns the constant Pi halves in float64. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float64 Pi_2() { return 1.57079632679489661923132169163975144; } /// Returns the constant Pi thirds in float64. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float64 Pi_3() { return 1.04719755119659774615421446109316762; } /// Returns the constant Pi fourths in float64. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float64 Pi_4() { return 0.78539816339744830961566084581987572; } /// Returns the constant Pi one hundred and eightieth in float64. /// static constexpr inline VTKM_EXEC_CONT vtkm::Float64 Pi_180() { return 0.01745329251994329547437168059786927; } /// Returns the constant 2 times Pi. /// template static constexpr inline VTKM_EXEC_CONT auto TwoPi() -> typename detail::FloatingPointReturnType::Type { using FT = typename detail::FloatingPointReturnType::Type; using RAFT = typename detail::FloatingPointReturnType::representable_as_float_type; return static_cast(RAFT::value ? TwoPif() : TwoPi()); } /// Returns the constant Pi. /// template static constexpr inline VTKM_EXEC_CONT auto Pi() -> typename detail::FloatingPointReturnType::Type { using FT = typename detail::FloatingPointReturnType::Type; using RAFT = typename detail::FloatingPointReturnType::representable_as_float_type; return static_cast(RAFT::value ? Pif() : Pi()); } /// Returns the constant Pi halves. /// template static constexpr inline VTKM_EXEC_CONT auto Pi_2() -> typename detail::FloatingPointReturnType::Type { using FT = typename detail::FloatingPointReturnType::Type; using RAFT = typename detail::FloatingPointReturnType::representable_as_float_type; return static_cast(RAFT::value ? Pi_2f() : Pi_2()); } /// Returns the constant Pi thirds. /// template static constexpr inline VTKM_EXEC_CONT auto Pi_3() -> typename detail::FloatingPointReturnType::Type { using FT = typename detail::FloatingPointReturnType::Type; using RAFT = typename detail::FloatingPointReturnType::representable_as_float_type; return static_cast(RAFT::value ? Pi_3f() : Pi_3()); } /// Returns the constant Pi fourths. /// template static constexpr inline VTKM_EXEC_CONT auto Pi_4() -> typename detail::FloatingPointReturnType::Type { using FT = typename detail::FloatingPointReturnType::Type; using RAFT = typename detail::FloatingPointReturnType::representable_as_float_type; return static_cast(RAFT::value ? Pi_4f() : Pi_4()); } /// Returns the constant Pi one hundred and eightieth. /// template static constexpr inline VTKM_EXEC_CONT auto Pi_180() -> typename detail::FloatingPointReturnType::Type { using FT = typename detail::FloatingPointReturnType::Type; using RAFT = typename detail::FloatingPointReturnType::representable_as_float_type; return static_cast(RAFT::value ? Pi_180f() : Pi_180()); } /// Compute the sine of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 Sin(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(sin)(x); #else return std::sin(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Sin(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(sin)(x); #else return std::sin(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Sin(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Sin(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Sin( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Sin(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Sin( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Sin(x[0]), vtkm::Sin(x[1]), vtkm::Sin(x[2]), vtkm::Sin(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Sin( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Sin(x[0]), vtkm::Sin(x[1]), vtkm::Sin(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Sin( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Sin(x[0]), vtkm::Sin(x[1])); } /// Compute the cosine of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 Cos(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(cos)(x); #else return std::cos(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Cos(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(cos)(x); #else return std::cos(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Cos(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Cos(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Cos( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Cos(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Cos( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Cos(x[0]), vtkm::Cos(x[1]), vtkm::Cos(x[2]), vtkm::Cos(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Cos( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Cos(x[0]), vtkm::Cos(x[1]), vtkm::Cos(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Cos( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Cos(x[0]), vtkm::Cos(x[1])); } /// Compute the tangent of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 Tan(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(tan)(x); #else return std::tan(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Tan(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(tan)(x); #else return std::tan(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Tan(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Tan(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Tan( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Tan(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Tan( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Tan(x[0]), vtkm::Tan(x[1]), vtkm::Tan(x[2]), vtkm::Tan(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Tan( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Tan(x[0]), vtkm::Tan(x[1]), vtkm::Tan(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Tan( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Tan(x[0]), vtkm::Tan(x[1])); } /// Compute the arc sine of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 ASin(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(asin)(x); #else return std::asin(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 ASin(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(asin)(x); #else return std::asin(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type ASin(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::ASin(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> ASin( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::ASin(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> ASin( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::ASin(x[0]), vtkm::ASin(x[1]), vtkm::ASin(x[2]), vtkm::ASin(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> ASin( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::ASin(x[0]), vtkm::ASin(x[1]), vtkm::ASin(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> ASin( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::ASin(x[0]), vtkm::ASin(x[1])); } /// Compute the arc cosine of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 ACos(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(acos)(x); #else return std::acos(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 ACos(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(acos)(x); #else return std::acos(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type ACos(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::ACos(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> ACos( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::ACos(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> ACos( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::ACos(x[0]), vtkm::ACos(x[1]), vtkm::ACos(x[2]), vtkm::ACos(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> ACos( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::ACos(x[0]), vtkm::ACos(x[1]), vtkm::ACos(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> ACos( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::ACos(x[0]), vtkm::ACos(x[1])); } /// Compute the arc tangent of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 ATan(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(atan)(x); #else return std::atan(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 ATan(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(atan)(x); #else return std::atan(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type ATan(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::ATan(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> ATan( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::ATan(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> ATan( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::ATan(x[0]), vtkm::ATan(x[1]), vtkm::ATan(x[2]), vtkm::ATan(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> ATan( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::ATan(x[0]), vtkm::ATan(x[1]), vtkm::ATan(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> ATan( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::ATan(x[0]), vtkm::ATan(x[1])); } /// Compute the arc tangent of \p x / \p y using the signs of both arguments /// to determine the quadrant of the return value. /// static inline VTKM_EXEC_CONT vtkm::Float32 ATan2(vtkm::Float32 x, vtkm::Float32 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(atan2)(x, y); #else return std::atan2(x, y); #endif } static inline VTKM_EXEC_CONT vtkm::Float64 ATan2(vtkm::Float64 x, vtkm::Float64 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(atan2)(x, y); #else return std::atan2(x, y); #endif } /// Compute the hyperbolic sine of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 SinH(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(sinh)(x); #else return std::sinh(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 SinH(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(sinh)(x); #else return std::sinh(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type SinH(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::SinH(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> SinH( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::SinH(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> SinH( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::SinH(x[0]), vtkm::SinH(x[1]), vtkm::SinH(x[2]), vtkm::SinH(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> SinH( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::SinH(x[0]), vtkm::SinH(x[1]), vtkm::SinH(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> SinH( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::SinH(x[0]), vtkm::SinH(x[1])); } /// Compute the hyperbolic cosine of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 CosH(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(cosh)(x); #else return std::cosh(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 CosH(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(cosh)(x); #else return std::cosh(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type CosH(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::CosH(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> CosH( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::CosH(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> CosH( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::CosH(x[0]), vtkm::CosH(x[1]), vtkm::CosH(x[2]), vtkm::CosH(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> CosH( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::CosH(x[0]), vtkm::CosH(x[1]), vtkm::CosH(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> CosH( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::CosH(x[0]), vtkm::CosH(x[1])); } /// Compute the hyperbolic tangent of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 TanH(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(tanh)(x); #else return std::tanh(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 TanH(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(tanh)(x); #else return std::tanh(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type TanH(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::TanH(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> TanH( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::TanH(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> TanH( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::TanH(x[0]), vtkm::TanH(x[1]), vtkm::TanH(x[2]), vtkm::TanH(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> TanH( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::TanH(x[0]), vtkm::TanH(x[1]), vtkm::TanH(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> TanH( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::TanH(x[0]), vtkm::TanH(x[1])); } /// Compute the hyperbolic arc sine of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 ASinH(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(asinh)(x); #else return std::asinh(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 ASinH(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(asinh)(x); #else return std::asinh(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type ASinH(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::ASinH(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> ASinH( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::ASinH(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> ASinH( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::ASinH(x[0]), vtkm::ASinH(x[1]), vtkm::ASinH(x[2]), vtkm::ASinH(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> ASinH( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::ASinH(x[0]), vtkm::ASinH(x[1]), vtkm::ASinH(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> ASinH( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::ASinH(x[0]), vtkm::ASinH(x[1])); } /// Compute the hyperbolic arc cosine of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 ACosH(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(acosh)(x); #else return std::acosh(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 ACosH(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(acosh)(x); #else return std::acosh(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type ACosH(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::ACosH(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> ACosH( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::ACosH(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> ACosH( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::ACosH(x[0]), vtkm::ACosH(x[1]), vtkm::ACosH(x[2]), vtkm::ACosH(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> ACosH( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::ACosH(x[0]), vtkm::ACosH(x[1]), vtkm::ACosH(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> ACosH( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::ACosH(x[0]), vtkm::ACosH(x[1])); } /// Compute the hyperbolic arc tangent of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 ATanH(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(atanh)(x); #else return std::atanh(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 ATanH(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(atanh)(x); #else return std::atanh(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type ATanH(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::ATanH(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> ATanH( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::ATanH(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> ATanH( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::ATanH(x[0]), vtkm::ATanH(x[1]), vtkm::ATanH(x[2]), vtkm::ATanH(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> ATanH( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::ATanH(x[0]), vtkm::ATanH(x[1]), vtkm::ATanH(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> ATanH( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::ATanH(x[0]), vtkm::ATanH(x[1])); } //----------------------------------------------------------------------------- /// Computes \p x raised to the power of \p y. /// static inline VTKM_EXEC_CONT vtkm::Float32 Pow(vtkm::Float32 x, vtkm::Float32 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(pow)(x, y); #else return std::pow(x, y); #endif } static inline VTKM_EXEC_CONT vtkm::Float64 Pow(vtkm::Float64 x, vtkm::Float64 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(pow)(x, y); #else return std::pow(x, y); #endif } /// Compute the square root of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 Sqrt(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(sqrt)(x); #else return std::sqrt(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Sqrt(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(sqrt)(x); #else return std::sqrt(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Sqrt(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Sqrt(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Sqrt( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Sqrt(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Sqrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Sqrt(x[0]), vtkm::Sqrt(x[1]), vtkm::Sqrt(x[2]), vtkm::Sqrt(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Sqrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Sqrt(x[0]), vtkm::Sqrt(x[1]), vtkm::Sqrt(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Sqrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Sqrt(x[0]), vtkm::Sqrt(x[1])); } /// Compute the reciprocal square root of \p x. The result of this function is /// equivalent to 1/Sqrt(x). However, on some devices it is faster to /// compute the reciprocal square root than the regular square root. Thus, you /// should use this function whenever dividing by the square root. /// #ifdef VTKM_CUDA static inline VTKM_EXEC_CONT vtkm::Float32 RSqrt(vtkm::Float32 x) { return rsqrtf(x); } static inline VTKM_EXEC_CONT vtkm::Float64 RSqrt(vtkm::Float64 x) { return rsqrt(x); } template static inline VTKM_EXEC_CONT vtkm::Float64 RSqrt(T x) { return rsqrt(static_cast(x)); } #else // !VTKM_CUDA static inline VTKM_EXEC_CONT vtkm::Float32 RSqrt(vtkm::Float32 x) { return 1 / vtkm::Sqrt(x); } static inline VTKM_EXEC_CONT vtkm::Float64 RSqrt(vtkm::Float64 x) { return 1 / vtkm::Sqrt(x); } template static inline VTKM_EXEC_CONT vtkm::Float64 RSqrt(T x) { return 1 / static_cast(x); } #endif // !VTKM_CUDA template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> RSqrt( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::RSqrt(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> RSqrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::RSqrt(x[0]), vtkm::RSqrt(x[1]), vtkm::RSqrt(x[2]), vtkm::RSqrt(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> RSqrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::RSqrt(x[0]), vtkm::RSqrt(x[1]), vtkm::RSqrt(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> RSqrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::RSqrt(x[0]), vtkm::RSqrt(x[1])); } /// Compute the cube root of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 Cbrt(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(cbrt)(x); #else return std::cbrt(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Cbrt(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(cbrt)(x); #else return std::cbrt(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Cbrt(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Cbrt(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Cbrt( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Cbrt(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Cbrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Cbrt(x[0]), vtkm::Cbrt(x[1]), vtkm::Cbrt(x[2]), vtkm::Cbrt(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Cbrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Cbrt(x[0]), vtkm::Cbrt(x[1]), vtkm::Cbrt(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Cbrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Cbrt(x[0]), vtkm::Cbrt(x[1])); } /// Compute the reciprocal cube root of \p x. The result of this function is /// equivalent to 1/Cbrt(x). However, on some devices it is faster to /// compute the reciprocal cube root than the regular cube root. Thus, you /// should use this function whenever dividing by the cube root. /// #ifdef VTKM_CUDA static inline VTKM_EXEC_CONT vtkm::Float32 RCbrt(vtkm::Float32 x) { return rcbrtf(x); } static inline VTKM_EXEC_CONT vtkm::Float64 RCbrt(vtkm::Float64 x) { return rcbrt(x); } template static inline VTKM_EXEC_CONT vtkm::Float64 RCbrt(T x) { return rcbrt(static_cast(x)); } #else // !VTKM_CUDA static inline VTKM_EXEC_CONT vtkm::Float32 RCbrt(vtkm::Float32 x) { return 1 / vtkm::Cbrt(x); } static inline VTKM_EXEC_CONT vtkm::Float64 RCbrt(vtkm::Float64 x) { return 1 / vtkm::Cbrt(x); } template static inline VTKM_EXEC_CONT vtkm::Float64 RCbrt(T x) { return 1 / vtkm::Cbrt(static_cast(x)); } #endif // !VTKM_CUDA template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> RCbrt( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::RCbrt(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> RCbrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::RCbrt(x[0]), vtkm::RCbrt(x[1]), vtkm::RCbrt(x[2]), vtkm::RCbrt(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> RCbrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::RCbrt(x[0]), vtkm::RCbrt(x[1]), vtkm::RCbrt(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> RCbrt( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::RCbrt(x[0]), vtkm::RCbrt(x[1])); } /// Computes e**\p x, the base-e exponential of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 Exp(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(exp)(x); #else return std::exp(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Exp(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(exp)(x); #else return std::exp(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Exp(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Exp(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Exp( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Exp(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Exp( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Exp(x[0]), vtkm::Exp(x[1]), vtkm::Exp(x[2]), vtkm::Exp(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Exp( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Exp(x[0]), vtkm::Exp(x[1]), vtkm::Exp(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Exp( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Exp(x[0]), vtkm::Exp(x[1])); } /// Computes 2**\p x, the base-2 exponential of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 Exp2(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(exp2)(x); #else return std::exp2(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Exp2(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(exp2)(x); #else return std::exp2(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Exp2(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Exp2(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Exp2( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Exp2(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Exp2( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Exp2(x[0]), vtkm::Exp2(x[1]), vtkm::Exp2(x[2]), vtkm::Exp2(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Exp2( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Exp2(x[0]), vtkm::Exp2(x[1]), vtkm::Exp2(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Exp2( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Exp2(x[0]), vtkm::Exp2(x[1])); } /// Computes (e**\p x) - 1, the of base-e exponental of \p x then minus 1. The /// accuracy of this function is good even for very small values of x. /// inline VTKM_EXEC_CONT vtkm::Float32 ExpM1(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(expm1)(x); #else return std::expm1(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 ExpM1(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(expm1)(x); #else return std::expm1(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type ExpM1(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::ExpM1(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> ExpM1( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::ExpM1(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> ExpM1( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::ExpM1(x[0]), vtkm::ExpM1(x[1]), vtkm::ExpM1(x[2]), vtkm::ExpM1(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> ExpM1( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::ExpM1(x[0]), vtkm::ExpM1(x[1]), vtkm::ExpM1(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> ExpM1( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::ExpM1(x[0]), vtkm::ExpM1(x[1])); } /// Computes 10**\p x, the base-10 exponential of \p x. /// #ifdef VTKM_CUDA static inline VTKM_EXEC_CONT vtkm::Float32 Exp10(vtkm::Float32 x) { return exp10f(x); } static inline VTKM_EXEC_CONT vtkm::Float64 Exp10(vtkm::Float64 x) { return exp10(x); } template static inline VTKM_EXEC_CONT vtkm::Float64 Exp10(T x) { return exp10(static_cast(x)); } #else // !VTKM_CUDA static inline VTKM_EXEC_CONT vtkm::Float32 Exp10(vtkm::Float32 x) { return vtkm::Pow(10, x); } static inline VTKM_EXEC_CONT vtkm::Float64 Exp10(vtkm::Float64 x) { return vtkm::Pow(10, x); } template static inline VTKM_EXEC_CONT vtkm::Float64 Exp10(T x) { return vtkm::Pow(10, static_cast(x)); } #endif // !VTKM_CUDA template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Exp10( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Exp10(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Exp10( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Exp10(x[0]), vtkm::Exp10(x[1]), vtkm::Exp10(x[2]), vtkm::Exp10(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Exp10( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Exp10(x[0]), vtkm::Exp10(x[1]), vtkm::Exp10(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Exp10( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Exp10(x[0]), vtkm::Exp10(x[1])); } /// Computes the natural logarithm of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 Log(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(log)(x); #else return std::log(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Log(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(log)(x); #else return std::log(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Log(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Log(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Log( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Log(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Log( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Log(x[0]), vtkm::Log(x[1]), vtkm::Log(x[2]), vtkm::Log(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Log( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Log(x[0]), vtkm::Log(x[1]), vtkm::Log(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Log( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Log(x[0]), vtkm::Log(x[1])); } /// Computes the logarithm base 2 of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 Log2(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(log2)(x); #else return std::log2(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Log2(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(log2)(x); #else return std::log2(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Log2(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Log2(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Log2( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Log2(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Log2( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Log2(x[0]), vtkm::Log2(x[1]), vtkm::Log2(x[2]), vtkm::Log2(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Log2( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Log2(x[0]), vtkm::Log2(x[1]), vtkm::Log2(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Log2( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Log2(x[0]), vtkm::Log2(x[1])); } /// Computes the logarithm base 10 of \p x. /// inline VTKM_EXEC_CONT vtkm::Float32 Log10(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(log10)(x); #else return std::log10(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Log10(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(log10)(x); #else return std::log10(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Log10(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Log10(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Log10( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Log10(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Log10( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Log10(x[0]), vtkm::Log10(x[1]), vtkm::Log10(x[2]), vtkm::Log10(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Log10( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Log10(x[0]), vtkm::Log10(x[1]), vtkm::Log10(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Log10( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Log10(x[0]), vtkm::Log10(x[1])); } /// Computes the value of log(1+x) accurately for very small values of x. /// inline VTKM_EXEC_CONT vtkm::Float32 Log1P(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(log1p)(x); #else return std::log1p(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Log1P(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(log1p)(x); #else return std::log1p(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Log1P(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Log1P(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Log1P( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Log1P(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Log1P( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Log1P(x[0]), vtkm::Log1P(x[1]), vtkm::Log1P(x[2]), vtkm::Log1P(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Log1P( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Log1P(x[0]), vtkm::Log1P(x[1]), vtkm::Log1P(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Log1P( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Log1P(x[0]), vtkm::Log1P(x[1])); } //----------------------------------------------------------------------------- /// Returns \p x or \p y, whichever is larger. /// template static inline VTKM_EXEC_CONT T Max(const T& x, const T& y); #ifdef VTKM_USE_STL static inline VTKM_EXEC_CONT vtkm::Float32 Max(vtkm::Float32 x, vtkm::Float32 y) { return (std::max)(x, y); } static inline VTKM_EXEC_CONT vtkm::Float64 Max(vtkm::Float64 x, vtkm::Float64 y) { return (std::max)(x, y); } #else // !VTKM_USE_STL static inline VTKM_EXEC_CONT vtkm::Float32 Max(vtkm::Float32 x, vtkm::Float32 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(fmax)(x, y); #else return std::fmax(x, y); #endif } static inline VTKM_EXEC_CONT vtkm::Float64 Max(vtkm::Float64 x, vtkm::Float64 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(fmax)(x, y); #else return std::fmax(x, y); #endif } #endif // !VTKM_USE_STL /// Returns \p x or \p y, whichever is smaller. /// template static inline VTKM_EXEC_CONT T Min(const T& x, const T& y); #if defined(VTKM_USE_STL) && !defined(VTKM_HIP) static inline VTKM_EXEC_CONT vtkm::Float32 Min(vtkm::Float32 x, vtkm::Float32 y) { return (std::min)(x, y); } static inline VTKM_EXEC_CONT vtkm::Float64 Min(vtkm::Float64 x, vtkm::Float64 y) { return (std::min)(x, y); } #else // !VTKM_USE_STL OR HIP static inline VTKM_EXEC_CONT vtkm::Float32 Min(vtkm::Float32 x, vtkm::Float32 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(fmin)(x, y); #else return std::fmin(x, y); #endif } static inline VTKM_EXEC_CONT vtkm::Float64 Min(vtkm::Float64 x, vtkm::Float64 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(fmin)(x, y); #else return std::fmin(x, y); #endif } #endif // !VTKM_USE_STL namespace detail { template static inline VTKM_EXEC_CONT T Max(T x, T y, vtkm::TypeTraitsScalarTag) { return (x < y) ? y : x; } template static inline VTKM_EXEC_CONT T Max(const T& x, const T& y, vtkm::TypeTraitsVectorTag) { using Traits = vtkm::VecTraits; T result; for (vtkm::IdComponent index = 0; index < Traits::NUM_COMPONENTS; index++) { Traits::SetComponent( result, index, vtkm::Max(Traits::GetComponent(x, index), Traits::GetComponent(y, index))); } return result; } template static inline VTKM_EXEC_CONT T Min(T x, T y, vtkm::TypeTraitsScalarTag) { return (x < y) ? x : y; } template static inline VTKM_EXEC_CONT T Min(const T& x, const T& y, vtkm::TypeTraitsVectorTag) { using Traits = vtkm::VecTraits; T result; for (vtkm::IdComponent index = 0; index < Traits::NUM_COMPONENTS; index++) { Traits::SetComponent( result, index, vtkm::Min(Traits::GetComponent(x, index), Traits::GetComponent(y, index))); } return result; } } // namespace detail /// Returns \p x or \p y, whichever is larger. /// template static inline VTKM_EXEC_CONT T Max(const T& x, const T& y) { return detail::Max(x, y, typename vtkm::TypeTraits::DimensionalityTag()); } /// Returns \p x or \p y, whichever is smaller. /// template static inline VTKM_EXEC_CONT T Min(const T& x, const T& y) { return detail::Min(x, y, typename vtkm::TypeTraits::DimensionalityTag()); } /// Clamp \p x to the given range. /// inline VTKM_EXEC_CONT vtkm::Float32 Clamp(vtkm::Float32 x, vtkm::Float32 lo, vtkm::Float32 hi) { return x > lo ? (x < hi ? x : hi) : lo; } inline VTKM_EXEC_CONT vtkm::Float64 Clamp(vtkm::Float64 x, vtkm::Float64 lo, vtkm::Float64 hi) { return x > lo ? (x < hi ? x : hi) : lo; } //----------------------------------------------------------------------------- //#ifdef VTKM_CUDA #define VTKM_USE_IEEE_NONFINITE //#endif #ifdef VTKM_USE_IEEE_NONFINITE namespace detail { union IEEE754Bits32 { vtkm::UInt32 bits; vtkm::Float32 scalar; }; #define VTKM_NAN_BITS_32 0x7FC00000U #define VTKM_INF_BITS_32 0x7F800000U #define VTKM_NEG_INF_BITS_32 0xFF800000U #define VTKM_EPSILON_32 1e-5f union IEEE754Bits64 { vtkm::UInt64 bits; vtkm::Float64 scalar; }; #define VTKM_NAN_BITS_64 0x7FF8000000000000ULL #define VTKM_INF_BITS_64 0x7FF0000000000000ULL #define VTKM_NEG_INF_BITS_64 0xFFF0000000000000ULL #define VTKM_EPSILON_64 1e-9 template struct FloatLimits; template <> struct FloatLimits { using BitsType = vtkm::detail::IEEE754Bits32; VTKM_EXEC_CONT static vtkm::Float32 Nan() { BitsType nan = { VTKM_NAN_BITS_32 }; return nan.scalar; } VTKM_EXEC_CONT static vtkm::Float32 Infinity() { BitsType inf = { VTKM_INF_BITS_32 }; return inf.scalar; } VTKM_EXEC_CONT static vtkm::Float32 NegativeInfinity() { BitsType neginf = { VTKM_NEG_INF_BITS_32 }; return neginf.scalar; } VTKM_EXEC_CONT static vtkm::Float32 Epsilon() { return VTKM_EPSILON_32; } }; template struct FloatLimits> { using BitsType = vtkm::detail::IEEE754Bits32; VTKM_EXEC_CONT static vtkm::Vec Nan() { BitsType nan = { VTKM_NAN_BITS_32 }; return vtkm::Vec(nan.scalar); } VTKM_EXEC_CONT static vtkm::Vec Infinity() { BitsType inf = { VTKM_INF_BITS_32 }; return vtkm::Vec(inf.scalar); } VTKM_EXEC_CONT static vtkm::Vec NegativeInfinity() { BitsType neginf = { VTKM_NEG_INF_BITS_32 }; return vtkm::Vec(neginf.scalar); } VTKM_EXEC_CONT static vtkm::Vec Epsilon() { return vtkm::Vec(VTKM_EPSILON_32); } }; template <> struct FloatLimits { using BitsType = vtkm::detail::IEEE754Bits64; VTKM_EXEC_CONT static vtkm::Float64 Nan() { BitsType nan = { VTKM_NAN_BITS_64 }; return nan.scalar; } VTKM_EXEC_CONT static vtkm::Float64 Infinity() { BitsType inf = { VTKM_INF_BITS_64 }; return inf.scalar; } VTKM_EXEC_CONT static vtkm::Float64 NegativeInfinity() { BitsType neginf = { VTKM_NEG_INF_BITS_64 }; return neginf.scalar; } VTKM_EXEC_CONT static vtkm::Float64 Epsilon() { return VTKM_EPSILON_64; } }; template struct FloatLimits> { using BitsType = vtkm::detail::IEEE754Bits64; VTKM_EXEC_CONT static vtkm::Vec Nan() { BitsType nan = { VTKM_NAN_BITS_64 }; return vtkm::Vec(nan.scalar); } VTKM_EXEC_CONT static vtkm::Vec Infinity() { BitsType inf = { VTKM_INF_BITS_64 }; return vtkm::Vec(inf.scalar); } VTKM_EXEC_CONT static vtkm::Vec NegativeInfinity() { BitsType neginf = { VTKM_NEG_INF_BITS_64 }; return vtkm::Vec(neginf.scalar); } VTKM_EXEC_CONT static vtkm::Vec Epsilon() { return vtkm::Vec(VTKM_EPSILON_64); } }; #undef VTKM_NAN_BITS_32 #undef VTKM_INF_BITS_32 #undef VTKM_NEG_INF_BITS_32 #undef VTKM_EPSILON_32 #undef VTKM_NAN_BITS_64 #undef VTKM_INF_BITS_64 #undef VTKM_NEG_INF_BITS_64 #undef VTKM_EPSILON_64 } // namespace detail /// Returns the representation for not-a-number (NaN). /// template static inline VTKM_EXEC_CONT T Nan() { return detail::FloatLimits::Nan(); } /// Returns the representation for infinity. /// template static inline VTKM_EXEC_CONT T Infinity() { return detail::FloatLimits::Infinity(); } /// Returns the representation for negative infinity. /// template static inline VTKM_EXEC_CONT T NegativeInfinity() { return detail::FloatLimits::NegativeInfinity(); } /// Returns the difference between 1 and the least value greater than 1 /// that is representable. /// template static inline VTKM_EXEC_CONT T Epsilon() { return detail::FloatLimits::Epsilon(); } #else // !VTKM_USE_IEEE_NONFINITE /// Returns the representation for not-a-number (NaN). /// template static inline VTKM_EXEC_CONT T Nan() { return std::numeric_limits::quiet_NaN(); } /// Returns the representation for infinity. /// template static inline VTKM_EXEC_CONT T Infinity() { return std::numeric_limits::infinity(); } /// Returns the representation for negative infinity. /// template static inline VTKM_EXEC_CONT T NegativeInfinity() { return -std::numeric_limits::infinity(); } /// Returns the difference between 1 and the least value greater than 1 /// that is representable. /// template static inline VTKM_EXEC_CONT T Epsilon() { return std::numeric_limits::epsilon(); } #endif // !VTKM_USE_IEEE_NONFINITE /// Returns the representation for not-a-number (NaN). /// static inline VTKM_EXEC_CONT vtkm::Float32 Nan32() { return vtkm::Nan(); } static inline VTKM_EXEC_CONT vtkm::Float64 Nan64() { return vtkm::Nan(); } /// Returns the representation for infinity. /// static inline VTKM_EXEC_CONT vtkm::Float32 Infinity32() { return vtkm::Infinity(); } static inline VTKM_EXEC_CONT vtkm::Float64 Infinity64() { return vtkm::Infinity(); } /// Returns the representation for negative infinity. /// static inline VTKM_EXEC_CONT vtkm::Float32 NegativeInfinity32() { return vtkm::NegativeInfinity(); } static inline VTKM_EXEC_CONT vtkm::Float64 NegativeInfinity64() { return vtkm::NegativeInfinity(); } /// Returns the difference between 1 and the least value greater than 1 /// that is representable. /// static inline VTKM_EXEC_CONT vtkm::Float32 Epsilon32() { return vtkm::Epsilon(); } static inline VTKM_EXEC_CONT vtkm::Float64 Epsilon64() { return vtkm::Epsilon(); } //----------------------------------------------------------------------------- /// Returns true if \p x is not a number. /// template static inline VTKM_EXEC_CONT bool IsNan(T x) { #ifndef VTKM_CUDA using std::isnan; #endif return (isnan(x) != 0); } /// Returns true if \p x is positive or negative infinity. /// template static inline VTKM_EXEC_CONT bool IsInf(T x) { #ifndef VTKM_CUDA using std::isinf; #endif return (isinf(x) != 0); } /// Returns true if \p x is a normal number (not NaN or infinite). /// template static inline VTKM_EXEC_CONT bool IsFinite(T x) { #ifndef VTKM_CUDA using std::isfinite; #endif return (isfinite(x) != 0); } //----------------------------------------------------------------------------- /// Round \p x to the smallest integer value not less than x. /// inline VTKM_EXEC_CONT vtkm::Float32 Ceil(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(ceil)(x); #else return std::ceil(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Ceil(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(ceil)(x); #else return std::ceil(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Ceil(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Ceil(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Ceil( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Ceil(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Ceil( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Ceil(x[0]), vtkm::Ceil(x[1]), vtkm::Ceil(x[2]), vtkm::Ceil(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Ceil( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Ceil(x[0]), vtkm::Ceil(x[1]), vtkm::Ceil(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Ceil( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Ceil(x[0]), vtkm::Ceil(x[1])); } /// Round \p x to the largest integer value not greater than x. /// inline VTKM_EXEC_CONT vtkm::Float32 Floor(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(floor)(x); #else return std::floor(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Floor(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(floor)(x); #else return std::floor(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Floor(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Floor(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Floor( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Floor(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Floor( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Floor(x[0]), vtkm::Floor(x[1]), vtkm::Floor(x[2]), vtkm::Floor(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Floor( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Floor(x[0]), vtkm::Floor(x[1]), vtkm::Floor(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Floor( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Floor(x[0]), vtkm::Floor(x[1])); } /// Round \p x to the nearest integral value. /// inline VTKM_EXEC_CONT vtkm::Float32 Round(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(round)(x); #else return std::round(x); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Round(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(round)(x); #else return std::round(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Round(const T& x) { using RT = typename detail::FloatingPointReturnType::Type; return vtkm::Round(static_cast(x)); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, N> Round( const vtkm::Vec& x) { vtkm::Vec::Type, N> result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Round(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 4> Round( const vtkm::Vec& x) { return vtkm::Vec::Type, 4>( vtkm::Round(x[0]), vtkm::Round(x[1]), vtkm::Round(x[2]), vtkm::Round(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 3> Round( const vtkm::Vec& x) { return vtkm::Vec::Type, 3>( vtkm::Round(x[0]), vtkm::Round(x[1]), vtkm::Round(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec::Type, 2> Round( const vtkm::Vec& x) { return vtkm::Vec::Type, 2>(vtkm::Round(x[0]), vtkm::Round(x[1])); } //----------------------------------------------------------------------------- /// Computes the remainder on division of 2 floating point numbers. The return /// value is \p numerator - n \p denominator, where n is the quotient of \p /// numerator divided by \p denominator rounded towards zero to an integer. For /// example, FMod(6.5, 2.3) returns 1.9, which is 6.5 - 2*2.3. /// static inline VTKM_EXEC_CONT vtkm::Float32 FMod(vtkm::Float32 x, vtkm::Float32 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(fmod)(x, y); #else return std::fmod(x, y); #endif } static inline VTKM_EXEC_CONT vtkm::Float64 FMod(vtkm::Float64 x, vtkm::Float64 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(fmod)(x, y); #else return std::fmod(x, y); #endif } /// Computes the remainder on division of 2 floating point numbers. The return /// value is \p numerator - n \p denominator, where n is the quotient of \p /// numerator divided by \p denominator rounded towards the nearest integer /// (instead of toward zero like FMod). For example, FMod(6.5, 2.3) /// returns -0.4, which is 6.5 - 3*2.3. /// #ifdef VTKM_MSVC template static inline VTKM_EXEC_CONT T Remainder(T numerator, T denominator) { T quotient = vtkm::Round(numerator / denominator); return numerator - quotient * denominator; } #else // !VTKM_MSVC static inline VTKM_EXEC_CONT vtkm::Float32 Remainder(vtkm::Float32 x, vtkm::Float32 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(remainder)(x, y); #else return std::remainder(x, y); #endif } static inline VTKM_EXEC_CONT vtkm::Float64 Remainder(vtkm::Float64 x, vtkm::Float64 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(remainder)(x, y); #else return std::remainder(x, y); #endif } #endif // !VTKM_MSVC /// Returns the remainder on division of 2 floating point numbers just like /// Remainder. In addition, this function also returns the \c quotient used to /// get that remainder. /// template static inline VTKM_EXEC_CONT vtkm::Float32 RemainderQuotient(vtkm::Float32 numerator, vtkm::Float32 denominator, QType& quotient) { int iQuotient; // See: https://github.com/ROCm-Developer-Tools/HIP/issues/2169 #if defined(VTKM_CUDA) || defined(VTKM_HIP) const vtkm::Float32 result = VTKM_CUDA_MATH_FUNCTION_32(remquo)(numerator, denominator, &iQuotient); #else const vtkm::Float32 result = std::remquo(numerator, denominator, &iQuotient); #endif quotient = static_cast(iQuotient); return result; } template static inline VTKM_EXEC_CONT vtkm::Float64 RemainderQuotient(vtkm::Float64 numerator, vtkm::Float64 denominator, QType& quotient) { int iQuotient; #ifdef VTKM_CUDA const vtkm::Float64 result = VTKM_CUDA_MATH_FUNCTION_64(remquo)(numerator, denominator, &iQuotient); #else const vtkm::Float64 result = std::remquo(numerator, denominator, &iQuotient); #endif quotient = static_cast(iQuotient); return result; } /// Gets the integral and fractional parts of \c x. The return value is the /// fractional part and \c integral is set to the integral part. /// static inline VTKM_EXEC_CONT vtkm::Float32 ModF(vtkm::Float32 x, vtkm::Float32& integral) { // See: https://github.com/ROCm-Developer-Tools/HIP/issues/2169 #if defined(VTKM_CUDA) || defined(VTKM_HIP) return VTKM_CUDA_MATH_FUNCTION_32(modf)(x, &integral); #else return std::modf(x, &integral); #endif } static inline VTKM_EXEC_CONT vtkm::Float64 ModF(vtkm::Float64 x, vtkm::Float64& integral) { #if defined(VTKM_CUDA) return VTKM_CUDA_MATH_FUNCTION_64(modf)(x, &integral); #else return std::modf(x, &integral); #endif } //----------------------------------------------------------------------------- /// Return the absolute value of \p x. That is, return \p x if it is positive or /// \p -x if it is negative. /// static inline VTKM_EXEC_CONT vtkm::Int32 Abs(vtkm::Int32 x) { return abs(x); } static inline VTKM_EXEC_CONT vtkm::Int64 Abs(vtkm::Int64 x) { #if VTKM_SIZE_LONG == 8 return labs(x); #elif VTKM_SIZE_LONG_LONG == 8 return llabs(x); #else #error Unknown size of Int64. #endif } static inline VTKM_EXEC_CONT vtkm::Float32 Abs(vtkm::Float32 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(fabs)(x); #else return std::fabs(x); #endif } static inline VTKM_EXEC_CONT vtkm::Float64 Abs(vtkm::Float64 x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(fabs)(x); #else return std::fabs(x); #endif } template static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType::Type Abs(T x) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(fabs)(static_cast(x)); #else return std::fabs(static_cast(x)); #endif } template static inline VTKM_EXEC_CONT vtkm::Vec Abs(const vtkm::Vec& x) { vtkm::Vec result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::Abs(x[index]); } return result; } template static inline VTKM_EXEC_CONT vtkm::Vec Abs(const vtkm::Vec& x) { return vtkm::Vec(vtkm::Abs(x[0]), vtkm::Abs(x[1]), vtkm::Abs(x[2]), vtkm::Abs(x[3])); } template static inline VTKM_EXEC_CONT vtkm::Vec Abs(const vtkm::Vec& x) { return vtkm::Vec(vtkm::Abs(x[0]), vtkm::Abs(x[1]), vtkm::Abs(x[2])); } template static inline VTKM_EXEC_CONT vtkm::Vec Abs(const vtkm::Vec& x) { return vtkm::Vec(vtkm::Abs(x[0]), vtkm::Abs(x[1])); } /// Returns a nonzero value if \p x is negative. /// static inline VTKM_EXEC_CONT vtkm::Int32 SignBit(vtkm::Float32 x) { #ifndef VTKM_CUDA using std::signbit; #endif return static_cast(signbit(x)); } static inline VTKM_EXEC_CONT vtkm::Int32 SignBit(vtkm::Float64 x) { #ifndef VTKM_CUDA using std::signbit; #endif return static_cast(signbit(x)); } /// Returns true if \p x is less than zero, false otherwise. /// static inline VTKM_EXEC_CONT bool IsNegative(vtkm::Float32 x) { return (vtkm::SignBit(x) != 0); } static inline VTKM_EXEC_CONT bool IsNegative(vtkm::Float64 x) { return (vtkm::SignBit(x) != 0); } /// Copies the sign of \p y onto \p x. If \p y is positive, returns Abs(\p x). /// If \p y is negative, returns -Abs(\p x). /// static inline VTKM_EXEC_CONT vtkm::Float32 CopySign(vtkm::Float32 x, vtkm::Float32 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(copysign)(x, y); #else return std::copysign(x, y); #endif } static inline VTKM_EXEC_CONT vtkm::Float64 CopySign(vtkm::Float64 x, vtkm::Float64 y) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(copysign)(x, y); #else return std::copysign(x, y); #endif } template static inline VTKM_EXEC_CONT vtkm::Vec CopySign(const vtkm::Vec& x, const vtkm::Vec& y) { vtkm::Vec result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::CopySign(x[index], y[index]); } return result; } /// Decompose floating poing value /// inline VTKM_EXEC_CONT vtkm::Float32 Frexp(vtkm::Float32 x, vtkm::Int32 *exponent) { // See: https://github.com/ROCm-Developer-Tools/HIP/issues/2169 #if defined(VTKM_CUDA) || defined(VTKM_HIP) return VTKM_CUDA_MATH_FUNCTION_32(frexp)(x, exponent); #else return std::frexp(x, exponent); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Frexp(vtkm::Float64 x, vtkm::Int32 *exponent) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(frexp)(x, exponent); #else return std::frexp(x, exponent); #endif } inline VTKM_EXEC_CONT vtkm::Float32 Ldexp(vtkm::Float32 x, vtkm::Int32 exponent) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_32(ldexp)(x, exponent); #else return std::ldexp(x, exponent); #endif } inline VTKM_EXEC_CONT vtkm::Float64 Ldexp(vtkm::Float64 x, vtkm::Int32 exponent) { #ifdef VTKM_CUDA return VTKM_CUDA_MATH_FUNCTION_64(ldexp)(x, exponent); #else return std::ldexp(x, exponent); #endif } // See: https://randomascii.wordpress.com/2012/01/23/stupid-float-tricks-2/ for why this works. inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float64 x, vtkm::Float64 y) { static_assert(sizeof(vtkm::Float64) == sizeof(vtkm::UInt64), "vtkm::Float64 is incorrect size."); static_assert(std::numeric_limits::has_denorm == std::denorm_present, "FloatDistance presumes the floating-point type has subnormal numbers."); if (!vtkm::IsFinite(x) || !vtkm::IsFinite(y)) { return 0xFFFFFFFFFFFFFFFFL; } // Signed zero is the sworn enemy of this process. if (y == 0) { y = vtkm::Abs(y); } if (x == 0) { x = vtkm::Abs(x); } if ( (x < 0 && y >= 0) || (x >= 0 && y < 0) ) { vtkm::UInt64 dx, dy; if (x < 0) { dy = FloatDistance(0.0, y); dx = FloatDistance(0.0, -x); } else { dy = FloatDistance(0.0, -y); dx = FloatDistance(0.0, x); } return dx + dy; } if (x < 0 && y < 0) { return FloatDistance(-x, -y); } // Note that: // int64_t xi = *reinterpret_cast(&x); // int64_t yi = *reinterpret_cast(&y); // also works, but generates warnings. // Good option to have if we get compile errors off memcpy or don't want to #include though. // At least on gcc, both versions generate the same assembly. vtkm::UInt64 xi; vtkm::UInt64 yi; memcpy(&xi, &x, sizeof(vtkm::UInt64)); memcpy(&yi, &y, sizeof(vtkm::UInt64)); if (yi > xi) { return yi - xi; } return xi - yi; } inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float32 x, vtkm::Float32 y) { static_assert(sizeof(vtkm::Float32) == sizeof(vtkm::Int32), "vtkm::Float32 is incorrect size."); static_assert(std::numeric_limits::has_denorm == std::denorm_present, "FloatDistance presumes the floating-point type has subnormal numbers."); if (!vtkm::IsFinite(x) || !vtkm::IsFinite(y)) { return 0xFFFFFFFFFFFFFFFFL; } if (y == 0) { y = vtkm::Abs(y); } if (x == 0) { x = vtkm::Abs(x); } if ( (x < 0 && y >= 0) || (x >= 0 && y < 0) ) { vtkm::UInt64 dx, dy; if (x < 0) { dy = FloatDistance(0.0f, y); dx = FloatDistance(0.0f, -x); } else { dy = FloatDistance(0.0f, -y); dx = FloatDistance(0.0f, x); } return dx + dy; } if (x < 0 && y < 0) { return FloatDistance(-x, -y); } vtkm::UInt32 xi_32; vtkm::UInt32 yi_32; memcpy(&xi_32, &x, sizeof(vtkm::UInt32)); memcpy(&yi_32, &y, sizeof(vtkm::UInt32)); vtkm::UInt64 xi = xi_32; vtkm::UInt64 yi = yi_32; if (yi > xi) { return yi - xi; } return xi - yi; } // Computes ab - cd. // See: https://pharr.org/matt/blog/2019/11/03/difference-of-floats.html template inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d) { T cd = c * d; T err = std::fma(-c, d, cd); T dop = std::fma(a, b, -cd); return dop + err; } // Solves ax² + bx + c = 0. // Only returns the real roots. // If there are real roots, the first element of the pair is <= the second. // If there are no real roots, both elements are NaNs. // The error should be at most 3 ulps. template inline VTKM_EXEC_CONT vtkm::Vec QuadraticRoots(T a, T b, T c) { if (a == 0) { if (b == 0) { if (c == 0) { // A degenerate case. All real numbers are roots; hopefully this arbitrary decision interacts gracefully with use. return vtkm::Vec(0,0); } else { return vtkm::Vec(vtkm::Nan(), vtkm::Nan()); } } return vtkm::Vec(-c/b, -c/b); } T delta = DifferenceOfProducts(b, b, 4*a, c); if (delta < 0) { return vtkm::Vec(vtkm::Nan(), vtkm::Nan()); } T q = -(b + vtkm::CopySign(vtkm::Sqrt(delta), b)) / 2; T r0 = q / a; T r1 = c / q; if (r0 < r1) { return vtkm::Vec(r0, r1); } return vtkm::Vec(r1, r0); } /// Bitwise operations /// /// Find the first set bit in @a word, and return its position (1-32). If no /// bits are set, returns 0. #ifdef VTKM_CUDA_DEVICE_PASS // Need to explicitly mark this as __device__ since __ffs is device only. inline __device__ vtkm::Int32 FindFirstSetBit(vtkm::UInt32 word) { // Output is [0,32], with ffs(0) == 0 return __ffs(static_cast(word)); } #else // CUDA_DEVICE_PASS inline VTKM_EXEC_CONT vtkm::Int32 FindFirstSetBit(vtkm::UInt32 word) { # if defined(VTKM_GCC) || defined(VTKM_CLANG) // Output is [0,32], with ffs(0) == 0 return __builtin_ffs(static_cast(word)); # elif defined(VTKM_MSVC) // Output is [0, 31], check return code to see if bits are set: vtkm::UInt32 firstSet; return _BitScanForward(reinterpret_cast(&firstSet), word) != 0 ? static_cast(firstSet + 1) : 0; # elif defined(VTKM_ICC) // Output is [0, 31], undefined if word is 0. return word != 0 ? _bit_scan_forward(word) + 1 : 0; # else // Naive implementation: if (word == 0) { return 0; } vtkm::Int32 bit = 1; while ((word & 0x1) == 0) { word >>= 1; ++bit; } return bit; # endif } #endif // CUDA_DEVICE_PASS /// Find the first set bit in @a word, and return its position (1-64). If no /// bits are set, returns 0. #ifdef VTKM_CUDA_DEVICE_PASS // Need to explicitly mark this as __device__ since __ffsll is device only. inline __device__ vtkm::Int32 FindFirstSetBit(vtkm::UInt64 word) { // Output is [0,64], with ffs(0) == 0 return __ffsll(static_cast(word)); } #else // CUDA_DEVICE_PASS inline VTKM_EXEC_CONT vtkm::Int32 FindFirstSetBit(vtkm::UInt64 word) { # if defined(VTKM_GCC) || defined(VTKM_CLANG) || defined(VTKM_ICC) // Output is [0,64], with ffs(0) == 0 return __builtin_ffsll(static_cast(word)); # elif defined(VTKM_MSVC) // Output is [0, 63], check return code to see if bits are set: vtkm::UInt32 firstSet; return _BitScanForward64(reinterpret_cast(&firstSet), word) != 0 ? static_cast(firstSet + 1) : 0; # else // Naive implementation: if (word == 0) { return 0; } vtkm::Int32 bit = 1; while ((word & 0x1) == 0) { word >>= 1; ++bit; } return bit; # endif } #endif // CUDA_DEVICE_PASS /// Count the total number of bits set in @a word. #ifdef VTKM_CUDA_DEVICE_PASS // Need to explicitly mark this as __device__ since __popc is device only. inline __device__ vtkm::Int32 CountSetBits(vtkm::UInt32 word) { return __popc(word); } #else // CUDA_DEVICE_PASS inline VTKM_EXEC_CONT vtkm::Int32 CountSetBits(vtkm::UInt32 word) { # if defined(VTKM_GCC) || defined(VTKM_CLANG) return __builtin_popcount(word); # elif defined(VTKM_MSVC) return static_cast(__popcnt(word)); # elif defined(VTKM_ICC) return _popcnt32(static_cast(word)); # else // Naive implementation: vtkm::Int32 bits = 0; while (word) { if (word & 0x1) { ++bits; } word >>= 1; } return bits; # endif } #endif // CUDA_DEVICE_PASS /// Count the total number of bits set in @a word. #ifdef VTKM_CUDA_DEVICE_PASS // Need to explicitly mark this as __device__ since __popcll is device only. inline __device__ vtkm::Int32 CountSetBits(vtkm::UInt64 word) { return __popcll(word); } #else // CUDA_DEVICE_PASS inline VTKM_EXEC_CONT vtkm::Int32 CountSetBits(vtkm::UInt64 word) { # if defined(VTKM_GCC) || defined(VTKM_CLANG) return __builtin_popcountll(word); # elif defined(VTKM_MSVC) return static_cast(__popcnt64(word)); # elif defined(VTKM_ICC) return _popcnt64(static_cast(word)); # else // Naive implementation: vtkm::Int32 bits = 0; while (word) { if (word & 0x1) { ++bits; } word >>= 1; } return bits; # endif } #endif // CUDA_DEVICE_PASS } // namespace vtkm // clang-format on #endif //vtk_m_Math_h