Rate this Page

Program Listing for File Exception.h#

Return to documentation for file (c10/util/Exception.h)

#ifndef C10_UTIL_EXCEPTION_H_#define C10_UTIL_EXCEPTION_H_#include<c10/macros/Export.h>#include<c10/macros/Macros.h>#include<c10/util/Backtrace.h>#include<c10/util/Lazy.h>#include<c10/util/StringUtil.h>#include<cstdint>#include<exception>#include<memory>#include<string>#include<variant>#include<vector>#if defined(_MSC_VER) && _MSC_VER <= 1900#define __func__ __FUNCTION__#endifnamespacec10{classC10_APIError:publicstd::exception{private:// The actual error message.std::stringmsg_;// Context for the message (in order of decreasing specificity).  Context will// be automatically formatted appropriately, so it is not necessary to add// extra leading/trailing newlines to strings inside this vectorstd::vector<std::string>context_;// The C++ backtrace at the point when this exception was raised.  This// may be empty if there is no valid backtrace.  (We don't use optional// here to reduce the dependencies this file has.)Backtracebacktrace_;// These two are derived fields from msg_stack_ and backtrace_, but we need// fields for the strings so that we can return a const char* (as the// signature of std::exception requires).  Currently, the invariant// is that these fields are ALWAYS populated consistently with respect// to msg_stack_ and backtrace_.mutableOptimisticLazy<std::string>what_;std::stringwhat_without_backtrace_;// This is a little debugging trick: you can stash a relevant pointer// in caller, and then when you catch the exception, you can compare// against pointers you have on hand to get more information about// where the exception came from.  In Caffe2, this is used to figure// out which operator raised an exception.constvoid*caller_;public:// PyTorch-style Error constructor.  NB: the implementation of this// is actually in Logging.cppError(SourceLocationsource_location,std::stringmsg);// Caffe2-style error messageError(constchar*file,constuint32_tline,constchar*condition,conststd::string&msg,Backtracebacktrace,constvoid*caller=nullptr);// Base constructorError(std::stringmsg,Backtracebacktrace=nullptr,constvoid*caller=nullptr);// Add some new context to the message stack.  The last added context// will be formatted at the end of the context list upon printing.// WARNING: This method is O(n) in the size of the stack, so don't go// wild adding a ridiculous amount of context to error messages.voidadd_context(std::stringmsg);conststd::string&msg()const{returnmsg_;}conststd::vector<std::string>&context()const{returncontext_;}constBacktrace&backtrace()const;constchar*what()constnoexceptoverride;constvoid*caller()constnoexcept{returncaller_;}virtualconstchar*what_without_backtrace()constnoexcept{returnwhat_without_backtrace_.c_str();}private:voidrefresh_what();std::stringcompute_what(boolinclude_backtrace)const;};classC10_APIWarning{public:classC10_APIUserWarning{};classC10_APIDeprecationWarning{};usingwarning_variant_t=std::variant<UserWarning,DeprecationWarning>;Warning(warning_variant_ttype,constSourceLocation&source_location,std::stringmsg,boolverbatim);Warning(warning_variant_ttype,SourceLocationsource_location,constchar*msg,boolverbatim);Warning(warning_variant_ttype,SourceLocationsource_location,::c10::detail::CompileTimeEmptyStringmsg,boolverbatim);// Getters for memberswarning_variant_ttype()const;constSourceLocation&source_location()const;conststd::string&msg()const;boolverbatim()const;private:// The type of warningwarning_variant_ttype_;// Where the warning happened.SourceLocationsource_location_;// The actual warning message.std::stringmsg_;// See note: [Verbatim Warnings]boolverbatim_;};usingUserWarning=Warning::UserWarning;usingDeprecationWarning=Warning::DeprecationWarning;// Issue a warning with a given message. Dispatched to the current// warning handler.voidC10_APIwarn(constWarning&warning);classC10_APIWarningHandler{public:virtual~WarningHandler()=default;virtualvoidprocess(constWarning&warning);};namespaceWarningUtils{// Note: [Verbatim Warnings]// Warnings originating in C++ code can appear out-of-place to Python users:// a user runs a line in Python, but the warning references a line in C++.// Some parts of PyTorch, like the JIT, are cognizant of this mismatch// and take care to map warnings back to the user's program, but most// of PyTorch simply throws a context-free warning. To allow warning// handlers to add context where appropriate, warn takes the// "verbatim" flag. When this is false a warning handler might append// the C++ warning to a Python warning message that relates the warning// back to the user's program. Callers who have already accounted for// context in their warnings should set verbatim to true so their warnings// appear without modification.C10_APIvoidset_warning_handler(WarningHandler*handler)noexcept(true);C10_APIWarningHandler*get_warning_handler()noexcept(true);classC10_APIWarningHandlerGuard{WarningHandler*prev_handler_;public:WarningHandlerGuard(WarningHandler*new_handler):prev_handler_(c10::WarningUtils::get_warning_handler()){c10::WarningUtils::set_warning_handler(new_handler);}WarningHandlerGuard(WarningHandlerGuard&&other)=delete;WarningHandlerGuard(constWarningHandlerGuard&)=delete;WarningHandlerGuard&operator=(constWarningHandlerGuard&)=delete;WarningHandlerGuard&operator=(WarningHandlerGuard&&)=delete;~WarningHandlerGuard(){c10::WarningUtils::set_warning_handler(prev_handler_);}};C10_APIvoidset_warnAlways(bool/*setting*/)noexcept(true);C10_APIboolget_warnAlways()noexcept(true);// A RAII guard that sets warn_always (not thread-local) on// construction, and sets it back to the original value upon destruction.structC10_APIWarnAlways{public:explicitWarnAlways(boolsetting=true);~WarnAlways();private:boolprev_setting;};}// namespace WarningUtils// Like Error, but we always report the C++ backtrace, instead of only// reporting when TORCH_SHOW_CPP_STACKTRACESclassC10_APIErrorAlwaysShowCppStacktrace:publicError{usingError::Error;constchar*what_without_backtrace()constnoexceptoverride{returnwhat();}};// Used in ATen for out-of-bound indices that can reasonably only be detected// lazily inside a kernel (See: advanced indexing).  These turn into// IndexError when they cross to Python.classC10_APIIndexError:publicError{usingError::Error;};// Used in ATen for invalid values.  These turn into// ValueError when they cross to Python.classC10_APIValueError:publicError{usingError::Error;};// Used in ATen for invalid types.  These turn into// TypeError when they cross to Python.classC10_APITypeError:publicError{usingError::Error;};// Used in ATen for functionality that is not implemented.  These turn into// NotImplementedError when they cross to Python.classC10_APINotImplementedError:publicError{usingError::Error;};// Used in ATen for buffer-related errors, e.g. trying to create a DLPack of// an unsupported device.  These turn into BufferError when they cross to// Python.classC10_APIBufferError:publicError{usingError::Error;};// Used in ATen for non finite indices.  These turn into// ExitException when they cross to Python.classC10_APIEnforceFiniteError:publicError{usingError::Error;};// Used in Onnxifi backend lowering.  These turn into// ExitException when they cross to Python.classC10_APIOnnxfiBackendSystemError:publicError{usingError::Error;};// Used for numerical errors from the linalg module. These// turn into LinAlgError when they cross into Python.classC10_APILinAlgError:publicError{usingError::Error;};classC10_APIOutOfMemoryError:publicError{usingError::Error;};// Used for handling syntactic errors in input arguments.// These turn into SyntaxError when the cross into Python.classC10_APISyntaxError:publicError{usingError::Error;};// Raised when accelerator API call hits an error.// These turn into AcceleratorError when the cross into PythonclassC10_APIAcceleratorError:publicError{int32_terror_code;public:AcceleratorError(SourceLocationloc,int32_tcode,conststd::string&msg):Error(loc,msg),error_code(code){}int32_tget_error_code()const{returnerror_code;}};// Base error type for all distributed errors.// These turn into DistError when they cross into Python.classC10_APIDistError:publicError{usingError::Error;};// Used for collective communication library errors from the distributed module.// These turn into DistBackendError when they cross into Python.classC10_APIDistBackendError:publicDistError{usingDistError::DistError;};// Used for errors originating from the store.// These turn into DistStoreError when they cross into Python.classC10_APIDistStoreError:publicDistError{usingDistError::DistError;};// Used for errors originating from the TCP/IP stack and not from collective// libraries. These turn into DistNetworkError when they cross into Python.classC10_APIDistNetworkError:publicDistError{usingDistError::DistError;};// Raised when a queue is empty and a non-blocking pop is called.// Translated to torch.distributed.QueueEmptyError in PythonclassC10_APIDistQueueEmptyError:publicDistStoreError{usingDistStoreError::DistStoreError;};// A utility function to return an exception std::string by prepending its// exception type before its what() contentC10_APIstd::stringGetExceptionString(conststd::exception&e);}// namespace c10// Private helper macro for implementing TORCH_INTERNAL_ASSERT and TORCH_CHECK//// Note: In the debug build With MSVC, __LINE__ might be of long type (a.k.a// int32_t), which is different from the definition of `SourceLocation` that// requires unsigned int (a.k.a uint32_t) and may cause a compile error with the// message: error C2397: conversion from 'long' to 'uint32_t' requires a// narrowing conversion Here the static cast is used to pass the build. if this// is used inside a lambda the __func__ macro expands to operator(), which isn't// very useful, but hard to fix in a macro so suppressing the warning.#define C10_THROW_ERROR(err_type, msg) \  throw ::c10::err_type(               \      {__func__, __FILE__, static_cast<uint32_t>(__LINE__)}, msg)#define C10_BUILD_ERROR(err_type, msg) \  ::c10::err_type({__func__, __FILE__, static_cast<uint32_t>(__LINE__)}, msg)// Private helper macro for workaround MSVC misexpansion of nested macro// invocations involving __VA_ARGS__.  See// https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly#define C10_EXPAND_MSVC_WORKAROUND(x) x#include<torch/headeronly/util/Exception.h>// ----------------------------------------------------------------------------// Error reporting macros// ----------------------------------------------------------------------------#ifdef STRIP_ERROR_MESSAGES#define TORCH_RETHROW(e, ...)                       \  do {                                              \    (void)e;/* Suppress unused variable warning */ \    throw;                                          \  } while (false)#else#define TORCH_RETHROW(e, ...)               \  do {                                      \    e.add_context(::c10::str(__VA_ARGS__)); \    throw;                                  \  } while (false)#endif// A utility macro to provide assert()-like functionality; that is, enforcement// of internal invariants in code.  It supports an arbitrary number of extra// arguments (evaluated only on failure), which will be printed in the assert// failure message using operator<< (this is useful to print some variables// which may be useful for debugging.)//// Usage://    TORCH_INTERNAL_ASSERT(should_be_true);//    TORCH_INTERNAL_ASSERT(x == 0, "x = ", x);//// Assuming no bugs in PyTorch, the conditions tested by this macro should// always be true; e.g., it should be possible to disable all of these// conditions without changing observable user behavior.  If you would like to// do error reporting for user input, please use TORCH_CHECK instead.//// NOTE: It is SAFE to use this macro in production code; on failure, this// simply raises an exception, it does NOT unceremoniously quit the process// (unlike assert()).//#ifdef STRIP_ERROR_MESSAGES#define TORCH_INTERNAL_ASSERT(cond, ...)                              \  if (C10_UNLIKELY_OR_CONST(!(cond))) {                               \    ::c10::detail::torchCheckFail(                                    \        __func__,                                                     \        __FILE__,                                                     \        static_cast<uint32_t>(__LINE__),                              \        #cond " INTERNAL ASSERT FAILED at " C10_STRINGIZE(__FILE__)); \  }#else// It would be nice if we could build a combined string literal out of// the TORCH_INTERNAL_ASSERT prefix and a user-provided string literal// as the first argument, but there doesn't seem to be any good way to// do that while still supporting having a first argument that isn't a// string literal.#define TORCH_INTERNAL_ASSERT(cond, ...)                                         \  if (C10_UNLIKELY_OR_CONST(!(cond))) {                                          \    ::c10::detail::torchInternalAssertFail(                                      \        __func__,                                                                \        __FILE__,                                                                \        static_cast<uint32_t>(__LINE__),                                         \        #cond                                                                    \        " INTERNAL ASSERT FAILED at " C10_STRINGIZE(__FILE__) ":" C10_STRINGIZE( \            __LINE__) ", please report a bug to PyTorch. ",                      \        c10::str(__VA_ARGS__));                                                  \  }#endif// A utility macro to make it easier to test for error conditions from user// input.  Like TORCH_INTERNAL_ASSERT, it supports an arbitrary number of extra// arguments (evaluated only on failure), which will be printed in the error// message using operator<< (e.g., you can pass any object which has// operator<< defined.  Most objects in PyTorch have these definitions!)//// Usage://    TORCH_CHECK(should_be_true); // A default error message will be provided//                                 // in this case; but we recommend writing an//                                 // explicit error message, as it is more//                                 // user friendly.//    TORCH_CHECK(x == 0, "Expected x to be 0, but got ", x);//// On failure, this macro will raise an exception.  If this exception propagates// to Python, it will convert into a Python RuntimeError.//// NOTE: It is SAFE to use this macro in production code; on failure, this// simply raises an exception, it does NOT unceremoniously quit the process// (unlike CHECK() from glog.)//#define TORCH_CHECK_WITH(error_t, cond, ...) \  TORCH_CHECK_WITH_MSG(error_t, cond, "", __VA_ARGS__)#ifdef STRIP_ERROR_MESSAGES#define TORCH_CHECK_MSG(cond, type, ...) \  (#cond #type " CHECK FAILED at " C10_STRINGIZE(__FILE__))#define TORCH_CHECK_WITH_MSG(error_t, cond, type, ...)                \  if (C10_UNLIKELY_OR_CONST(!(cond))) {                               \    C10_THROW_ERROR(Error, TORCH_CHECK_MSG(cond, type, __VA_ARGS__)); \  }#elsenamespacec10::detail{template<typename...Args>autotorchCheckMsgImpl(constchar*/*msg*/,constArgs&...args){return::c10::str(args...);}inlineC10_APIconstchar*torchCheckMsgImpl(constchar*msg){returnmsg;}// If there is just 1 user-provided C-string argument, use it.inlineC10_APIconstchar*torchCheckMsgImpl(constchar*/*msg*/,constchar*args){returnargs;}}// namespace c10::detail#define TORCH_CHECK_MSG(cond, type, ...)                   \  (::c10::detail::torchCheckMsgImpl(                       \      "Expected " #cond                                    \      " to be true, but got false.  "                      \      "(Could this error message be improved?  If so, "    \      "please report an enhancement request to PyTorch.)", \      ##__VA_ARGS__))#define TORCH_CHECK_WITH_MSG(error_t, cond, type, ...)                  \  if (C10_UNLIKELY_OR_CONST(!(cond))) {                                 \    C10_THROW_ERROR(error_t, TORCH_CHECK_MSG(cond, type, __VA_ARGS__)); \  }#endifnamespacec10::detail{[[noreturn]]C10_APIvoidtorchCheckFail(constchar*func,constchar*file,uint32_tline,conststd::string&msg);[[noreturn]]C10_APIvoidtorchCheckFail(constchar*func,constchar*file,uint32_tline,constchar*msg);// The c10::str() call that creates userMsg can have 1 of 3 return// types depending on the number and types of arguments passed to// TORCH_INTERNAL_ASSERT.  0 arguments will get a// CompileTimeEmptyString, 1 const char * will be passed straight// through, and anything else will get converted to std::string.[[noreturn]]C10_APIvoidtorchInternalAssertFail(constchar*func,constchar*file,uint32_tline,constchar*condMsg,constchar*userMsg);[[noreturn]]inlineC10_APIvoidtorchInternalAssertFail(constchar*func,constchar*file,uint32_tline,constchar*condMsg,::c10::detail::CompileTimeEmptyString/*userMsg*/){torchCheckFail(func,file,line,condMsg);}[[noreturn]]C10_APIvoidtorchInternalAssertFail(constchar*func,constchar*file,uint32_tline,constchar*condMsg,conststd::string&userMsg);}// namespace c10::detail#ifdef STANDALONE_TORCH_HEADER// TORCH_CHECK throws std::runtime_error instead of c10::Error which is// useful when certain headers are used in a libtorch-independent way,// e.g. when Vectorized<T> is used in AOTInductor generated code.#ifdef STRIP_ERROR_MESSAGES#define TORCH_CHECK(cond, ...)                \  if (C10_UNLIKELY_OR_CONST(!(cond))) {       \    throw std::runtime_error(TORCH_CHECK_MSG( \        cond,                                 \        "",                                   \        __func__,                             \        ", ",                                 \        __FILE__,                             \        ":",                                  \        __LINE__,                             \        ", ",                                 \        __VA_ARGS__));                        \  }#else#define TORCH_CHECK(cond, ...)                \  if (C10_UNLIKELY_OR_CONST(!(cond))) {       \    throw std::runtime_error(TORCH_CHECK_MSG( \        cond,                                 \        "",                                   \        __func__,                             \        ", ",                                 \        __FILE__,                             \        ":",                                  \        __LINE__,                             \        ", ",                                 \        ##__VA_ARGS__));                      \  }#endif#else#ifdef STRIP_ERROR_MESSAGES#define TORCH_CHECK(cond, ...)                   \  if (C10_UNLIKELY_OR_CONST(!(cond))) {          \    ::c10::detail::torchCheckFail(               \        __func__,                                \        __FILE__,                                \        static_cast<uint32_t>(__LINE__),         \        TORCH_CHECK_MSG(cond, "", __VA_ARGS__)); \  }#else#define TORCH_CHECK(cond, ...)                     \  if (C10_UNLIKELY_OR_CONST(!(cond))) {            \    ::c10::detail::torchCheckFail(                 \        __func__,                                  \        __FILE__,                                  \        static_cast<uint32_t>(__LINE__),           \        TORCH_CHECK_MSG(cond, "", ##__VA_ARGS__)); \  }#endif#endif// An utility macro that does what `TORCH_CHECK` does if compiled in the host// code, otherwise does nothing. Supposed to be used in the code shared between// host and device code as an alternative for `TORCH_CHECK`.#if defined(__CUDACC__) || defined(__HIPCC__)#define TORCH_CHECK_IF_NOT_ON_CUDA(cond, ...)#else#define TORCH_CHECK_IF_NOT_ON_CUDA(cond, ...) TORCH_CHECK(cond, ##__VA_ARGS__)#endif// Debug only version of TORCH_INTERNAL_ASSERT. This macro only checks in debug// build, and does nothing in release build.  It is appropriate to use// in situations where you want to add an assert to a hotpath, but it is// too expensive to run this assert on production builds.#ifdef NDEBUG// Optimized version - generates no code.#define TORCH_INTERNAL_ASSERT_DEBUG_ONLY(...) \  while (false)                               \  C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(__VA_ARGS__))#else#define TORCH_INTERNAL_ASSERT_DEBUG_ONLY(...) \  C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(__VA_ARGS__))#endif// TODO: We're going to get a lot of similar looking string literals// this way; check if this actually affects binary size.// Like TORCH_CHECK, but raises LinAlgError instead of Error.#define TORCH_CHECK_LINALG(cond, ...) \  TORCH_CHECK_WITH_MSG(LinAlgError, cond, "LINALG", __VA_ARGS__)// Like TORCH_CHECK, but raises IndexErrors instead of Errors.#define TORCH_CHECK_INDEX(cond, ...) \  TORCH_CHECK_WITH_MSG(IndexError, cond, "INDEX", __VA_ARGS__)// Like TORCH_CHECK, but raises ValueErrors instead of Errors.#define TORCH_CHECK_VALUE(cond, ...) \  TORCH_CHECK_WITH_MSG(ValueError, cond, "VALUE", __VA_ARGS__)// Like TORCH_CHECK, but raises TypeErrors instead of Errors.#define TORCH_CHECK_TYPE(cond, ...) \  TORCH_CHECK_WITH_MSG(TypeError, cond, "TYPE", __VA_ARGS__)// Like TORCH_CHECK, but raises NotImplementedErrors instead of Errors.#define TORCH_CHECK_NOT_IMPLEMENTED(cond, ...) \  TORCH_CHECK_WITH_MSG(NotImplementedError, cond, "TYPE", __VA_ARGS__)// Like TORCH_CHECK, but raises BufferError instead of Errors.#define TORCH_CHECK_BUFFER(cond, ...) \  TORCH_CHECK_WITH_MSG(BufferError, cond, "TYPE", __VA_ARGS__)#define TORCH_CHECK_ALWAYS_SHOW_CPP_STACKTRACE(cond, ...) \  TORCH_CHECK_WITH_MSG(                                   \      ErrorAlwaysShowCppStacktrace, cond, "TYPE", ##__VA_ARGS__)#ifdef STRIP_ERROR_MESSAGES#define WARNING_MESSAGE_STRING(...) \  ::c10::detail::CompileTimeEmptyString {}#else#define WARNING_MESSAGE_STRING(...) ::c10::str(__VA_ARGS__)#endif// Report a warning to the user.  Accepts an arbitrary number of extra// arguments which are concatenated into the warning message using operator<<//#ifdef DISABLE_WARN#define _TORCH_WARN_WITH(...) ((void)0);#else#define _TORCH_WARN_WITH(warning_t, ...)                     \  ::c10::warn(::c10::Warning(                                \      warning_t(),                                           \      {__func__, __FILE__, static_cast<uint32_t>(__LINE__)}, \      WARNING_MESSAGE_STRING(__VA_ARGS__),                   \      false));#endif#define TORCH_WARN(...) _TORCH_WARN_WITH(::c10::UserWarning, __VA_ARGS__);#define TORCH_WARN_DEPRECATION(...) \  _TORCH_WARN_WITH(::c10::DeprecationWarning, __VA_ARGS__);// Report a warning to the user only once.  Accepts an arbitrary number of extra// arguments which are concatenated into the warning message using operator<<//#define _TORCH_WARN_ONCE(...)                                \  [[maybe_unused]] static const auto C10_ANONYMOUS_VARIABLE( \      torch_warn_once_) = [&] {                              \    TORCH_WARN(__VA_ARGS__);                                 \    return true;                                             \  }()#ifdef DISABLE_WARN#define TORCH_WARN_ONCE(...) ((void)0);#else#define TORCH_WARN_ONCE(...)                   \  if (::c10::WarningUtils::get_warnAlways()) { \    TORCH_WARN(__VA_ARGS__);                   \  } else {                                     \    _TORCH_WARN_ONCE(__VA_ARGS__);             \  }#endif// Report an error with a specific argument// NOTE: using the argument name in TORCH_CHECK's message is preferred#define TORCH_CHECK_ARG(cond, argN, ...) \  TORCH_CHECK(cond, "invalid argument ", argN, ": ", __VA_ARGS__)#ifndef FATAL_IF#ifdef C10_USE_GLOG#define FATAL_IF(condition)                                           \  condition ? (void)0                                                 \            : ::c10::LoggerVoidify() &                                \          ::c10::MessageLogger(                                       \              ::c10::SourceLocation::current(), ::google::GLOG_FATAL) \              .stream()#else#define FATAL_IF(condition)                                        \  condition ? (void)0                                              \            : ::c10::LoggerVoidify() &                             \          ::c10::MessageLogger(                                    \              ::c10::SourceLocation::current(), ::c10::GLOG_FATAL) \              .stream()#endif#endif#ifndef NON_FATAL_IF#ifdef C10_USE_GLOG#define NON_FATAL_IF(condition)                                              \  condition ? (void)0                                                        \            : ::c10::LoggerVoidify() &                                       \          ::c10::MessageLogger(                                              \              ::c10::SourceLocation::current(), ::google::GLOG_FATAL, false) \              .stream()#else#define NON_FATAL_IF(condition)                                           \  condition ? (void)0                                                     \            : ::c10::LoggerVoidify() &                                    \          ::c10::MessageLogger(                                           \              ::c10::SourceLocation::current(), ::c10::GLOG_FATAL, false) \              .stream()#endif#endif// Binary comparison check macros#define TORCH_CHECK_OP(val1, val2, op)                                      \  NON_FATAL_IF(((val1)op(val2)))                                            \      << "Check failed: " #val1 " " #op " " #val2 " (" << (val1) << " vs. " \      << (val2) << "). "#define TORCH_DCHECK_OP(val1, val2, op)                                       \  FATAL_IF(((val1)op(val2))) << "Check failed: " #val1 " " #op " " #val2 " (" \                             << (val1) << " vs. " << (val2) << "). "#define TORCH_CHECK_EQ(val1, val2) TORCH_CHECK_OP(val1, val2, ==)#define TORCH_CHECK_NE(val1, val2) TORCH_CHECK_OP(val1, val2, !=)#define TORCH_CHECK_LE(val1, val2) TORCH_CHECK_OP(val1, val2, <=)#define TORCH_CHECK_LT(val1, val2) TORCH_CHECK_OP(val1, val2, <)#define TORCH_CHECK_GE(val1, val2) TORCH_CHECK_OP(val1, val2, >=)#define TORCH_CHECK_GT(val1, val2) TORCH_CHECK_OP(val1, val2, >)// Debug versions of TORCH_CHECK_OP macros#ifndef NDEBUG#define TORCH_DCHECK_EQ(val1, val2) TORCH_DCHECK_OP(val1, val2, ==)#define TORCH_DCHECK_NE(val1, val2) TORCH_DCHECK_OP(val1, val2, !=)#define TORCH_DCHECK_LE(val1, val2) TORCH_DCHECK_OP(val1, val2, <=)#define TORCH_DCHECK_LT(val1, val2) TORCH_DCHECK_OP(val1, val2, <)#define TORCH_DCHECK_GE(val1, val2) TORCH_DCHECK_OP(val1, val2, >=)#define TORCH_DCHECK_GT(val1, val2) TORCH_DCHECK_OP(val1, val2, >)#else// !NDEBUG// Optimized versions - generate no code#define TORCH_DCHECK_EQ(val1, val2) \  while (false)                     \  TORCH_DCHECK_OP(val1, val2, ==)#define TORCH_DCHECK_NE(val1, val2) \  while (false)                     \  TORCH_DCHECK_OP(val1, val2, !=)#define TORCH_DCHECK_LE(val1, val2) \  while (false)                     \  TORCH_DCHECK_OP(val1, val2, <=)#define TORCH_DCHECK_LT(val1, val2) \  while (false)                     \  TORCH_DCHECK_OP(val1, val2, <)#define TORCH_DCHECK_GE(val1, val2) \  while (false)                     \  TORCH_DCHECK_OP(val1, val2, >=)#define TORCH_DCHECK_GT(val1, val2) \  while (false)                     \  TORCH_DCHECK_OP(val1, val2, >)#endif// NDEBUG// Null pointer check macro#define TORCH_CHECK_NOTNULL(val) \  ::c10::CheckNotNull(__FILE__, __LINE__, #val, (val), false)#ifndef NDEBUG#define TORCH_DCHECK_NOTNULL(val) \  ::c10::CheckNotNull(__FILE__, __LINE__, #val, (val), true)#else// !NDEBUG#define TORCH_DCHECK_NOTNULL(val) \  while (false)                   \  TORCH_CHECK_NOTNULL(val)#endif// NDEBUG// ----------------------------------------------------------------------------// Deprecated macros// ----------------------------------------------------------------------------namespacec10::detail{/*// Deprecation disabled until we fix sites in our codebase[[deprecated("AT_ERROR(msg) is deprecated, use TORCH_CHECK(false, msg)instead.")]]*/inlinevoiddeprecated_AT_ERROR(){}/*// Deprecation disabled until we fix sites in our codebase[[deprecated("AT_ASSERT is deprecated, if you mean to indicate aninternal invariant failure, use " \                       "TORCH_INTERNAL_ASSERT instead; if you mean to do usererror checking, use " \ "TORCH_CHECK.  Seehttps://github.com/pytorch/pytorch/issues/20287 for more details.")]]*/inlinevoiddeprecated_AT_ASSERT(){}/*// Deprecation disabled until we fix sites in our codebase[[deprecated("AT_ASSERTM is deprecated, if you mean to indicate aninternal invariant failure, use " \                       "TORCH_INTERNAL_ASSERT instead; if you mean to do usererror checking, use " \ "TORCH_CHECK.  Seehttps://github.com/pytorch/pytorch/issues/20287 for more details.")]]*/inlinevoiddeprecated_AT_ASSERTM(){}}// namespace c10::detail// Deprecated alias; this alias was deprecated because people kept mistakenly// using it for user error checking.  Use TORCH_INTERNAL_ASSERT or TORCH_CHECK// instead. See https://github.com/pytorch/pytorch/issues/20287 for more// details.#define AT_ASSERT(...)                                              \  do {                                                              \    ::c10::detail::deprecated_AT_ASSERT();                          \    C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(__VA_ARGS__)); \  } while (false)// Deprecated alias, like AT_ASSERT.  The new TORCH_INTERNAL_ASSERT macro// supports both 0-ary and variadic calls, so having a separate// message-accepting macro is not necessary.//// NB: we MUST include cond explicitly here, as MSVC will miscompile the macro// expansion, shunting all of __VA_ARGS__ to cond.  An alternate workaround// can be seen at// https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly#define AT_ASSERTM(cond, ...)                                             \  do {                                                                    \    ::c10::detail::deprecated_AT_ASSERTM();                               \    C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(cond, __VA_ARGS__)); \  } while (false)// Deprecated alias; this alias was deprecated because it represents extra API// surface that makes it hard for people to understand what macro to use.// Use TORCH_CHECK(false, ...) or TORCH_INTERNAL_ASSERT(false, ...) to// unconditionally fail at a line of code.#define AT_ERROR(...)                                                        \  do {                                                                       \    ::c10::detail::deprecated_AT_ERROR();                                    \    C10_EXPAND_MSVC_WORKAROUND(TORCH_CHECK(false, ::c10::str(__VA_ARGS__))); \  } while (false)#endif// C10_UTIL_EXCEPTION_H_