LCOV - code coverage report
Current view: top level - home/runner/.local/lib/python3.10/site-packages/torch/include/c10/util - Exception.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 0 7 0.0 %
Date: 2026-06-05 17:04:24 Functions: 0 10 0.0 %

          Line data    Source code
       1             : #if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
       2             : // @allow-raw-throw
       3             : #ifndef C10_UTIL_EXCEPTION_H_
       4             : #define C10_UTIL_EXCEPTION_H_
       5             : 
       6             : #include <c10/macros/Export.h>
       7             : #include <c10/macros/Macros.h>
       8             : #include <c10/util/Backtrace.h>
       9             : #include <c10/util/Lazy.h>
      10             : #include <c10/util/StringUtil.h>
      11             : 
      12             : #include <cstdint>
      13             : #include <exception>
      14             : #include <memory>
      15             : #include <string>
      16             : #include <variant>
      17             : #include <vector>
      18             : 
      19             : #if defined(_MSC_VER) && _MSC_VER <= 1900
      20             : #define __func__ __FUNCTION__
      21             : #endif
      22             : 
      23             : namespace c10 {
      24             : 
      25             : /// The primary ATen error class.
      26             : /// Provides a complete error message with source location information via
      27             : /// `what()`, and a more concise message via `what_without_backtrace()`.
      28             : /// Don't throw this directly; use TORCH_CHECK/TORCH_INTERNAL_ASSERT instead.
      29             : ///
      30             : /// NB: c10::Error is handled specially by the default torch to suppress the
      31             : /// backtrace, see torch/csrc/Exceptions.h
      32             : class C10_API Error : public std::exception {
      33             :  private:
      34             :   // The actual error message.
      35             :   std::string msg_;
      36             : 
      37             :   // Context for the message (in order of decreasing specificity).  Context will
      38             :   // be automatically formatted appropriately, so it is not necessary to add
      39             :   // extra leading/trailing newlines to strings inside this vector
      40             :   std::vector<std::string> context_;
      41             : 
      42             :   // The C++ backtrace at the point when this exception was raised.  This
      43             :   // may be empty if there is no valid backtrace.  (We don't use optional
      44             :   // here to reduce the dependencies this file has.)
      45             :   Backtrace backtrace_;
      46             : 
      47             :   // These two are derived fields from msg_stack_ and backtrace_, but we need
      48             :   // fields for the strings so that we can return a const char* (as the
      49             :   // signature of std::exception requires).  Currently, the invariant
      50             :   // is that these fields are ALWAYS populated consistently with respect
      51             :   // to msg_stack_ and backtrace_.
      52             :   mutable OptimisticLazy<std::string> what_;
      53             :   std::string what_without_backtrace_;
      54             : 
      55             :   // This is a little debugging trick: you can stash a relevant pointer
      56             :   // in caller, and then when you catch the exception, you can compare
      57             :   // against pointers you have on hand to get more information about
      58             :   // where the exception came from.  In Caffe2, this is used to figure
      59             :   // out which operator raised an exception.
      60             :   const void* caller_;
      61             : 
      62             :  public:
      63             :   // PyTorch-style Error constructor.  NB: the implementation of this
      64             :   // is actually in Logging.cpp
      65             :   Error(SourceLocation source_location, std::string msg);
      66             : 
      67             :   // Caffe2-style error message
      68             :   Error(
      69             :       const char* file,
      70             :       const uint32_t line,
      71             :       const char* condition,
      72             :       const std::string& msg,
      73             :       Backtrace backtrace,
      74             :       const void* caller = nullptr);
      75             : 
      76             :   // Base constructor
      77             :   Error(
      78             :       std::string msg,
      79             :       Backtrace backtrace = nullptr,
      80             :       const void* caller = nullptr);
      81             : 
      82             :   // Add some new context to the message stack.  The last added context
      83             :   // will be formatted at the end of the context list upon printing.
      84             :   // WARNING: This method is O(n) in the size of the stack, so don't go
      85             :   // wild adding a ridiculous amount of context to error messages.
      86             :   void add_context(std::string msg);
      87             : 
      88             :   const std::string& msg() const {
      89             :     return msg_;
      90             :   }
      91             : 
      92             :   const std::vector<std::string>& context() const {
      93             :     return context_;
      94             :   }
      95             : 
      96             :   const Backtrace& backtrace() const;
      97             : 
      98             :   /// Returns the complete error message, including the source location.
      99             :   /// The returned pointer is invalidated if you call add_context() on
     100             :   /// this object.
     101             :   const char* what() const noexcept override;
     102             : 
     103             :   const void* caller() const noexcept {
     104             :     return caller_;
     105             :   }
     106             : 
     107             :   /// Returns only the error message string, without source location.
     108             :   /// The returned pointer is invalidated if you call add_context() on
     109             :   /// this object.
     110           0 :   virtual const char* what_without_backtrace() const noexcept {
     111           0 :     return what_without_backtrace_.c_str();
     112             :   }
     113             : 
     114             :  private:
     115             :   void refresh_what();
     116             :   std::string compute_what(bool include_backtrace) const;
     117             : };
     118             : 
     119             : class C10_API Warning {
     120             :  public:
     121             :   class C10_API UserWarning{};
     122             :   class C10_API DeprecationWarning{};
     123             : 
     124             :   using warning_variant_t = std::variant<UserWarning, DeprecationWarning>;
     125             : 
     126             :   Warning(
     127             :       warning_variant_t type,
     128             :       const SourceLocation& source_location,
     129             :       std::string msg,
     130             :       bool verbatim);
     131             : 
     132             :   Warning(
     133             :       warning_variant_t type,
     134             :       SourceLocation source_location,
     135             :       const char* msg,
     136             :       bool verbatim);
     137             : 
     138             :   Warning(
     139             :       warning_variant_t type,
     140             :       SourceLocation source_location,
     141             :       ::c10::detail::CompileTimeEmptyString msg,
     142             :       bool verbatim);
     143             : 
     144             :   // Getters for members
     145             :   warning_variant_t type() const;
     146             :   const SourceLocation& source_location() const;
     147             :   const std::string& msg() const;
     148             :   bool verbatim() const;
     149             : 
     150             :  private:
     151             :   // The type of warning
     152             :   warning_variant_t type_;
     153             : 
     154             :   // Where the warning happened.
     155             :   SourceLocation source_location_;
     156             : 
     157             :   // The actual warning message.
     158             :   std::string msg_;
     159             : 
     160             :   // See note: [Verbatim Warnings]
     161             :   bool verbatim_;
     162             : };
     163             : 
     164             : using UserWarning = Warning::UserWarning;
     165             : using DeprecationWarning = Warning::DeprecationWarning;
     166             : 
     167             : // Issue a warning with a given message. Dispatched to the current
     168             : // warning handler.
     169             : void C10_API warn(const Warning& warning);
     170             : 
     171             : class C10_API WarningHandler {
     172             :  public:
     173             :   virtual ~WarningHandler() = default;
     174             :   /// The default warning handler. Prints the message to stderr.
     175             :   virtual void process(const Warning& warning);
     176             : };
     177             : 
     178             : namespace WarningUtils {
     179             : 
     180             : // Note: [Verbatim Warnings]
     181             : // Warnings originating in C++ code can appear out-of-place to Python users:
     182             : // a user runs a line in Python, but the warning references a line in C++.
     183             : // Some parts of PyTorch, like the JIT, are cognizant of this mismatch
     184             : // and take care to map warnings back to the user's program, but most
     185             : // of PyTorch simply throws a context-free warning. To allow warning
     186             : // handlers to add context where appropriate, warn takes the
     187             : // "verbatim" flag. When this is false a warning handler might append
     188             : // the C++ warning to a Python warning message that relates the warning
     189             : // back to the user's program. Callers who have already accounted for
     190             : // context in their warnings should set verbatim to true so their warnings
     191             : // appear without modification.
     192             : 
     193             : /// Sets the global warning handler. This is not thread-safe, so it should
     194             : /// generally be called once during initialization or while holding the GIL
     195             : /// for programs that use python.
     196             : /// User is responsible for keeping the WarningHandler alive until
     197             : /// it is not needed.
     198             : C10_API void set_warning_handler(WarningHandler* handler) noexcept(true);
     199             : /// Gets the global warning handler.
     200             : C10_API WarningHandler* get_warning_handler() noexcept(true);
     201             : 
     202             : class C10_API WarningHandlerGuard {
     203             :   WarningHandler* prev_handler_;
     204             : 
     205             :  public:
     206             :   WarningHandlerGuard(WarningHandler* new_handler)
     207             :       : prev_handler_(c10::WarningUtils::get_warning_handler()) {
     208             :     c10::WarningUtils::set_warning_handler(new_handler);
     209             :   }
     210             :   WarningHandlerGuard(WarningHandlerGuard&& other) = delete;
     211             :   WarningHandlerGuard(const WarningHandlerGuard&) = delete;
     212             :   WarningHandlerGuard& operator=(const WarningHandlerGuard&) = delete;
     213             :   WarningHandlerGuard& operator=(WarningHandlerGuard&&) = delete;
     214             :   ~WarningHandlerGuard() {
     215             :     c10::WarningUtils::set_warning_handler(prev_handler_);
     216             :   }
     217             : };
     218             : 
     219             : /// The TORCH_WARN_ONCE macro is difficult to test for. Use
     220             : /// setWarnAlways(true) to turn it into TORCH_WARN, which can be
     221             : /// tested for more easily.
     222             : C10_API void set_warnAlways(bool /*setting*/) noexcept(true);
     223             : C10_API bool get_warnAlways() noexcept(true);
     224             : 
     225             : // A RAII guard that sets warn_always (not thread-local) on
     226             : // construction, and sets it back to the original value upon destruction.
     227             : struct C10_API WarnAlways {
     228             :  public:
     229             :   explicit WarnAlways(bool setting = true);
     230             :   ~WarnAlways();
     231             : 
     232             :  private:
     233             :   bool prev_setting;
     234             : };
     235             : 
     236             : } // namespace WarningUtils
     237             : 
     238             : // Like Error, but we always report the C++ backtrace, instead of only
     239             : // reporting when TORCH_SHOW_CPP_STACKTRACES
     240             : class C10_API ErrorAlwaysShowCppStacktrace : public Error {
     241             :   using Error::Error;
     242             :   const char* what_without_backtrace() const noexcept override {
     243             :     return what();
     244             :   }
     245             : };
     246             : 
     247             : // Used in ATen for out-of-bound indices that can reasonably only be detected
     248             : // lazily inside a kernel (See: advanced indexing).  These turn into
     249             : // IndexError when they cross to Python.
     250             : class C10_API IndexError : public Error {
     251             :   using Error::Error;
     252             : };
     253             : 
     254             : // Used in ATen for invalid values.  These turn into
     255             : // ValueError when they cross to Python.
     256             : class C10_API ValueError : public Error {
     257           0 :   using Error::Error;
     258             : };
     259             : 
     260             : // Used in ATen for invalid types.  These turn into
     261             : // TypeError when they cross to Python.
     262             : class C10_API TypeError : public Error {
     263             :   using Error::Error;
     264             : };
     265             : 
     266             : // Used in ATen for functionality that is not implemented.  These turn into
     267             : // NotImplementedError when they cross to Python.
     268             : class C10_API NotImplementedError : public Error {
     269           0 :   using Error::Error;
     270             : };
     271             : 
     272             : // Used in ATen for buffer-related errors, e.g. trying to create a DLPack of
     273             : // an unsupported device.  These turn into BufferError when they cross to
     274             : // Python.
     275             : class C10_API BufferError : public Error {
     276             :   using Error::Error;
     277             : };
     278             : 
     279             : // Used in ATen for non finite indices.  These turn into
     280             : // ExitException when they cross to Python.
     281             : class C10_API EnforceFiniteError : public Error {
     282             :   using Error::Error;
     283             : };
     284             : 
     285             : // Used in Onnxifi backend lowering.  These turn into
     286             : // ExitException when they cross to Python.
     287             : class C10_API OnnxfiBackendSystemError : public Error {
     288             :   using Error::Error;
     289             : };
     290             : 
     291             : // Used for numerical errors from the linalg module. These
     292             : // turn into LinAlgError when they cross into Python.
     293             : class C10_API LinAlgError : public Error {
     294             :   using Error::Error;
     295             : };
     296             : 
     297             : class C10_API OutOfMemoryError : public Error {
     298             :   using Error::Error;
     299             : };
     300             : 
     301             : // Used for handling syntactic errors in input arguments.
     302             : // These turn into SyntaxError when the cross into Python.
     303             : class C10_API SyntaxError : public Error {
     304             :   using Error::Error;
     305             : };
     306             : 
     307             : // Raised when accelerator API call hits an error.
     308             : // These turn into AcceleratorError when the cross into Python
     309             : class C10_API AcceleratorError : public Error {
     310             :   int32_t error_code;
     311             : 
     312             :  public:
     313             :   AcceleratorError(SourceLocation loc, int32_t code, const std::string& msg)
     314             :       : Error(loc, msg), error_code(code) {}
     315             :   int32_t get_error_code() const {
     316             :     return error_code;
     317             :   }
     318             : };
     319             : 
     320             : // Base error type for all distributed errors.
     321             : // These turn into DistError when they cross into Python.
     322             : class C10_API DistError : public Error {
     323             :   using Error::Error;
     324             : };
     325             : 
     326             : // Used for collective communication library errors from the distributed module.
     327             : // These turn into DistBackendError when they cross into Python.
     328             : class C10_API DistBackendError : public DistError {
     329             :   using DistError::DistError;
     330             : };
     331             : 
     332             : // Used for errors originating from the store.
     333             : // These turn into DistStoreError when they cross into Python.
     334             : class C10_API DistStoreError : public DistError {
     335             :   using DistError::DistError;
     336             : };
     337             : 
     338             : // Used for errors originating from the TCP/IP stack and not from collective
     339             : // libraries. These turn into DistNetworkError when they cross into Python.
     340             : class C10_API DistNetworkError : public DistError {
     341             :   using DistError::DistError;
     342             : };
     343             : 
     344             : // Raised when a queue is empty and a non-blocking pop is called.
     345             : // Translated to torch.distributed.QueueEmptyError in Python
     346             : class C10_API DistQueueEmptyError : public DistStoreError {
     347             :   using DistStoreError::DistStoreError;
     348             : };
     349             : 
     350             : // A utility function to return an exception std::string by prepending its
     351             : // exception type before its what() content
     352             : C10_API std::string GetExceptionString(const std::exception& e);
     353             : 
     354             : } // namespace c10
     355             : 
     356             : // Private helper macro for implementing TORCH_INTERNAL_ASSERT and TORCH_CHECK
     357             : //
     358             : // Note: In the debug build With MSVC, __LINE__ might be of long type (a.k.a
     359             : // int32_t), which is different from the definition of `SourceLocation` that
     360             : // requires unsigned int (a.k.a uint32_t) and may cause a compile error with the
     361             : // message: error C2397: conversion from 'long' to 'uint32_t' requires a
     362             : // narrowing conversion Here the static cast is used to pass the build. if this
     363             : // is used inside a lambda the __func__ macro expands to operator(), which isn't
     364             : // very useful, but hard to fix in a macro so suppressing the warning.
     365             : #define C10_THROW_ERROR(err_type, msg) \
     366             :   throw ::c10::err_type(               \
     367             :       {__func__, __FILE__, static_cast<uint32_t>(__LINE__)}, msg)
     368             : 
     369             : #define C10_BUILD_ERROR(err_type, msg) \
     370             :   ::c10::err_type({__func__, __FILE__, static_cast<uint32_t>(__LINE__)}, msg)
     371             : 
     372             : // Private helper macro for workaround MSVC misexpansion of nested macro
     373             : // invocations involving __VA_ARGS__.  See
     374             : // https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly
     375             : #define C10_EXPAND_MSVC_WORKAROUND(x) x
     376             : 
     377             : #include <torch/headeronly/util/Exception.h>
     378             : 
     379             : // ----------------------------------------------------------------------------
     380             : // Error reporting macros
     381             : // ----------------------------------------------------------------------------
     382             : 
     383             : #ifdef STRIP_ERROR_MESSAGES
     384             : #define TORCH_RETHROW(e, ...)                       \
     385             :   do {                                              \
     386             :     (void)e; /* Suppress unused variable warning */ \
     387             :     throw;                                          \
     388             :   } while (false)
     389             : #else
     390             : #define TORCH_RETHROW(e, ...)               \
     391             :   do {                                      \
     392             :     e.add_context(::c10::str(__VA_ARGS__)); \
     393             :     throw;                                  \
     394             :   } while (false)
     395             : #endif
     396             : 
     397             : // A utility macro to provide assert()-like functionality; that is, enforcement
     398             : // of internal invariants in code.  It supports an arbitrary number of extra
     399             : // arguments (evaluated only on failure), which will be printed in the assert
     400             : // failure message using operator<< (this is useful to print some variables
     401             : // which may be useful for debugging.)
     402             : //
     403             : // Usage:
     404             : //    TORCH_INTERNAL_ASSERT(should_be_true);
     405             : //    TORCH_INTERNAL_ASSERT(x == 0, "x = ", x);
     406             : //
     407             : // Assuming no bugs in PyTorch, the conditions tested by this macro should
     408             : // always be true; e.g., it should be possible to disable all of these
     409             : // conditions without changing observable user behavior.  If you would like to
     410             : // do error reporting for user input, please use TORCH_CHECK instead.
     411             : //
     412             : // NOTE: It is SAFE to use this macro in production code; on failure, this
     413             : // simply raises an exception, it does NOT unceremoniously quit the process
     414             : // (unlike assert()).
     415             : //
     416             : #ifdef STRIP_ERROR_MESSAGES
     417             : #define TORCH_INTERNAL_ASSERT(cond, ...)                              \
     418             :   if (C10_UNLIKELY_OR_CONST(!(cond))) {                               \
     419             :     ::c10::detail::torchCheckFail(                                    \
     420             :         __func__,                                                     \
     421             :         __FILE__,                                                     \
     422             :         static_cast<uint32_t>(__LINE__),                              \
     423             :         #cond " INTERNAL ASSERT FAILED at " C10_STRINGIZE(__FILE__)); \
     424             :   }
     425             : #else
     426             : // It would be nice if we could build a combined string literal out of
     427             : // the TORCH_INTERNAL_ASSERT prefix and a user-provided string literal
     428             : // as the first argument, but there doesn't seem to be any good way to
     429             : // do that while still supporting having a first argument that isn't a
     430             : // string literal.
     431             : #define TORCH_INTERNAL_ASSERT(cond, ...)                                         \
     432             :   if (C10_UNLIKELY_OR_CONST(!(cond))) {                                          \
     433             :     ::c10::detail::torchInternalAssertFail(                                      \
     434             :         __func__,                                                                \
     435             :         __FILE__,                                                                \
     436             :         static_cast<uint32_t>(__LINE__),                                         \
     437             :         #cond                                                                    \
     438             :         " INTERNAL ASSERT FAILED at " C10_STRINGIZE(__FILE__) ":" C10_STRINGIZE( \
     439             :             __LINE__) ", please report a bug to PyTorch. ",                      \
     440             :         c10::str(__VA_ARGS__));                                                  \
     441             :   }
     442             : #endif
     443             : 
     444             : // A utility macro to make it easier to test for error conditions from user
     445             : // input.  Like TORCH_INTERNAL_ASSERT, it supports an arbitrary number of extra
     446             : // arguments (evaluated only on failure), which will be printed in the error
     447             : // message using operator<< (e.g., you can pass any object which has
     448             : // operator<< defined.  Most objects in PyTorch have these definitions!)
     449             : //
     450             : // Usage:
     451             : //    TORCH_CHECK(should_be_true); // A default error message will be provided
     452             : //                                 // in this case; but we recommend writing an
     453             : //                                 // explicit error message, as it is more
     454             : //                                 // user friendly.
     455             : //    TORCH_CHECK(x == 0, "Expected x to be 0, but got ", x);
     456             : //
     457             : // On failure, this macro will raise an exception.  If this exception propagates
     458             : // to Python, it will convert into a Python RuntimeError.
     459             : //
     460             : // NOTE: It is SAFE to use this macro in production code; on failure, this
     461             : // simply raises an exception, it does NOT unceremoniously quit the process
     462             : // (unlike CHECK() from glog.)
     463             : //
     464             : #define TORCH_CHECK_WITH(error_t, cond, ...) \
     465             :   TORCH_CHECK_WITH_MSG(error_t, cond, "", __VA_ARGS__)
     466             : 
     467             : #ifdef STRIP_ERROR_MESSAGES
     468             : #define TORCH_CHECK_MSG(cond, type, ...) \
     469             :   (#cond #type " CHECK FAILED at " C10_STRINGIZE(__FILE__))
     470             : #define TORCH_CHECK_WITH_MSG(error_t, cond, type, ...)                \
     471             :   if (C10_UNLIKELY_OR_CONST(!(cond))) {                               \
     472             :     C10_THROW_ERROR(Error, TORCH_CHECK_MSG(cond, type, __VA_ARGS__)); \
     473             :   }
     474             : #else
     475             : 
     476             : namespace c10::detail {
     477             : template <typename... Args>
     478           0 : auto torchCheckMsgImpl(const char* /*msg*/, const Args&... args) {
     479           0 :   return ::c10::str(args...);
     480             : }
     481             : inline C10_API const char* torchCheckMsgImpl(const char* msg) {
     482             :   return msg;
     483             : }
     484             : // If there is just 1 user-provided C-string argument, use it.
     485             : inline C10_API const char* torchCheckMsgImpl(
     486             :     const char* /*msg*/,
     487             :     const char* args) {
     488             :   return args;
     489             : }
     490             : } // namespace c10::detail
     491             : 
     492             : #define TORCH_CHECK_MSG(cond, type, ...)                   \
     493             :   (::c10::detail::torchCheckMsgImpl(                       \
     494             :       "Expected " #cond                                    \
     495             :       " to be true, but got false.  "                      \
     496             :       "(Could this error message be improved?  If so, "    \
     497             :       "please report an enhancement request to PyTorch.)", \
     498             :       ##__VA_ARGS__))
     499             : #define TORCH_CHECK_WITH_MSG(error_t, cond, type, ...)                  \
     500             :   if (C10_UNLIKELY_OR_CONST(!(cond))) {                                 \
     501             :     C10_THROW_ERROR(error_t, TORCH_CHECK_MSG(cond, type, __VA_ARGS__)); \
     502             :   }
     503             : #endif
     504             : 
     505             : namespace c10::detail {
     506             : 
     507             : [[noreturn]] C10_API void torchCheckFail(
     508             :     const char* func,
     509             :     const char* file,
     510             :     uint32_t line,
     511             :     const std::string& msg);
     512             : [[noreturn]] C10_API void torchCheckFail(
     513             :     const char* func,
     514             :     const char* file,
     515             :     uint32_t line,
     516             :     const char* msg);
     517             : 
     518             : // The c10::str() call that creates userMsg can have 1 of 3 return
     519             : // types depending on the number and types of arguments passed to
     520             : // TORCH_INTERNAL_ASSERT.  0 arguments will get a
     521             : // CompileTimeEmptyString, 1 const char * will be passed straight
     522             : // through, and anything else will get converted to std::string.
     523             : [[noreturn]] C10_API void torchInternalAssertFail(
     524             :     const char* func,
     525             :     const char* file,
     526             :     uint32_t line,
     527             :     const char* condMsg,
     528             :     const char* userMsg);
     529             : [[noreturn]] inline C10_API void torchInternalAssertFail(
     530             :     const char* func,
     531             :     const char* file,
     532             :     uint32_t line,
     533             :     const char* condMsg,
     534             :     ::c10::detail::CompileTimeEmptyString /*userMsg*/) {
     535           0 :   torchCheckFail(func, file, line, condMsg);
     536             : }
     537             : [[noreturn]] C10_API void torchInternalAssertFail(
     538             :     const char* func,
     539             :     const char* file,
     540             :     uint32_t line,
     541             :     const char* condMsg,
     542             :     const std::string& userMsg);
     543             : 
     544             : } // namespace c10::detail
     545             : 
     546             : #ifdef STANDALONE_TORCH_HEADER
     547             : 
     548             : // TORCH_CHECK throws std::runtime_error instead of c10::Error which is
     549             : // useful when certain headers are used in a libtorch-independent way,
     550             : // e.g. when Vectorized<T> is used in AOTInductor generated code.
     551             : #ifdef STRIP_ERROR_MESSAGES
     552             : #define TORCH_CHECK(cond, ...)                \
     553             :   if (C10_UNLIKELY_OR_CONST(!(cond))) {       \
     554             :     throw std::runtime_error(TORCH_CHECK_MSG( \
     555             :         cond,                                 \
     556             :         "",                                   \
     557             :         __func__,                             \
     558             :         ", ",                                 \
     559             :         __FILE__,                             \
     560             :         ":",                                  \
     561             :         __LINE__,                             \
     562             :         ", ",                                 \
     563             :         __VA_ARGS__));                        \
     564             :   }
     565             : #else
     566             : #define TORCH_CHECK(cond, ...)                \
     567             :   if (C10_UNLIKELY_OR_CONST(!(cond))) {       \
     568             :     throw std::runtime_error(TORCH_CHECK_MSG( \
     569             :         cond,                                 \
     570             :         "",                                   \
     571             :         __func__,                             \
     572             :         ", ",                                 \
     573             :         __FILE__,                             \
     574             :         ":",                                  \
     575             :         __LINE__,                             \
     576             :         ", ",                                 \
     577             :         ##__VA_ARGS__));                      \
     578             :   }
     579             : #endif
     580             : 
     581             : #else
     582             : 
     583             : #ifdef STRIP_ERROR_MESSAGES
     584             : #define TORCH_CHECK(cond, ...)                   \
     585             :   if (C10_UNLIKELY_OR_CONST(!(cond))) {          \
     586             :     ::c10::detail::torchCheckFail(               \
     587             :         __func__,                                \
     588             :         __FILE__,                                \
     589             :         static_cast<uint32_t>(__LINE__),         \
     590             :         TORCH_CHECK_MSG(cond, "", __VA_ARGS__)); \
     591             :   }
     592             : #else
     593             : #define TORCH_CHECK(cond, ...)                     \
     594             :   if (C10_UNLIKELY_OR_CONST(!(cond))) {            \
     595             :     ::c10::detail::torchCheckFail(                 \
     596             :         __func__,                                  \
     597             :         __FILE__,                                  \
     598             :         static_cast<uint32_t>(__LINE__),           \
     599             :         TORCH_CHECK_MSG(cond, "", ##__VA_ARGS__)); \
     600             :   }
     601             : #endif
     602             : 
     603             : #endif
     604             : 
     605             : // An utility macro that does what `TORCH_CHECK` does if compiled in the host
     606             : // code, otherwise does nothing. Supposed to be used in the code shared between
     607             : // host and device code as an alternative for `TORCH_CHECK`.
     608             : #if defined(__CUDACC__) || defined(__HIPCC__)
     609             : #define TORCH_CHECK_IF_NOT_ON_CUDA(cond, ...)
     610             : #else
     611             : #define TORCH_CHECK_IF_NOT_ON_CUDA(cond, ...) TORCH_CHECK(cond, ##__VA_ARGS__)
     612             : #endif
     613             : 
     614             : // Debug only version of TORCH_INTERNAL_ASSERT. This macro only checks in debug
     615             : // build, and does nothing in release build.  It is appropriate to use
     616             : // in situations where you want to add an assert to a hotpath, but it is
     617             : // too expensive to run this assert on production builds.
     618             : #ifdef NDEBUG
     619             : // Optimized version - generates no code.
     620             : #define TORCH_INTERNAL_ASSERT_DEBUG_ONLY(...) \
     621             :   while (false)                               \
     622             :   C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(__VA_ARGS__))
     623             : #else
     624             : #define TORCH_INTERNAL_ASSERT_DEBUG_ONLY(...) \
     625             :   C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(__VA_ARGS__))
     626             : #endif
     627             : 
     628             : // TODO: We're going to get a lot of similar looking string literals
     629             : // this way; check if this actually affects binary size.
     630             : 
     631             : // Like TORCH_CHECK, but raises LinAlgError instead of Error.
     632             : #define TORCH_CHECK_LINALG(cond, ...) \
     633             :   TORCH_CHECK_WITH_MSG(LinAlgError, cond, "LINALG", __VA_ARGS__)
     634             : 
     635             : // Like TORCH_CHECK, but raises IndexErrors instead of Errors.
     636             : #define TORCH_CHECK_INDEX(cond, ...) \
     637             :   TORCH_CHECK_WITH_MSG(IndexError, cond, "INDEX", __VA_ARGS__)
     638             : 
     639             : // Like TORCH_CHECK, but raises ValueErrors instead of Errors.
     640             : #define TORCH_CHECK_VALUE(cond, ...) \
     641             :   TORCH_CHECK_WITH_MSG(ValueError, cond, "VALUE", __VA_ARGS__)
     642             : 
     643             : // Like TORCH_CHECK, but raises TypeErrors instead of Errors.
     644             : #define TORCH_CHECK_TYPE(cond, ...) \
     645             :   TORCH_CHECK_WITH_MSG(TypeError, cond, "TYPE", __VA_ARGS__)
     646             : 
     647             : // Like TORCH_CHECK, but raises NotImplementedErrors instead of Errors.
     648             : #define TORCH_CHECK_NOT_IMPLEMENTED(cond, ...) \
     649             :   TORCH_CHECK_WITH_MSG(NotImplementedError, cond, "TYPE", __VA_ARGS__)
     650             : 
     651             : // Like TORCH_CHECK, but raises BufferError instead of Errors.
     652             : #define TORCH_CHECK_BUFFER(cond, ...) \
     653             :   TORCH_CHECK_WITH_MSG(BufferError, cond, "TYPE", __VA_ARGS__)
     654             : 
     655             : #define TORCH_CHECK_ALWAYS_SHOW_CPP_STACKTRACE(cond, ...) \
     656             :   TORCH_CHECK_WITH_MSG(                                   \
     657             :       ErrorAlwaysShowCppStacktrace, cond, "TYPE", ##__VA_ARGS__)
     658             : 
     659             : #ifdef STRIP_ERROR_MESSAGES
     660             : #define WARNING_MESSAGE_STRING(...) \
     661             :   ::c10::detail::CompileTimeEmptyString {}
     662             : #else
     663             : #define WARNING_MESSAGE_STRING(...) ::c10::str(__VA_ARGS__)
     664             : #endif
     665             : 
     666             : // Report a warning to the user.  Accepts an arbitrary number of extra
     667             : // arguments which are concatenated into the warning message using operator<<
     668             : //
     669             : #ifdef DISABLE_WARN
     670             : #define _TORCH_WARN_WITH(...) ((void)0);
     671             : #else
     672             : #define _TORCH_WARN_WITH(warning_t, ...)                     \
     673             :   ::c10::warn(::c10::Warning(                                \
     674             :       warning_t(),                                           \
     675             :       {__func__, __FILE__, static_cast<uint32_t>(__LINE__)}, \
     676             :       WARNING_MESSAGE_STRING(__VA_ARGS__),                   \
     677             :       false));
     678             : #endif
     679             : 
     680             : #define TORCH_WARN(...) _TORCH_WARN_WITH(::c10::UserWarning, __VA_ARGS__);
     681             : 
     682             : #define TORCH_WARN_DEPRECATION(...) \
     683             :   _TORCH_WARN_WITH(::c10::DeprecationWarning, __VA_ARGS__);
     684             : 
     685             : // Report a warning to the user only once.  Accepts an arbitrary number of extra
     686             : // arguments which are concatenated into the warning message using operator<<
     687             : //
     688             : #define _TORCH_WARN_ONCE(...)                                \
     689             :   [[maybe_unused]] static const auto C10_ANONYMOUS_VARIABLE( \
     690             :       torch_warn_once_) = [&] {                              \
     691             :     TORCH_WARN(__VA_ARGS__);                                 \
     692             :     return true;                                             \
     693             :   }()
     694             : 
     695             : #ifdef DISABLE_WARN
     696             : #define TORCH_WARN_ONCE(...) ((void)0);
     697             : #else
     698             : #define TORCH_WARN_ONCE(...)                   \
     699             :   if (::c10::WarningUtils::get_warnAlways()) { \
     700             :     TORCH_WARN(__VA_ARGS__);                   \
     701             :   } else {                                     \
     702             :     _TORCH_WARN_ONCE(__VA_ARGS__);             \
     703             :   }
     704             : #endif
     705             : 
     706             : // Report an error with a specific argument
     707             : // NOTE: using the argument name in TORCH_CHECK's message is preferred
     708             : #define TORCH_CHECK_ARG(cond, argN, ...) \
     709             :   TORCH_CHECK(cond, "invalid argument ", argN, ": ", __VA_ARGS__)
     710             : 
     711             : #ifndef FATAL_IF
     712             : #ifdef C10_USE_GLOG
     713             : #define FATAL_IF(condition)                                           \
     714             :   condition ? (void)0                                                 \
     715             :             : ::c10::LoggerVoidify() &                                \
     716             :           ::c10::MessageLogger(                                       \
     717             :               ::c10::SourceLocation::current(), ::google::GLOG_FATAL) \
     718             :               .stream()
     719             : #else
     720             : #define FATAL_IF(condition)                                        \
     721             :   condition ? (void)0                                              \
     722             :             : ::c10::LoggerVoidify() &                             \
     723             :           ::c10::MessageLogger(                                    \
     724             :               ::c10::SourceLocation::current(), ::c10::GLOG_FATAL) \
     725             :               .stream()
     726             : #endif
     727             : #endif
     728             : 
     729             : #ifndef NON_FATAL_IF
     730             : #ifdef C10_USE_GLOG
     731             : #define NON_FATAL_IF(condition)                                              \
     732             :   condition ? (void)0                                                        \
     733             :             : ::c10::LoggerVoidify() &                                       \
     734             :           ::c10::MessageLogger(                                              \
     735             :               ::c10::SourceLocation::current(), ::google::GLOG_FATAL, false) \
     736             :               .stream()
     737             : #else
     738             : #define NON_FATAL_IF(condition)                                           \
     739             :   condition ? (void)0                                                     \
     740             :             : ::c10::LoggerVoidify() &                                    \
     741             :           ::c10::MessageLogger(                                           \
     742             :               ::c10::SourceLocation::current(), ::c10::GLOG_FATAL, false) \
     743             :               .stream()
     744             : #endif
     745             : #endif
     746             : 
     747             : // Binary comparison check macros
     748             : #define TORCH_CHECK_OP(val1, val2, op)                                      \
     749             :   NON_FATAL_IF(((val1)op(val2)))                                            \
     750             :       << "Check failed: " #val1 " " #op " " #val2 " (" << (val1) << " vs. " \
     751             :       << (val2) << "). "
     752             : 
     753             : #define TORCH_DCHECK_OP(val1, val2, op)                                       \
     754             :   FATAL_IF(((val1)op(val2))) << "Check failed: " #val1 " " #op " " #val2 " (" \
     755             :                              << (val1) << " vs. " << (val2) << "). "
     756             : 
     757             : #define TORCH_CHECK_EQ(val1, val2) TORCH_CHECK_OP(val1, val2, ==)
     758             : #define TORCH_CHECK_NE(val1, val2) TORCH_CHECK_OP(val1, val2, !=)
     759             : #define TORCH_CHECK_LE(val1, val2) TORCH_CHECK_OP(val1, val2, <=)
     760             : #define TORCH_CHECK_LT(val1, val2) TORCH_CHECK_OP(val1, val2, <)
     761             : #define TORCH_CHECK_GE(val1, val2) TORCH_CHECK_OP(val1, val2, >=)
     762             : #define TORCH_CHECK_GT(val1, val2) TORCH_CHECK_OP(val1, val2, >)
     763             : 
     764             : // Debug versions of TORCH_CHECK_OP macros
     765             : #ifndef NDEBUG
     766             : #define TORCH_DCHECK_EQ(val1, val2) TORCH_DCHECK_OP(val1, val2, ==)
     767             : #define TORCH_DCHECK_NE(val1, val2) TORCH_DCHECK_OP(val1, val2, !=)
     768             : #define TORCH_DCHECK_LE(val1, val2) TORCH_DCHECK_OP(val1, val2, <=)
     769             : #define TORCH_DCHECK_LT(val1, val2) TORCH_DCHECK_OP(val1, val2, <)
     770             : #define TORCH_DCHECK_GE(val1, val2) TORCH_DCHECK_OP(val1, val2, >=)
     771             : #define TORCH_DCHECK_GT(val1, val2) TORCH_DCHECK_OP(val1, val2, >)
     772             : #else // !NDEBUG
     773             : // Optimized versions - generate no code
     774             : #define TORCH_DCHECK_EQ(val1, val2) \
     775             :   while (false)                     \
     776             :   TORCH_DCHECK_OP(val1, val2, ==)
     777             : #define TORCH_DCHECK_NE(val1, val2) \
     778             :   while (false)                     \
     779             :   TORCH_DCHECK_OP(val1, val2, !=)
     780             : #define TORCH_DCHECK_LE(val1, val2) \
     781             :   while (false)                     \
     782             :   TORCH_DCHECK_OP(val1, val2, <=)
     783             : #define TORCH_DCHECK_LT(val1, val2) \
     784             :   while (false)                     \
     785             :   TORCH_DCHECK_OP(val1, val2, <)
     786             : #define TORCH_DCHECK_GE(val1, val2) \
     787             :   while (false)                     \
     788             :   TORCH_DCHECK_OP(val1, val2, >=)
     789             : #define TORCH_DCHECK_GT(val1, val2) \
     790             :   while (false)                     \
     791             :   TORCH_DCHECK_OP(val1, val2, >)
     792             : #endif // NDEBUG
     793             : 
     794             : // Null pointer check macro
     795             : #define TORCH_CHECK_NOTNULL(val) \
     796             :   ::c10::CheckNotNull(__FILE__, __LINE__, #val, (val), false)
     797             : 
     798             : #ifndef NDEBUG
     799             : #define TORCH_DCHECK_NOTNULL(val) \
     800             :   ::c10::CheckNotNull(__FILE__, __LINE__, #val, (val), true)
     801             : #else // !NDEBUG
     802             : #define TORCH_DCHECK_NOTNULL(val) \
     803             :   while (false)                   \
     804             :   TORCH_CHECK_NOTNULL(val)
     805             : #endif // NDEBUG
     806             : 
     807             : // ----------------------------------------------------------------------------
     808             : // Deprecated macros
     809             : // ----------------------------------------------------------------------------
     810             : 
     811             : namespace c10::detail {
     812             : 
     813             : /*
     814             : // Deprecation disabled until we fix sites in our codebase
     815             : [[deprecated("AT_ERROR(msg) is deprecated, use TORCH_CHECK(false, msg)
     816             : instead.")]]
     817             : */
     818             : inline void deprecated_AT_ERROR() {}
     819             : 
     820             : /*
     821             : // Deprecation disabled until we fix sites in our codebase
     822             : [[deprecated("AT_ASSERT is deprecated, if you mean to indicate an
     823             : internal invariant failure, use " \
     824             :                        "TORCH_INTERNAL_ASSERT instead; if you mean to do user
     825             : error checking, use " \ "TORCH_CHECK.  See
     826             : https://github.com/pytorch/pytorch/issues/20287 for more details.")]]
     827             : */
     828             : inline void deprecated_AT_ASSERT() {}
     829             : 
     830             : /*
     831             : // Deprecation disabled until we fix sites in our codebase
     832             : [[deprecated("AT_ASSERTM is deprecated, if you mean to indicate an
     833             : internal invariant failure, use " \
     834             :                        "TORCH_INTERNAL_ASSERT instead; if you mean to do user
     835             : error checking, use " \ "TORCH_CHECK.  See
     836             : https://github.com/pytorch/pytorch/issues/20287 for more details.")]]
     837             : */
     838             : inline void deprecated_AT_ASSERTM() {}
     839             : 
     840             : } // namespace c10::detail
     841             : 
     842             : // Deprecated alias; this alias was deprecated because people kept mistakenly
     843             : // using it for user error checking.  Use TORCH_INTERNAL_ASSERT or TORCH_CHECK
     844             : // instead. See https://github.com/pytorch/pytorch/issues/20287 for more
     845             : // details.
     846             : #define AT_ASSERT(...)                                              \
     847             :   do {                                                              \
     848             :     ::c10::detail::deprecated_AT_ASSERT();                          \
     849             :     C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(__VA_ARGS__)); \
     850             :   } while (false)
     851             : 
     852             : // Deprecated alias, like AT_ASSERT.  The new TORCH_INTERNAL_ASSERT macro
     853             : // supports both 0-ary and variadic calls, so having a separate
     854             : // message-accepting macro is not necessary.
     855             : //
     856             : // NB: we MUST include cond explicitly here, as MSVC will miscompile the macro
     857             : // expansion, shunting all of __VA_ARGS__ to cond.  An alternate workaround
     858             : // can be seen at
     859             : // https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly
     860             : #define AT_ASSERTM(cond, ...)                                             \
     861             :   do {                                                                    \
     862             :     ::c10::detail::deprecated_AT_ASSERTM();                               \
     863             :     C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(cond, __VA_ARGS__)); \
     864             :   } while (false)
     865             : 
     866             : // Deprecated alias; this alias was deprecated because it represents extra API
     867             : // surface that makes it hard for people to understand what macro to use.
     868             : // Use TORCH_CHECK(false, ...) or TORCH_INTERNAL_ASSERT(false, ...) to
     869             : // unconditionally fail at a line of code.
     870             : #define AT_ERROR(...)                                                        \
     871             :   do {                                                                       \
     872             :     ::c10::detail::deprecated_AT_ERROR();                                    \
     873             :     C10_EXPAND_MSVC_WORKAROUND(TORCH_CHECK(false, ::c10::str(__VA_ARGS__))); \
     874             :   } while (false)
     875             : 
     876             : #endif // C10_UTIL_EXCEPTION_H_
     877             : 
     878             : #else
     879             : #error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined."
     880             : #endif  // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)

Generated by: LCOV version 1.16