Line data Source code
1 : #if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) 2 : #pragma once 3 : 4 : #include <c10/macros/Macros.h> 5 : #include <c10/util/TypeSafeSignMath.h> 6 : #include <c10/util/complex.h> 7 : 8 : #include <cmath> 9 : #include <limits> 10 : #include <type_traits> 11 : 12 : namespace c10 { 13 : // In some versions of MSVC, there will be a compiler error when building. 14 : // C4146: unary minus operator applied to unsigned type, result still unsigned 15 : // C4804: unsafe use of type 'bool' in operation 16 : // It can be addressed by disabling the following warning. 17 : #ifdef _MSC_VER 18 : #pragma warning(push) 19 : #pragma warning(disable : 4146) 20 : #pragma warning(disable : 4804) 21 : #pragma warning(disable : 4018) 22 : #endif 23 : 24 : // The overflow checks may involve float to int conversion which may 25 : // trigger precision loss warning. Re-enable the warning once the code 26 : // is fixed. See T58053069. 27 : C10_CLANG_DIAGNOSTIC_PUSH() 28 : #if C10_CLANG_HAS_WARNING("-Wimplicit-float-conversion") 29 : C10_CLANG_DIAGNOSTIC_IGNORE("-Wimplicit-float-conversion") 30 : #endif 31 : 32 : // bool can be converted to any type. 33 : // Without specializing on bool, in pytorch_linux_trusty_py2_7_9_build: 34 : // `error: comparison of constant '255' with boolean expression is always false` 35 : // for `f > limit::max()` below 36 : template <typename To, typename From> 37 0 : std::enable_if_t<std::is_same_v<From, bool>, bool> overflows( 38 : From /*f*/, 39 : bool strict_unsigned [[maybe_unused]] = false) { 40 0 : return false; 41 : } 42 : 43 : // skip isnan and isinf check for integral types 44 : template <typename To, typename From> 45 : std::enable_if_t<std::is_integral_v<From> && !std::is_same_v<From, bool>, bool> 46 0 : overflows(From f, bool strict_unsigned = false) { 47 : using limit = std::numeric_limits<typename scalar_value_type<To>::type>; 48 : if constexpr (!limit::is_signed && std::numeric_limits<From>::is_signed) { 49 : // allow for negative numbers to wrap using two's complement arithmetic. 50 : // For example, with uint8, this allows for `a - b` to be treated as 51 : // `a + 255 * b`. 52 0 : if (!strict_unsigned) { 53 0 : return greater_than_max<To>(f) || 54 0 : (c10::is_negative(f) && 55 0 : -static_cast<uint64_t>(f) > static_cast<uint64_t>(limit::max())); 56 : } 57 : } 58 0 : return c10::less_than_lowest<To>(f) || greater_than_max<To>(f); 59 : } 60 : 61 : template <typename To, typename From> 62 0 : std::enable_if_t<std::is_floating_point_v<From>, bool> overflows( 63 : From f, 64 : bool strict_unsigned [[maybe_unused]] = false) { 65 : using limit = std::numeric_limits<typename scalar_value_type<To>::type>; 66 0 : if (limit::has_infinity && std::isinf(static_cast<double>(f))) { 67 : return false; 68 : } 69 0 : if (!limit::has_quiet_NaN && (f != f)) { 70 : return true; 71 : } 72 0 : return f < limit::lowest() || f > limit::max(); 73 : } 74 : 75 : C10_CLANG_DIAGNOSTIC_POP() 76 : 77 : #ifdef _MSC_VER 78 : #pragma warning(pop) 79 : #endif 80 : 81 : template <typename To, typename From> 82 0 : std::enable_if_t<is_complex<From>::value, bool> overflows( 83 : From f, 84 : bool strict_unsigned = false) { 85 : // casts from complex to real are considered to overflow if the 86 : // imaginary component is non-zero 87 0 : if (!is_complex<To>::value && f.imag() != 0) { 88 : return true; 89 : } 90 : // Check for overflow componentwise 91 : // (Technically, the imag overflow check is guaranteed to be false 92 : // when !is_complex<To>, but any optimizer worth its salt will be 93 : // able to figure it out.) 94 : return overflows< 95 : typename scalar_value_type<To>::type, 96 0 : typename From::value_type>(f.real(), strict_unsigned) || 97 : overflows< 98 : typename scalar_value_type<To>::type, 99 0 : typename From::value_type>(f.imag(), strict_unsigned); 100 : } 101 : } // namespace c10 102 : 103 : #else 104 : #error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." 105 : #endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)