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;
31 #ifndef CUDA_DRIVER_TRY
57 #define CUDA_DRIVER_TRY(...) \
58 GET_CUDA_DRIVER_TRY_MACRO(__VA_ARGS__, CUDA_DRIVER_TRY_2, CUDA_DRIVER_TRY_1) \
62 #define GET_CUDA_DRIVER_TRY_MACRO(_1, _2, NAME, ...) NAME
63 #define CUDA_DRIVER_TRY_2(_call, _exception_type) \
65 kvikio::detail::cuda_driver_try_2<_exception_type>(_call, __LINE__, __FILE__); \
67 #define CUDA_DRIVER_TRY_1(_call) CUDA_DRIVER_TRY_2(_call, kvikio::CUfileException)
96 #define CUFILE_TRY(...) \
97 GET_CUFILE_TRY_MACRO(__VA_ARGS__, CUFILE_TRY_2, CUFILE_TRY_1) \
101 #define GET_CUFILE_TRY_MACRO(_1, _2, NAME, ...) NAME
102 #define CUFILE_TRY_2(_call, _exception_type) \
104 kvikio::detail::cufile_try_2<_exception_type>(_call, __LINE__, __FILE__); \
106 #define CUFILE_TRY_1(_call) CUFILE_TRY_2(_call, kvikio::CUfileException)
109 #ifndef CUFILE_CHECK_BYTES_DONE
110 #define CUFILE_CHECK_BYTES_DONE(...) \
111 GET_CUFILE_CHECK_BYTES_DONE_MACRO( \
112 __VA_ARGS__, CUFILE_CHECK_BYTES_DONE_2, CUFILE_CHECK_BYTES_DONE_1) \
114 #define GET_CUFILE_CHECK_BYTES_DONE_MACRO(_1, _2, NAME, ...) NAME
115 #define CUFILE_CHECK_BYTES_DONE_2(_nbytes_done, _exception_type) \
117 kvikio::detail::cufile_check_bytes_done_2<_exception_type>(_nbytes_done, __LINE__, __FILE__); \
119 #define CUFILE_CHECK_BYTES_DONE_1(_call) CUFILE_CHECK_BYTES_DONE_2(_call, kvikio::CUfileException)
123 template <
typename Exception>
124 void cuda_driver_try_2(CUresult error,
int line_number,
char const* filename)
126 if (error == CUDA_ERROR_STUB_LIBRARY) {
127 throw Exception{std::string{
"CUDA error at: "} + std::string(filename) +
":" +
128 std::to_string(line_number) +
129 ": CUDA_ERROR_STUB_LIBRARY("
130 "The CUDA driver loaded is a stub library)"};
132 if (error != CUDA_SUCCESS) {
133 char const* err_name =
nullptr;
134 char const* err_str =
nullptr;
135 CUresult err_name_status = cudaAPI::instance().GetErrorName(error, &err_name);
136 CUresult err_str_status = cudaAPI::instance().GetErrorString(error, &err_str);
137 if (err_name_status == CUDA_ERROR_INVALID_VALUE) { err_name =
"unknown"; }
138 if (err_str_status == CUDA_ERROR_INVALID_VALUE) { err_str =
"unknown"; }
139 throw Exception{std::string{
"CUDA error at: "} + filename +
":" + std::to_string(line_number) +
140 ": " + std::string(err_name) +
"(" + std::string(err_str) +
")"};
144 template <
typename Exception>
145 void cufile_try_2(
CUfileError_t error,
int line_number,
char const* filename)
147 if (error.err != CU_FILE_SUCCESS) {
148 if (error.err == CU_FILE_CUDA_DRIVER_ERROR) {
149 CUresult
const cuda_error = error.cu_err;
152 throw Exception{std::string{
"cuFile error at: "} + filename +
":" +
153 std::to_string(line_number) +
": " +
154 cufileop_status_error((CUfileOpError)std::abs(error.err))};
158 template <
typename Exception>
159 void cufile_check_bytes_done_2(ssize_t nbytes_done,
int line_number,
char const* filename)
161 if (nbytes_done < 0) {
162 auto const err = std::abs(nbytes_done);
163 auto const msg = (err > CUFILEOP_BASE_ERR)
164 ? std::string(cufileop_status_error((CUfileOpError)err))
165 : std::string(std::strerror(err));
166 throw Exception{std::string{
"cuFile error at: "} + filename +
":" +
167 std::to_string(line_number) +
": " + msg};
171 #define KVIKIO_LOG_ERROR(err_msg) kvikio::detail::log_error(err_msg, __LINE__, __FILE__)
172 void log_error(std::string_view err_msg,
int line_number,
char const* filename);
205 #define KVIKIO_EXPECT(...) \
206 GET_KVIKIO_EXPECT_MACRO(__VA_ARGS__, KVIKIO_EXPECT_3, KVIKIO_EXPECT_2)(__VA_ARGS__)
209 #define GET_KVIKIO_EXPECT_MACRO(_1, _2, _3, NAME, ...) NAME
211 #define KVIKIO_EXPECT_3(_condition, _msg, _exception_type) \
213 kvikio::detail::kvikio_assertion<_exception_type>(_condition, _msg, __LINE__, __FILE__); \
216 #define KVIKIO_EXPECT_2(_condition, _msg) KVIKIO_EXPECT_3(_condition, _msg, kvikio::CUfileException)
241 #define KVIKIO_FAIL(...) \
242 GET_KVIKIO_FAIL_MACRO(__VA_ARGS__, KVIKIO_FAIL_2, KVIKIO_FAIL_1)(__VA_ARGS__)
245 #define GET_KVIKIO_FAIL_MACRO(_1, _2, NAME, ...) NAME
247 #define KVIKIO_FAIL_2(_msg, _exception_type) \
249 kvikio::detail::kvikio_assertion<_exception_type>(false, _msg, __LINE__, __FILE__); \
252 #define KVIKIO_FAIL_1(_msg) KVIKIO_FAIL_2(_msg, kvikio::CUfileException)
255 template <
typename Exception>
256 void kvikio_assertion(
bool condition,
const char* msg,
int line_number,
char const* filename)
259 std::stringstream ss;
260 ss <<
"KvikIO failure at: " << filename <<
":" << line_number <<
": ";
261 if (msg ==
nullptr) {
262 ss <<
"(no message)";
266 throw Exception{ss.str()};
270 template <
typename Exception>
271 void kvikio_assertion(
bool condition,
const std::string& msg,
int line_number,
char const* filename)
273 kvikio_assertion<Exception>(condition, msg.c_str(), line_number, filename);
315 #define SYSCALL_CHECK(...) \
316 GET_SYSCALL_CHECK_MACRO(__VA_ARGS__, SYSCALL_CHECK_3, SYSCALL_CHECK_2, SYSCALL_CHECK_1) \
320 #define GET_SYSCALL_CHECK_MACRO(_1, _2, _3, NAME, ...) NAME
321 #define SYSCALL_CHECK_1(_return_value) \
323 kvikio::detail::check_linux_call(__LINE__, __FILE__, _return_value); \
325 #define SYSCALL_CHECK_2(_return_value, _extra_msg) \
327 kvikio::detail::check_linux_call(__LINE__, __FILE__, _return_value, _extra_msg); \
329 #define SYSCALL_CHECK_3(_return_value, _extra_msg, _error_value) \
331 kvikio::detail::check_linux_call(__LINE__, __FILE__, _return_value, _extra_msg, _error_value); \
335 void handle_linux_call_error(
int line_number,
char const* filename, std::string_view extra_msg);
337 inline void check_linux_call(
int line_number,
338 char const* filename,
340 std::string_view extra_msg =
"",
341 int error_value = -1)
343 if (return_value == error_value) { handle_linux_call_error(line_number, filename, extra_msg); }
346 template <
typename T>
347 void check_linux_call(
348 int line_number,
char const* filename, T return_value, std::string_view extra_msg, T error_value)
350 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.