11 #include <system_error>
13 #include <kvikio/shim/cuda.hpp>
14 #include <kvikio/shim/cufile_h_wrapper.hpp>
19 using std::runtime_error::runtime_error;
33 #ifndef CUDA_DRIVER_TRY
59 #define CUDA_DRIVER_TRY(...) \
60 GET_CUDA_DRIVER_TRY_MACRO(__VA_ARGS__, CUDA_DRIVER_TRY_2, CUDA_DRIVER_TRY_1) \
64 #define GET_CUDA_DRIVER_TRY_MACRO(_1, _2, NAME, ...) NAME
65 #define CUDA_DRIVER_TRY_2(_call, _exception_type) \
67 kvikio::detail::cuda_driver_try_2<_exception_type>(_call, __LINE__, __FILE__); \
69 #define CUDA_DRIVER_TRY_1(_call) CUDA_DRIVER_TRY_2(_call, kvikio::CUfileException)
98 #define CUFILE_TRY(...) \
99 GET_CUFILE_TRY_MACRO(__VA_ARGS__, CUFILE_TRY_2, CUFILE_TRY_1) \
103 #define GET_CUFILE_TRY_MACRO(_1, _2, NAME, ...) NAME
104 #define CUFILE_TRY_2(_call, _exception_type) \
106 kvikio::detail::cufile_try_2<_exception_type>(_call, __LINE__, __FILE__); \
108 #define CUFILE_TRY_1(_call) CUFILE_TRY_2(_call, kvikio::CUfileException)
111 #ifndef CUFILE_CHECK_BYTES_DONE
112 #define CUFILE_CHECK_BYTES_DONE(...) \
113 GET_CUFILE_CHECK_BYTES_DONE_MACRO( \
114 __VA_ARGS__, CUFILE_CHECK_BYTES_DONE_2, CUFILE_CHECK_BYTES_DONE_1) \
116 #define GET_CUFILE_CHECK_BYTES_DONE_MACRO(_1, _2, NAME, ...) NAME
117 #define CUFILE_CHECK_BYTES_DONE_2(_nbytes_done, _exception_type) \
119 kvikio::detail::cufile_check_bytes_done_2<_exception_type>(_nbytes_done, __LINE__, __FILE__); \
121 #define CUFILE_CHECK_BYTES_DONE_1(_call) CUFILE_CHECK_BYTES_DONE_2(_call, kvikio::CUfileException)
125 template <
typename Exception>
126 void cuda_driver_try_2(CUresult error,
int line_number,
char const* filename)
128 if (error == CUDA_ERROR_STUB_LIBRARY) {
129 throw Exception{std::string{
"CUDA error at: "} + std::string(filename) +
":" +
130 std::to_string(line_number) +
131 ": CUDA_ERROR_STUB_LIBRARY("
132 "The CUDA driver loaded is a stub library)"};
134 if (error != CUDA_SUCCESS) {
135 char const* err_name =
nullptr;
136 char const* err_str =
nullptr;
137 CUresult err_name_status = cudaAPI::instance().GetErrorName(error, &err_name);
138 CUresult err_str_status = cudaAPI::instance().GetErrorString(error, &err_str);
139 if (err_name_status == CUDA_ERROR_INVALID_VALUE) { err_name =
"unknown"; }
140 if (err_str_status == CUDA_ERROR_INVALID_VALUE) { err_str =
"unknown"; }
141 throw Exception{std::string{
"CUDA error at: "} + filename +
":" + std::to_string(line_number) +
142 ": " + std::string(err_name) +
"(" + std::string(err_str) +
")"};
146 template <
typename Exception>
147 void cufile_try_2(
CUfileError_t error,
int line_number,
char const* filename)
149 if (error.err != CU_FILE_SUCCESS) {
150 if (error.err == CU_FILE_CUDA_DRIVER_ERROR) {
151 CUresult
const cuda_error = error.cu_err;
154 throw Exception{std::string{
"cuFile error at: "} + filename +
":" +
155 std::to_string(line_number) +
": " +
156 cufileop_status_error((CUfileOpError)std::abs(error.err))};
160 template <
typename Exception>
161 void cufile_check_bytes_done_2(ssize_t nbytes_done,
int line_number,
char const* filename)
163 if (nbytes_done < 0) {
164 auto const err = std::abs(nbytes_done);
165 auto const msg = (err > CUFILEOP_BASE_ERR)
166 ? std::string(cufileop_status_error((CUfileOpError)err))
167 : std::string(std::strerror(err));
168 throw Exception{std::string{
"cuFile error at: "} + filename +
":" +
169 std::to_string(line_number) +
": " + msg};
173 #define KVIKIO_LOG_ERROR(err_msg) kvikio::detail::log_error(err_msg, __LINE__, __FILE__)
174 void log_error(std::string_view err_msg,
int line_number,
char const* filename);
207 #define KVIKIO_EXPECT(...) \
208 GET_KVIKIO_EXPECT_MACRO(__VA_ARGS__, KVIKIO_EXPECT_3, KVIKIO_EXPECT_2)(__VA_ARGS__)
211 #define GET_KVIKIO_EXPECT_MACRO(_1, _2, _3, NAME, ...) NAME
213 #define KVIKIO_EXPECT_3(_condition, _msg, _exception_type) \
215 kvikio::detail::kvikio_assertion<_exception_type>(_condition, _msg, __LINE__, __FILE__); \
218 #define KVIKIO_EXPECT_2(_condition, _msg) KVIKIO_EXPECT_3(_condition, _msg, kvikio::CUfileException)
243 #define KVIKIO_FAIL(...) \
244 GET_KVIKIO_FAIL_MACRO(__VA_ARGS__, KVIKIO_FAIL_2, KVIKIO_FAIL_1)(__VA_ARGS__)
247 #define GET_KVIKIO_FAIL_MACRO(_1, _2, NAME, ...) NAME
249 #define KVIKIO_FAIL_2(_msg, _exception_type) \
251 kvikio::detail::kvikio_assertion<_exception_type>(false, _msg, __LINE__, __FILE__); \
254 #define KVIKIO_FAIL_1(_msg) KVIKIO_FAIL_2(_msg, kvikio::CUfileException)
257 template <
typename Exception>
258 void kvikio_assertion(
bool condition,
const char* msg,
int line_number,
char const* filename)
261 std::stringstream ss;
262 ss <<
"KvikIO failure at: " << filename <<
":" << line_number <<
": ";
263 if (msg ==
nullptr) {
264 ss <<
"(no message)";
268 throw Exception{ss.str()};
272 template <
typename Exception>
273 void kvikio_assertion(
bool condition,
const std::string& msg,
int line_number,
char const* filename)
275 kvikio_assertion<Exception>(condition, msg.c_str(), line_number, filename);
317 #define SYSCALL_CHECK(...) \
318 GET_SYSCALL_CHECK_MACRO(__VA_ARGS__, SYSCALL_CHECK_3, SYSCALL_CHECK_2, SYSCALL_CHECK_1) \
322 #define GET_SYSCALL_CHECK_MACRO(_1, _2, _3, NAME, ...) NAME
323 #define SYSCALL_CHECK_1(_return_value) \
325 kvikio::detail::check_linux_call(__LINE__, __FILE__, _return_value); \
327 #define SYSCALL_CHECK_2(_return_value, _extra_msg) \
329 kvikio::detail::check_linux_call(__LINE__, __FILE__, _return_value, _extra_msg); \
331 #define SYSCALL_CHECK_3(_return_value, _extra_msg, _error_value) \
333 kvikio::detail::check_linux_call(__LINE__, __FILE__, _return_value, _extra_msg, _error_value); \
337 void handle_linux_call_error(
int line_number,
char const* filename, std::string_view extra_msg);
339 inline void check_linux_call(
int line_number,
340 char const* filename,
342 std::string_view extra_msg =
"",
343 int error_value = -1)
345 if (return_value == error_value) { handle_linux_call_error(line_number, filename, extra_msg); }
348 template <
typename T>
349 void check_linux_call(
350 int line_number,
char const* filename, T return_value, std::string_view extra_msg, T error_value)
352 if (return_value == error_value) { handle_linux_call_error(line_number, filename, extra_msg); }
#define CUDA_DRIVER_TRY(...)
Error checking macro for CUDA driver API functions.