Exception.h 26 KB

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