LCOV - code coverage report
Current view: top level - libtorch/include/c10/util - Exception.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 11 0
Test Date: 2024-04-30 13:17:26 Functions: 0.0 % 8 0

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

Generated by: LCOV version 2.0-1