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

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

Generated by: LCOV version 1.16