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

Generated by: LCOV version 1.16