All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
detail/error.hpp
1 /*
2  * Copyright (c) 2020-2024, NVIDIA CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <rmm/error.hpp>
20 
21 #include <cuda_runtime_api.h>
22 
23 #include <cassert>
24 #include <iostream>
25 #include <string>
26 
27 #define STRINGIFY_DETAIL(x) #x
28 #define RMM_STRINGIFY(x) STRINGIFY_DETAIL(x)
29 
54 #define RMM_EXPECTS(...) \
55  GET_RMM_EXPECTS_MACRO(__VA_ARGS__, RMM_EXPECTS_3, RMM_EXPECTS_2) \
56  (__VA_ARGS__)
57 #define GET_RMM_EXPECTS_MACRO(_1, _2, _3, NAME, ...) NAME
58 #define RMM_EXPECTS_3(_condition, _reason, _exception_type) \
59  (!!(_condition)) ? static_cast<void>(0) \
60  : throw _exception_type /*NOLINT(bugprone-macro-parentheses)*/ \
61  { \
62  "RMM failure at: " __FILE__ ":" RMM_STRINGIFY(__LINE__) ": " _reason \
63  }
64 #define RMM_EXPECTS_2(_condition, _reason) RMM_EXPECTS_3(_condition, _reason, rmm::logic_error)
65 
78 #define RMM_FAIL(...) \
79  GET_RMM_FAIL_MACRO(__VA_ARGS__, RMM_FAIL_2, RMM_FAIL_1) \
80  (__VA_ARGS__)
81 #define GET_RMM_FAIL_MACRO(_1, _2, NAME, ...) NAME
82 #define RMM_FAIL_2(_what, _exception_type) \
83  /*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \
84  throw _exception_type{"RMM failure at:" __FILE__ ":" RMM_STRINGIFY(__LINE__) ": " _what};
85 #define RMM_FAIL_1(_what) RMM_FAIL_2(_what, rmm::logic_error)
86 
108 #define RMM_CUDA_TRY(...) \
109  GET_RMM_CUDA_TRY_MACRO(__VA_ARGS__, RMM_CUDA_TRY_2, RMM_CUDA_TRY_1) \
110  (__VA_ARGS__)
111 #define GET_RMM_CUDA_TRY_MACRO(_1, _2, NAME, ...) NAME
112 #define RMM_CUDA_TRY_2(_call, _exception_type) \
113  do { \
114  cudaError_t const error = (_call); \
115  if (cudaSuccess != error) { \
116  cudaGetLastError(); \
117  /*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \
118  throw _exception_type{std::string{"CUDA error at: "} + __FILE__ + ":" + \
119  RMM_STRINGIFY(__LINE__) + ": " + cudaGetErrorName(error) + " " + \
120  cudaGetErrorString(error)}; \
121  } \
122  } while (0)
123 #define RMM_CUDA_TRY_1(_call) RMM_CUDA_TRY_2(_call, rmm::cuda_error)
124 
135 #define RMM_CUDA_TRY_ALLOC(_call) \
136  do { \
137  cudaError_t const error = (_call); \
138  if (cudaSuccess != error) { \
139  cudaGetLastError(); \
140  auto const msg = std::string{"CUDA error at: "} + __FILE__ + ":" + RMM_STRINGIFY(__LINE__) + \
141  ": " + cudaGetErrorName(error) + " " + cudaGetErrorString(error); \
142  if (cudaErrorMemoryAllocation == error) { throw rmm::out_of_memory{msg}; } \
143  throw rmm::bad_alloc{msg}; \
144  } \
145  } while (0)
146 
172 #ifdef NDEBUG
173 #define RMM_ASSERT_CUDA_SUCCESS(_call) \
174  do { \
175  (_call); \
176  } while (0);
177 #else
178 #define RMM_ASSERT_CUDA_SUCCESS(_call) \
179  do { \
180  cudaError_t const status__ = (_call); \
181  if (status__ != cudaSuccess) { \
182  std::cerr << "CUDA Error detected. " << cudaGetErrorName(status__) << " " \
183  << cudaGetErrorString(status__) << std::endl; \
184  } \
185  /* NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) */ \
186  assert(status__ == cudaSuccess); \
187  } while (0)
188 #endif