Loading...
Searching...
No Matches
detail/error.hpp
1/*
2 * SPDX-FileCopyrightText: Copyright (c) 2020-2026, NVIDIA CORPORATION.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#pragma once
7
8#include <rmm/error.hpp>
9
10#include <cuda_runtime_api.h>
11
12#include <cassert>
13#include <exception>
14#include <iostream>
15#include <string>
16#include <type_traits>
17
18#define STRINGIFY_DETAIL(x) #x
19#define RMM_STRINGIFY(x) STRINGIFY_DETAIL(x)
20
45#define RMM_EXPECTS(...) \
46 GET_RMM_EXPECTS_MACRO(__VA_ARGS__, RMM_EXPECTS_3, RMM_EXPECTS_2) \
47 (__VA_ARGS__)
48#define GET_RMM_EXPECTS_MACRO(_1, _2, _3, NAME, ...) NAME
49#define RMM_EXPECTS_3(_condition, _reason, _exception_type) \
50 do { \
51 static_assert(std::is_base_of_v<std::exception, _exception_type>); \
52 /*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \
53 (!!(_condition)) ? static_cast<void>(0) \
54 : throw _exception_type{std::string{"RMM failure at: "} + __FILE__ + ":" + \
55 RMM_STRINGIFY(__LINE__) + ": " + _reason}; \
56 } while (0)
57#define RMM_EXPECTS_2(_condition, _reason) RMM_EXPECTS_3(_condition, _reason, rmm::logic_error)
58
71#define RMM_FAIL(...) \
72 GET_RMM_FAIL_MACRO(__VA_ARGS__, RMM_FAIL_2, RMM_FAIL_1) \
73 (__VA_ARGS__)
74#define GET_RMM_FAIL_MACRO(_1, _2, NAME, ...) NAME
75#define RMM_FAIL_2(_what, _exception_type) \
76 /*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \
77 throw _exception_type \
78 { \
79 std::string{"RMM failure at:"} + __FILE__ + ":" + RMM_STRINGIFY(__LINE__) + ": " + _what \
80 }
81#define RMM_FAIL_1(_what) RMM_FAIL_2(_what, rmm::logic_error)
82
103#define RMM_CUDA_TRY(...) \
104 GET_RMM_CUDA_TRY_MACRO(__VA_ARGS__, RMM_CUDA_TRY_2, RMM_CUDA_TRY_1) \
105 (__VA_ARGS__)
106#define GET_RMM_CUDA_TRY_MACRO(_1, _2, NAME, ...) NAME
107#define RMM_CUDA_TRY_2(_call, _exception_type) \
108 do { \
109 cudaError_t const error = (_call); \
110 if (cudaSuccess != error) { \
111 cudaGetLastError(); \
112 /*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \
113 throw _exception_type{std::string{"CUDA error at: "} + __FILE__ + ":" + \
114 RMM_STRINGIFY(__LINE__) + ": " + cudaGetErrorName(error) + " " + \
115 cudaGetErrorString(error)}; \
116 } \
117 } while (0)
118#define RMM_CUDA_TRY_1(_call) RMM_CUDA_TRY_2(_call, rmm::cuda_error)
119
134#define RMM_CUDA_TRY_ALLOC(...) \
135 GET_RMM_CUDA_TRY_ALLOC_MACRO(__VA_ARGS__, RMM_CUDA_TRY_ALLOC_2, RMM_CUDA_TRY_ALLOC_1) \
136 (__VA_ARGS__)
137#define GET_RMM_CUDA_TRY_ALLOC_MACRO(_1, _2, NAME, ...) NAME
138
139#define RMM_CUDA_TRY_ALLOC_2(_call, num_bytes) \
140 do { \
141 cudaError_t const error = (_call); \
142 if (cudaSuccess != error) { \
143 cudaGetLastError(); \
144 auto const msg = std::string{"CUDA error (failed to allocate "} + \
145 std::to_string(num_bytes) + " bytes) at: " + __FILE__ + ":" + \
146 RMM_STRINGIFY(__LINE__) + ": " + cudaGetErrorName(error) + " " + \
147 cudaGetErrorString(error); \
148 if (cudaErrorMemoryAllocation == error) { throw rmm::out_of_memory{msg}; } \
149 throw rmm::bad_alloc{msg}; \
150 } \
151 } while (0)
152
153#define RMM_CUDA_TRY_ALLOC_1(_call) \
154 do { \
155 cudaError_t const error = (_call); \
156 if (cudaSuccess != error) { \
157 cudaGetLastError(); \
158 auto const msg = std::string{"CUDA error at: "} + __FILE__ + ":" + RMM_STRINGIFY(__LINE__) + \
159 ": " + cudaGetErrorName(error) + " " + cudaGetErrorString(error); \
160 if (cudaErrorMemoryAllocation == error) { throw rmm::out_of_memory{msg}; } \
161 throw rmm::bad_alloc{msg}; \
162 } \
163 } while (0)
164
191#ifdef NDEBUG
192#define RMM_ASSERT_CUDA_SUCCESS(_call) \
193 do { \
194 (_call); \
195 } while (0);
196#else
197#define RMM_ASSERT_CUDA_SUCCESS(_call) \
198 do { \
199 cudaError_t const status__ = (_call); \
200 if (status__ != cudaSuccess) { \
201 std::cerr << "CUDA Error detected. " << cudaGetErrorName(status__) << " " \
202 << cudaGetErrorString(status__) << std::endl; \
203 } \
204 /* NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) */ \
205 assert(status__ == cudaSuccess); \
206 } while (0)
207#endif
208
228#ifdef NDEBUG
229#define RMM_ASSERT_CUDA_SUCCESS_SAFE_SHUTDOWN(_call) \
230 do { \
231 (_call); \
232 } while (0);
233#else
234#define RMM_ASSERT_CUDA_SUCCESS_SAFE_SHUTDOWN(_call) \
235 do { \
236 cudaError_t const status__ = (_call); \
237 if (status__ != cudaSuccess && status__ != cudaErrorCudartUnloading) { \
238 std::cerr << "CUDA Error detected. " << cudaGetErrorName(status__) << " " \
239 << cudaGetErrorString(status__) << std::endl; \
240 } \
241 /* NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) */ \
242 assert(status__ == cudaSuccess || status__ == cudaErrorCudartUnloading); \
243 } while (0)
244#endif