//@HEADER // ************************************************************************ // // Kokkos v. 4.0 // Copyright (2022) National Technology & Engineering // Solutions of Sandia, LLC (NTESS). // // Under the terms of Contract DE-NA0003525 with NTESS, // the U.S. Government retains certain rights in this software. // // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. // See https://kokkos.org/LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //@HEADER #include #include #include #include #include "Kokkos_NumericTraits.hpp" // Suppress "'long double' is treated as 'double' in device code" #ifdef KOKKOS_COMPILER_NVCC #ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ #pragma nv_diagnostic push #pragma nv_diag_suppress 20208 #else #ifdef __CUDA_ARCH__ #pragma diagnostic push #pragma diag_suppress 20208 #endif #endif #endif struct extrema { #define DEFINE_EXTREMA(T, m, M) \ KOKKOS_FUNCTION static T min(T) { return m; } \ KOKKOS_FUNCTION static T max(T) { return M; } DEFINE_EXTREMA(char, CHAR_MIN, CHAR_MAX); DEFINE_EXTREMA(signed char, SCHAR_MIN, SCHAR_MAX); DEFINE_EXTREMA(unsigned char, 0, UCHAR_MAX); DEFINE_EXTREMA(short, SHRT_MIN, SHRT_MAX); DEFINE_EXTREMA(unsigned short, 0, USHRT_MAX); DEFINE_EXTREMA(int, INT_MIN, INT_MAX); DEFINE_EXTREMA(unsigned, 0U, UINT_MAX); DEFINE_EXTREMA(long, LONG_MIN, LONG_MAX); DEFINE_EXTREMA(unsigned long, 0UL, ULONG_MAX); DEFINE_EXTREMA(long long, LLONG_MIN, LLONG_MAX); DEFINE_EXTREMA(unsigned long long, 0ULL, ULLONG_MAX); DEFINE_EXTREMA(float, -FLT_MAX, FLT_MAX); DEFINE_EXTREMA(double, -DBL_MAX, DBL_MAX); #if !defined(KOKKOS_ENABLE_CUDA) || \ !defined(KOKKOS_COMPILER_NVHPC) // 23.7 long double DEFINE_EXTREMA(long double, -LDBL_MAX, LDBL_MAX); #else static long double min(long double) { return -LDBL_MAX; } static long double max(long double) { return LDBL_MAX; } #endif #undef DEFINE_EXTREMA }; // clang-format off struct Infinity { template using trait = Kokkos::Experimental::infinity; }; struct Epsilon { template using trait = Kokkos::Experimental::epsilon; }; struct FiniteMin { template using trait = Kokkos::Experimental::finite_min; }; struct FiniteMax { template using trait = Kokkos::Experimental::finite_max; }; struct RoundError { template using trait = Kokkos::Experimental::round_error; }; struct NormMin { template using trait = Kokkos::Experimental::norm_min; }; struct DenormMin { template using trait = Kokkos::Experimental::denorm_min; }; struct Digits { template using trait = Kokkos::Experimental::digits; }; struct Digits10 { template using trait = Kokkos::Experimental::digits10; }; struct MaxDigits10 { template using trait = Kokkos::Experimental::max_digits10; }; struct Radix { template using trait = Kokkos::Experimental::radix; }; struct MinExponent { template using trait = Kokkos::Experimental::min_exponent; }; struct MaxExponent { template using trait = Kokkos::Experimental::max_exponent; }; struct MinExponent10 { template using trait = Kokkos::Experimental::min_exponent10; }; struct MaxExponent10 { template using trait = Kokkos::Experimental::max_exponent10; }; struct QuietNaN { template using trait = Kokkos::Experimental::quiet_NaN; }; struct SignalingNaN { template using trait = Kokkos::Experimental::signaling_NaN; }; // clang-format on template KOKKOS_FUNCTION T* take_address_of(T& arg) { return &arg; } template KOKKOS_FUNCTION void take_by_value(T) {} template struct TestNumericTraits { template using trait = typename Tag::template trait; Kokkos::View compare; TestNumericTraits() { compare = Kokkos::View("C"); run(); } void run() const { int errors = 0; Kokkos::parallel_reduce(Kokkos::RangePolicy(0, 1), *this, errors); ASSERT_EQ(errors, 0); (void)take_address_of(trait::value); // use on host } KOKKOS_FUNCTION void operator()(Infinity, int, int& e) const { using Kokkos::Experimental::infinity; constexpr auto inf = infinity::value; auto const zero = T(0); e += (int)!(inf + inf == inf); e += (int)!(inf != zero); use_on_device(); } KOKKOS_FUNCTION void operator()(Epsilon, int, int& e) const { using Kokkos::Experimental::epsilon; T const eps = epsilon::value; T const one = 1; // Avoid higher precision intermediate representation compare() = one + eps; e += (int)!(compare() != one); compare() = one + eps / 2; e += (int)!(compare() == one); use_on_device(); } KOKKOS_FUNCTION void operator()(FiniteMin, int, int& e) const { using Kokkos::Experimental::finite_max; using Kokkos::Experimental::finite_min; auto const min = finite_min::value; auto const max = finite_max::value; e += (int)!(min == extrema::min(T{})); e += (int)!(max == extrema::max(T{})); use_on_device(); } // clang-format off KOKKOS_FUNCTION void operator()(FiniteMax, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(RoundError, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(NormMin, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(DenormMin, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(Digits, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(Digits10, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(MaxDigits10, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(Radix, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(MinExponent, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(MaxExponent, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(MinExponent10, int, int&) const { use_on_device(); } KOKKOS_FUNCTION void operator()(MaxExponent10, int, int&) const { use_on_device(); } // clang-format on KOKKOS_FUNCTION void operator()(QuietNaN, int, int& e) const { #ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC 23.7 nan using Kokkos::Experimental::quiet_NaN; constexpr auto nan = quiet_NaN::value; auto const zero = T(0); e += (int)!(nan != nan); e += (int)!(nan != zero); #else (void)e; #endif use_on_device(); } KOKKOS_FUNCTION void operator()(SignalingNaN, int, int& e) const { #ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC 23.7 nan using Kokkos::Experimental::signaling_NaN; constexpr auto nan = signaling_NaN::value; auto const zero = T(0); e += (int)!(nan != nan); e += (int)!(nan != zero); #else (void)e; #endif use_on_device(); } KOKKOS_FUNCTION void use_on_device() const { #if defined(KOKKOS_COMPILER_NVCC) || defined(KOKKOS_COMPILER_NVHPC) || \ defined(KOKKOS_ENABLE_OPENMPTARGET) || defined(KOKKOS_ENABLE_OPENACC) take_by_value(trait::value); #else (void)take_address_of(trait::value); #endif } }; #if (defined(KOKKOS_COMPILER_NVCC) && defined(KOKKOS_ENABLE_CUDA)) || \ defined(KOKKOS_ENABLE_SYCL) || defined(KOKKOS_ENABLE_OPENMPTARGET) template struct TestNumericTraits< #if defined(KOKKOS_ENABLE_CUDA) Kokkos::Cuda, #elif defined(KOKKOS_ENABLE_SYCL) Kokkos::Experimental::SYCL, #else Kokkos::Experimental::OpenMPTarget, #endif long double, Tag> { template using trait = typename Tag::template trait; TestNumericTraits() { (void)take_address_of(trait::value); // Do nothing on the device. // According to the doc // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#constexpr-variables // the traits member constant value cannot be directly used in device code. } }; #endif TEST(TEST_CATEGORY, numeric_traits_infinity) { #ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC 23.7 TestNumericTraits(); TestNumericTraits(); #endif TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double // FIXME_OPENMPTARGET long double on Intel GPUs #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_epsilon) { #ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC 23.7 bit_comparison_type TestNumericTraits(); TestNumericTraits(); #endif TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_round_error) { #ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC 23.7 bit_comparison_type TestNumericTraits(); TestNumericTraits(); #endif TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_norm_min) { #ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC 23.7 bit_comparison_type TestNumericTraits(); TestNumericTraits(); #endif TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_denorm_min) { TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_finite_min_max) { TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double // FIXME_OPENMPTARGET long double on Intel GPUs #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_digits) { TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double // FIXME_OPENMPTARGET long double on Intel GPUs #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_digits10) { TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double // FIXME_OPENMPTARGET long double on Intel GPUs #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_max_digits10) { TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double // FIXME_OPENMPTARGET long double on Intel GPUs #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_radix) { TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double // FIXME_OPENMPTARGET long double on Intel GPUs #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_min_max_exponent) { TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double // FIXME_OPENMPTARGET long double on Intel GPUs #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_min_max_exponent10) { TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double // FIXME_OPENMPTARGET long double on Intel GPUs #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); TestNumericTraits(); #endif } TEST(TEST_CATEGORY, numeric_traits_quiet_and_signaling_nan) { #ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC 23.7 TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); #endif TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); TestNumericTraits(); // FIXME_NVHPC 23.7 long double // FIXME_OPENMPTARGET long double on Intel GPUs #if (!defined(KOKKOS_ENABLE_CUDA) || !defined(KOKKOS_COMPILER_NVHPC)) && \ (!defined(KOKKOS_ENABLE_OPENMPTARGET) || !defined(KOKKOS_ARCH_INTEL_GPU)) TestNumericTraits(); TestNumericTraits(); #endif } namespace NumericTraitsSFINAE { struct HasNoSpecialization {}; #define CHECK_TRAIT_IS_SFINAE_FRIENDLY(TRAIT) \ template \ using TRAIT##_value_t = decltype(Kokkos::Experimental::TRAIT::value); \ template \ using has_##TRAIT = Kokkos::is_detected; \ static_assert(!has_##TRAIT::value); CHECK_TRAIT_IS_SFINAE_FRIENDLY(infinity) CHECK_TRAIT_IS_SFINAE_FRIENDLY(finite_min) CHECK_TRAIT_IS_SFINAE_FRIENDLY(finite_max) CHECK_TRAIT_IS_SFINAE_FRIENDLY(epsilon) CHECK_TRAIT_IS_SFINAE_FRIENDLY(round_error) CHECK_TRAIT_IS_SFINAE_FRIENDLY(norm_min) CHECK_TRAIT_IS_SFINAE_FRIENDLY(denorm_min) CHECK_TRAIT_IS_SFINAE_FRIENDLY(quiet_NaN) CHECK_TRAIT_IS_SFINAE_FRIENDLY(signaling_NaN) CHECK_TRAIT_IS_SFINAE_FRIENDLY(digits) CHECK_TRAIT_IS_SFINAE_FRIENDLY(digits10) CHECK_TRAIT_IS_SFINAE_FRIENDLY(max_digits10) CHECK_TRAIT_IS_SFINAE_FRIENDLY(radix) CHECK_TRAIT_IS_SFINAE_FRIENDLY(min_exponent) CHECK_TRAIT_IS_SFINAE_FRIENDLY(min_exponent10) CHECK_TRAIT_IS_SFINAE_FRIENDLY(max_exponent) CHECK_TRAIT_IS_SFINAE_FRIENDLY(max_exponent10) } // namespace NumericTraitsSFINAE // Example detecting presence or absence of values template using infinity_value_t = decltype(Kokkos::Experimental::infinity::value); template using has_infinity = Kokkos::is_detected; template ::value>* = nullptr> constexpr T legacy_std_numeric_limits_infinity() { return Kokkos::Experimental::infinity::value; } template ::value>* = nullptr> constexpr T legacy_std_numeric_limits_infinity() { return T(); } TEST(TEST_CATEGORY, numeric_traits_sfinae_friendly) { ASSERT_EQ(legacy_std_numeric_limits_infinity(), 0); } // Compare to std::numeric_limits template struct AssertIntEquality { static constexpr bool value = false; }; template struct AssertIntEquality { static constexpr bool value = true; }; #define CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(T, TRAIT) \ static_assert(AssertIntEquality::value, \ std::numeric_limits::TRAIT>::value, \ "") #define CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(T, TRAIT) \ static_assert(Kokkos::Experimental::TRAIT::value == \ std::numeric_limits::TRAIT(), \ "") CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(float, infinity); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(double, infinity); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, infinity); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(float, epsilon); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(double, epsilon); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, epsilon); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(float, round_error); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(double, round_error); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, round_error); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(float, denorm_min); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(double, denorm_min); // FIXME_OPENMPTARGET - The static_assert causes issues on Intel GPUs with the // OpenMPTarget backend. #if !(defined(KOKKOS_ENABLE_OPENMPTARGET) && \ defined(KOKKOS_COMPILER_INTEL_LLVM)) CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, denorm_min); #endif // clang-format off static_assert(Kokkos::Experimental::norm_min::value == std::numeric_limits< float>::min()); static_assert(Kokkos::Experimental::norm_min::value == std::numeric_limits< double>::min()); static_assert(Kokkos::Experimental::norm_min::value == std::numeric_limits::min()); // integer types static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits< char>::min()); static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits< signed char>::min()); static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits< unsigned char>::min()); static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits< short>::min()); static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits< unsigned short>::min()); static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits< int>::min()); static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits< unsigned int>::min()); static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits< long int>::min()); static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits< unsigned long int>::min()); static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits< long long int>::min()); static_assert(Kokkos::Experimental::finite_min::value == std::numeric_limits::min()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< char>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< signed char>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< unsigned char>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< short>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< unsigned short>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< int>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< unsigned int>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< long int>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< unsigned long int>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< long long int>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits::max()); // floating point types static_assert(Kokkos::Experimental::finite_min::value == -std::numeric_limits< float>::max()); static_assert(Kokkos::Experimental::finite_min::value == -std::numeric_limits< double>::max()); static_assert(Kokkos::Experimental::finite_min::value == -std::numeric_limits::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< float>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits< double>::max()); static_assert(Kokkos::Experimental::finite_max::value == std::numeric_limits::max()); // clang-format on CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(bool, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(char, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(signed char, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned char, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(short, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned short, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(int, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned int, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long int, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned long int, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long long int, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned long long int, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(float, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(double, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long double, digits); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(bool, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(char, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(signed char, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned char, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(short, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned short, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(int, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned int, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long int, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned long int, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long long int, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned long long int, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(float, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(double, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long double, digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(float, max_digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(double, max_digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long double, max_digits10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(bool, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(char, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(signed char, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned char, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(short, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned short, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(int, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned int, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long int, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned long int, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long long int, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(unsigned long long int, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(float, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(double, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long double, radix); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(float, min_exponent); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(float, max_exponent); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(double, min_exponent); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(double, max_exponent); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long double, min_exponent); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long double, max_exponent); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(float, min_exponent10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(float, max_exponent10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(double, min_exponent10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(double, max_exponent10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long double, min_exponent10); CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long double, max_exponent10); #undef CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION #undef CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT #define CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(T, TRAIT) \ static_assert(Kokkos::Experimental::TRAIT::value != \ Kokkos::Experimental::TRAIT::value); \ static_assert(std::numeric_limits::TRAIT() != \ std::numeric_limits::TRAIT()); \ static_assert(Kokkos::Experimental::TRAIT::value != \ std::numeric_limits::TRAIT()) // Workaround compiler issue error: expression must have a constant value // See kokkos/kokkos#4574 // There is the same bug with CUDA 11.6 // FIXME_NVHPC FIXME_CUDA FIXME_NVCC #if !defined(KOKKOS_COMPILER_NVHPC) && (CUDA_VERSION < 11060) && \ !(defined(KOKKOS_COMPILER_NVCC) && !defined(KOKKOS_ENABLE_CUDA)) CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(float, quiet_NaN); CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(double, quiet_NaN); CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, quiet_NaN); CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(float, signaling_NaN); CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(double, signaling_NaN); CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, signaling_NaN); #endif #undef CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION #define CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(T, TRAIT) \ static_assert(Kokkos::Experimental::TRAIT::value == \ Kokkos::Experimental::TRAIT::value); \ static_assert(Kokkos::Experimental::TRAIT::value == \ Kokkos::Experimental::TRAIT::value); \ static_assert(Kokkos::Experimental::TRAIT::value == \ Kokkos::Experimental::TRAIT::value) #define CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(TRAIT) \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(float, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(double, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(long double, TRAIT) #define CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(TRAIT) \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(bool, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(char, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(signed char, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(unsigned char, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(short, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(unsigned short, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(int, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(unsigned int, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(long int, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(unsigned long int, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(long long int, TRAIT); \ CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(unsigned long long int, TRAIT) CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(infinity); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(finite_min); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(finite_min); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(finite_max); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(finite_max); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(epsilon); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(round_error); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(norm_min); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(digits); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(digits); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(digits10); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(digits10); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(max_digits10); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(radix); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(radix); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(min_exponent); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(min_exponent10); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(max_exponent); CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(max_exponent10); #undef CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL #undef CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT #undef CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES #define CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES(T, TRAIT) \ static_assert(Kokkos::Experimental::TRAIT::value != \ Kokkos::Experimental::TRAIT::value); \ static_assert(Kokkos::Experimental::TRAIT::value != \ Kokkos::Experimental::TRAIT::value); \ static_assert(Kokkos::Experimental::TRAIT::value != \ Kokkos::Experimental::TRAIT::value); \ static_assert(Kokkos::Experimental::TRAIT::value != \ Kokkos::Experimental::TRAIT::value) #define CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(TRAIT) \ CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES(float, TRAIT); \ CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES(double, TRAIT); \ CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES(long double, TRAIT) CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(quiet_NaN); CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(signaling_NaN); #undef CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT #undef CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES #ifdef KOKKOS_COMPILER_NVCC #ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ #pragma nv_diagnostic pop #else #ifdef __CUDA_ARCH__ #pragma diagnostic pop #endif #endif #endif