cuda-api-wrappers
Thin C++-flavored wrappers for the CUDA Runtime API
error.hpp
Go to the documentation of this file.
1 
8 #pragma once
9 #ifndef CUDA_API_WRAPPERS_FATBIN_BUILDER_ERROR_HPP_
10 #define CUDA_API_WRAPPERS_FATBIN_BUILDER_ERROR_HPP_
11 
12 #include "types.hpp"
13 
14 #include <nvFatbin.h>
15 
16 #include <type_traits>
17 #include <string>
18 #include <stdexcept>
19 
20 #if CUDA_VERSION >= 12040
21 
22 namespace cuda {
23 
24 namespace fatbin_builder {
25 
26 namespace status {
27 
28 enum named_t : ::std::underlying_type<status_t>::type {
29  success = NVFATBIN_SUCCESS,
30  other_internal_error = NVFATBIN_ERROR_INTERNAL,
31  elf_architecture_mismatch = NVFATBIN_ERROR_ELF_ARCH_MISMATCH,
32  elf_architecture_size = NVFATBIN_ERROR_ELF_SIZE_MISMATCH,
33  missing_ptx_version = NVFATBIN_ERROR_MISSING_PTX_VERSION,
34  unexpected_null_pointer = NVFATBIN_ERROR_NULL_POINTER,
35  data_compression_failed = NVFATBIN_ERROR_COMPRESSION_FAILED,
36  maximum_compressed_size_exceeded = NVFATBIN_ERROR_COMPRESSED_SIZE_EXCEEDED,
37  unrecognized_option = NVFATBIN_ERROR_UNRECOGNIZED_OPTION,
38  invalid_architecture = NVFATBIN_ERROR_INVALID_ARCH,
39  invalid_ltoir_data = NVFATBIN_ERROR_INVALID_NVVM,
40  invalid_nnvm_data = NVFATBIN_ERROR_INVALID_NVVM, // Note alias to same value
41  empty_input = NVFATBIN_ERROR_EMPTY_INPUT,
42 #if CUDA_VERSION >= 12050
43  missing_ptx_architecture = NVFATBIN_ERROR_MISSING_PTX_ARCH,
44  ptx_architecture_mismatch = NVFATBIN_ERROR_PTX_ARCH_MISMATCH,
45  missing_fatbin = NVFATBIN_ERROR_MISSING_FATBIN,
46  invalid_index = NVFATBIN_ERROR_INVALID_INDEX,
47  identifier_reused = NVFATBIN_ERROR_IDENTIFIER_REUSE,
48 #endif
49 #if CUDA_VERSION >= 12060
50  internal_ptx_option_related_error = NVFATBIN_ERROR_INTERNAL_PTX_OPTION
51 #endif
52 };
53 
55 constexpr bool operator==(const status_t& lhs, const named_t& rhs) { return lhs == static_cast<status_t>(rhs); }
56 constexpr bool operator!=(const status_t& lhs, const named_t& rhs) { return lhs != static_cast<status_t>(rhs); }
57 constexpr bool operator==(const named_t& lhs, const status_t& rhs) { return static_cast<status_t>(lhs) == rhs; }
58 constexpr bool operator!=(const named_t& lhs, const status_t& rhs) { return static_cast<status_t>(lhs) != rhs; }
60 
61 } // namespace status
62 
63 } // namespace fatbin_builder
64 
68 constexpr bool is_success(fatbin_builder::status_t status)
70 {
71  return (status == fatbin_builder::status::named_t::success);
72 }
74 
78 constexpr bool is_failure(fatbin_builder::status_t status)
79 {
80  return not is_success(status);
81 }
82 
87 inline ::std::string describe(fatbin_builder::status_t status)
89 {
90  return nvFatbinGetErrorString(status);
91 }
92 
93 namespace fatbin_builder {
94 
102 class runtime_error : public ::std::runtime_error {
103 public:
104  // TODO: Constructor chaining; and perhaps allow for more construction mechanisms?
105  runtime_error(status_t error_code) :
106  ::std::runtime_error(describe(error_code)),
107  code_(error_code)
108  { }
109  // I wonder if I should do this the other way around
110  runtime_error(status_t error_code, ::std::string what_arg) :
111  ::std::runtime_error(::std::move(what_arg) + ": " + describe(error_code)),
112  code_(error_code)
113  { }
114  runtime_error(status::named_t error_code) :
115  runtime_error(static_cast<status_t>(error_code)) { }
116  runtime_error(status::named_t error_code, const ::std::string& what_arg) :
117  runtime_error(static_cast<status_t>(error_code), what_arg) { }
118 
119 protected:
120  runtime_error(status_t error_code, ::std::runtime_error err) :
121  ::std::runtime_error(::std::move(err)), code_(error_code)
122  { }
123 
124 public:
125  static runtime_error with_message_override(status_t error_code, ::std::string complete_what_arg)
126  {
127  return runtime_error(error_code, ::std::runtime_error(complete_what_arg));
128  }
129 
133  status_t code() const { return code_; }
134 
135 private:
136  status_t code_;
137 };
138 
139 
140 } // namespace fatbin_builder
141 
142 // TODO: The following could use ::std::optional arguments - which would
143 // prevent the need for dual versions of the functions - but we're
144 // not writing C++17 here
145 
153 inline void throw_if_error(fatbin_builder::status_t status, const ::std::string& message) noexcept(false)
154 {
155  if (is_failure(status)) { throw fatbin_builder::runtime_error(status, message); }
156 }
157 
164 inline void throw_if_error(fatbin_builder::status_t status) noexcept(false)
165 {
166  if (is_failure(status)) { throw fatbin_builder::runtime_error(status); }
167 }
168 
178 #define throw_if_fatbin_builder_error_lazy(Kind, status__, ... ) \
179 do { \
180  ::cuda::fatbin_builder::status_t tie_status__ = static_cast<::cuda::fatbin_builder::status_t>(status__); \
181  if (::cuda::is_failure<Kind>(tie_status__)) { \
182  throw ::cuda::fatbin_builder::runtime_error<Kind>(tie_status__, (__VA_ARGS__)); \
183  } \
184 } while(false)
185 
186 } // namespace cuda
187 
188 #endif // CUDA_VERSION >= 12040
189 
190 #endif // CUDA_API_WRAPPERS_FATBIN_BUILDER_ERROR_HPP_
Definitions and functionality wrapping CUDA APIs.
Definition: array.hpp:22
constexpr bool is_failure(status_t status)
Determine whether the API call returning the specified status had failed.
Definition: error.hpp:209
STL namespace.
Type definitions used in CUDA real-time compilation work wrappers.
void throw_if_error(status_t status, const ::std::string &message) noexcept(false)
Do nothing...
Definition: error.hpp:335
named_t
Aliases for CUDA status codes.
Definition: error.hpp:36
inline ::std::string describe(status_t status)
Obtain a brief textual explanation for a specified kind of CUDA Runtime API status or error code...
Definition: error.hpp:215
bool operator==(const context_t &lhs, const context_t &rhs) noexcept
Definition: context.hpp:762
constexpr bool is_success(status_t status)
Determine whether the API call returning the specified status had succeeded.
Definition: error.hpp:203
CUresult status_t
Indicates either the result (success or error index) of a CUDA Runtime or Driver API call...
Definition: types.hpp:77