Skip to content

Commit

Permalink
[PyTorch] Make TORCH_CHECK less likely to interfere with inlining (#4…
Browse files Browse the repository at this point in the history
…9263)

Summary:
Pull Request resolved: #49263

Now it is smaller and calls to an out-of-line function in
case of failure.
ghstack-source-id: 118480531

Test Plan:
1) Inspect perf profile of internal benchmark, much less
time spent in (for example) `c10::impl::getDeviceImpl`, which calls
TORCH_CHECK and should be inlined
2) Internal benchmarks

Reviewed By: smessmer

Differential Revision: D25481308

fbshipit-source-id: 0121ada779ca2518ca717f75920420957b3bb1aa
  • Loading branch information
swolchok authored and facebook-github-bot committed Dec 14, 2020
1 parent eb051af commit 7d406b4
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 14 deletions.
8 changes: 8 additions & 0 deletions c10/util/Exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ void Error::add_context(std::string new_msg) {
refresh_what();
}

namespace detail {

void torchCheckFail(const char *func, const char *file, uint32_t line, const std::string& msg) {
throw ::c10::Error({func, file, line}, msg);
}

} // namespace detail

namespace Warning {

namespace {
Expand Down
46 changes: 32 additions & 14 deletions c10/util/Exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ C10_API std::string GetExceptionString(const std::exception& e);
namespace detail {

// Return x if it is non-empty; otherwise return y.
inline std::string if_empty_then(std::string x, std::string y) {
inline std::string if_empty_then(const std::string& x, const std::string& y) {
if (x.empty()) {
return y;
} else {
Expand Down Expand Up @@ -324,27 +324,45 @@ inline std::string if_empty_then(std::string x, std::string y) {
TORCH_CHECK_WITH_MSG(error_t, cond, "", __VA_ARGS__)

#ifdef STRIP_ERROR_MESSAGES
#define TORCH_CHECK_WITH_MSG(error_t, cond, type, ...) \
if (C10_UNLIKELY_OR_CONST(!(cond))) { \
C10_THROW_ERROR(Error, \
#cond #type " CHECK FAILED at " \
C10_STRINGIZE(__FILE__) \
); \
#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__) \
); \
}
#else
#define TORCH_CHECK_MSG(cond, type, ...) \
::c10::detail::if_empty_then( \
::c10::str(__VA_ARGS__), \
"Expected " #cond " to be true, but got false. " \
"(Could this error message be improved? If so, " \
"please report an enhancement request to PyTorch.)" \
)
#define TORCH_CHECK_WITH_MSG(error_t, cond, type, ...) \
if (C10_UNLIKELY_OR_CONST(!(cond))) { \
C10_THROW_ERROR(error_t, \
::c10::detail::if_empty_then( \
::c10::str(__VA_ARGS__), \
"Expected " #cond " to be true, but got false. " \
"(Could this error message be improved? If so, " \
"please report an enhancement request to PyTorch.)" \
) \
TORCH_CHECK_MSG(cond, type, __VA_ARGS__) \
); \
}
#endif
#define TORCH_CHECK(cond, ...) TORCH_CHECK_WITH(Error, cond, __VA_ARGS__)

namespace c10 {
namespace detail {

[[noreturn]] C10_API void torchCheckFail(const char *func, const char *file, uint32_t line, const std::string& msg);

} // namespace detail
} // namespace 10

#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__)); \
}

// 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
Expand Down

0 comments on commit 7d406b4

Please sign in to comment.