Exception.h 29 KB

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