LCOV - code coverage report
Current view: top level - home/runner/.local/lib/python3.9/site-packages/torch/include/c10/util - overflows.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 0 16 0.0 %
Date: 2025-11-25 13:55:50 Functions: 0 45 0.0 %

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

Generated by: LCOV version 1.16