Skip to main content

singe_cuda/
error.rs

1#![allow(deprecated)]
2
3use std::{
4    ffi::{CStr, NulError},
5    io,
6};
7
8use num_enum::{FromPrimitive, IntoPrimitive};
9use thiserror::Error;
10
11use singe_cuda_sys::{nvrtc, nvvm, runtime};
12
13use crate::nvrtc::Status as NvrtcStatus;
14use crate::nvvm::Status as NvvmStatus;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, FromPrimitive, IntoPrimitive)]
17#[repr(u32)]
18#[non_exhaustive]
19pub enum Status {
20    Success = runtime::cudaError_t::CUDA_SUCCESS as _,
21    InvalidValue = runtime::cudaError_t::CUDA_ERROR_INVALID_VALUE as _,
22    OutOfMemory = runtime::cudaError_t::CUDA_ERROR_OUT_OF_MEMORY as _,
23    NotInitialized = runtime::cudaError_t::CUDA_ERROR_NOT_INITIALIZED as _,
24    Deinitialized = runtime::cudaError_t::CUDA_ERROR_DEINITIALIZED as _,
25    ProfilerDisabled = runtime::cudaError_t::CUDA_ERROR_PROFILER_DISABLED as _,
26    #[deprecated]
27    ProfilerNotInitialized = runtime::cudaError_t::CUDA_ERROR_PROFILER_NOT_INITIALIZED as _,
28    #[deprecated]
29    ProfilerAlreadyStarted = runtime::cudaError_t::CUDA_ERROR_PROFILER_ALREADY_STARTED as _,
30    #[deprecated]
31    ProfilerAlreadyStopped = runtime::cudaError_t::CUDA_ERROR_PROFILER_ALREADY_STOPPED as _,
32    StubLibrary = runtime::cudaError_t::CUDA_ERROR_STUB_LIBRARY as _,
33    CallRequiresNewerDriver = runtime::cudaError_t::CUDA_ERROR_CALL_REQUIRES_NEWER_DRIVER as _,
34    DeviceUnavailable = runtime::cudaError_t::CUDA_ERROR_DEVICE_UNAVAILABLE as _,
35    NoDevice = runtime::cudaError_t::CUDA_ERROR_NO_DEVICE as _,
36    InvalidDevice = runtime::cudaError_t::CUDA_ERROR_INVALID_DEVICE as _,
37    DeviceNotLicensed = runtime::cudaError_t::CUDA_ERROR_DEVICE_NOT_LICENSED as _,
38    InvalidImage = runtime::cudaError_t::CUDA_ERROR_INVALID_IMAGE as _,
39    InvalidContext = runtime::cudaError_t::CUDA_ERROR_INVALID_CONTEXT as _,
40    #[deprecated]
41    ContextAlreadyCurrent = runtime::cudaError_t::CUDA_ERROR_CONTEXT_ALREADY_CURRENT as _,
42    MapFailed = runtime::cudaError_t::CUDA_ERROR_MAP_FAILED as _,
43    UnmapFailed = runtime::cudaError_t::CUDA_ERROR_UNMAP_FAILED as _,
44    ArrayIsMapped = runtime::cudaError_t::CUDA_ERROR_ARRAY_IS_MAPPED as _,
45    AlreadyMapped = runtime::cudaError_t::CUDA_ERROR_ALREADY_MAPPED as _,
46    NoBinaryForGpu = runtime::cudaError_t::CUDA_ERROR_NO_BINARY_FOR_GPU as _,
47    AlreadyAcquired = runtime::cudaError_t::CUDA_ERROR_ALREADY_ACQUIRED as _,
48    NotMapped = runtime::cudaError_t::CUDA_ERROR_NOT_MAPPED as _,
49    NotMappedAsArray = runtime::cudaError_t::CUDA_ERROR_NOT_MAPPED_AS_ARRAY as _,
50    NotMappedAsPointer = runtime::cudaError_t::CUDA_ERROR_NOT_MAPPED_AS_POINTER as _,
51    EccUncorrectable = runtime::cudaError_t::CUDA_ERROR_ECC_UNCORRECTABLE as _,
52    UnsupportedLimit = runtime::cudaError_t::CUDA_ERROR_UNSUPPORTED_LIMIT as _,
53    ContextAlreadyInUse = runtime::cudaError_t::CUDA_ERROR_CONTEXT_ALREADY_IN_USE as _,
54    PeerAccessUnsupported = runtime::cudaError_t::CUDA_ERROR_PEER_ACCESS_UNSUPPORTED as _,
55    InvalidPtx = runtime::cudaError_t::CUDA_ERROR_INVALID_PTX as _,
56    InvalidGraphicsContext = runtime::cudaError_t::CUDA_ERROR_INVALID_GRAPHICS_CONTEXT as _,
57    NvlinkUncorrectable = runtime::cudaError_t::CUDA_ERROR_NVLINK_UNCORRECTABLE as _,
58    JitCompilerNotFound = runtime::cudaError_t::CUDA_ERROR_JIT_COMPILER_NOT_FOUND as _,
59    UnsupportedPtxVersion = runtime::cudaError_t::CUDA_ERROR_UNSUPPORTED_PTX_VERSION as _,
60    JitCompilationDisabled = runtime::cudaError_t::CUDA_ERROR_JIT_COMPILATION_DISABLED as _,
61    UnsupportedExecAffinity = runtime::cudaError_t::CUDA_ERROR_UNSUPPORTED_EXEC_AFFINITY as _,
62    UnsupportedDevsideSync = runtime::cudaError_t::CUDA_ERROR_UNSUPPORTED_DEVSIDE_SYNC as _,
63    Contained = runtime::cudaError_t::CUDA_ERROR_CONTAINED as _,
64    InvalidSource = runtime::cudaError_t::CUDA_ERROR_INVALID_SOURCE as _,
65    FileNotFound = runtime::cudaError_t::CUDA_ERROR_FILE_NOT_FOUND as _,
66    SharedObjectSymbolNotFound =
67        runtime::cudaError_t::CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND as _,
68    SharedObjectInitFailed = runtime::cudaError_t::CUDA_ERROR_SHARED_OBJECT_INIT_FAILED as _,
69    OperatingSystem = runtime::cudaError_t::CUDA_ERROR_OPERATING_SYSTEM as _,
70    InvalidHandle = runtime::cudaError_t::CUDA_ERROR_INVALID_HANDLE as _,
71    IllegalState = runtime::cudaError_t::CUDA_ERROR_ILLEGAL_STATE as _,
72    LossyQuery = runtime::cudaError_t::CUDA_ERROR_LOSSY_QUERY as _,
73    NotFound = runtime::cudaError_t::CUDA_ERROR_NOT_FOUND as _,
74    NotReady = runtime::cudaError_t::CUDA_ERROR_NOT_READY as _,
75    IllegalAddress = runtime::cudaError_t::CUDA_ERROR_ILLEGAL_ADDRESS as _,
76    LaunchOutOfResources = runtime::cudaError_t::CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES as _,
77    LaunchTimeout = runtime::cudaError_t::CUDA_ERROR_LAUNCH_TIMEOUT as _,
78    LaunchIncompatibleTexturing =
79        runtime::cudaError_t::CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING as _,
80    PeerAccessAlreadyEnabled = runtime::cudaError_t::CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED as _,
81    PeerAccessNotEnabled = runtime::cudaError_t::CUDA_ERROR_PEER_ACCESS_NOT_ENABLED as _,
82    PrimaryContextActive = runtime::cudaError_t::CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE as _,
83    ContextIsDestroyed = runtime::cudaError_t::CUDA_ERROR_CONTEXT_IS_DESTROYED as _,
84    Assert = runtime::cudaError_t::CUDA_ERROR_ASSERT as _,
85    TooManyPeers = runtime::cudaError_t::CUDA_ERROR_TOO_MANY_PEERS as _,
86    HostMemoryAlreadyRegistered =
87        runtime::cudaError_t::CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED as _,
88    HostMemoryNotRegistered = runtime::cudaError_t::CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED as _,
89    HardwareStackError = runtime::cudaError_t::CUDA_ERROR_HARDWARE_STACK_ERROR as _,
90    IllegalInstruction = runtime::cudaError_t::CUDA_ERROR_ILLEGAL_INSTRUCTION as _,
91    MisalignedAddress = runtime::cudaError_t::CUDA_ERROR_MISALIGNED_ADDRESS as _,
92    InvalidAddressSpace = runtime::cudaError_t::CUDA_ERROR_INVALID_ADDRESS_SPACE as _,
93    InvalidPc = runtime::cudaError_t::CUDA_ERROR_INVALID_PC as _,
94    LaunchFailed = runtime::cudaError_t::CUDA_ERROR_LAUNCH_FAILED as _,
95    CooperativeLaunchTooLarge = runtime::cudaError_t::CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE as _,
96    TensorMemoryLeak = runtime::cudaError_t::CUDA_ERROR_TENSOR_MEMORY_LEAK as _,
97    NotPermitted = runtime::cudaError_t::CUDA_ERROR_NOT_PERMITTED as _,
98    NotSupported = runtime::cudaError_t::CUDA_ERROR_NOT_SUPPORTED as _,
99    SystemNotReady = runtime::cudaError_t::CUDA_ERROR_SYSTEM_NOT_READY as _,
100    SystemDriverMismatch = runtime::cudaError_t::CUDA_ERROR_SYSTEM_DRIVER_MISMATCH as _,
101    CompatNotSupportedOnDevice =
102        runtime::cudaError_t::CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE as _,
103    MpsConnectionFailed = runtime::cudaError_t::CUDA_ERROR_MPS_CONNECTION_FAILED as _,
104    MpsRpcFailure = runtime::cudaError_t::CUDA_ERROR_MPS_RPC_FAILURE as _,
105    MpsServerNotReady = runtime::cudaError_t::CUDA_ERROR_MPS_SERVER_NOT_READY as _,
106    MpsMaxClientsReached = runtime::cudaError_t::CUDA_ERROR_MPS_MAX_CLIENTS_REACHED as _,
107    MpsMaxConnectionsReached = runtime::cudaError_t::CUDA_ERROR_MPS_MAX_CONNECTIONS_REACHED as _,
108    MpsClientTerminated = runtime::cudaError_t::CUDA_ERROR_MPS_CLIENT_TERMINATED as _,
109    CdpNotSupported = runtime::cudaError_t::CUDA_ERROR_CDP_NOT_SUPPORTED as _,
110    CdpVersionMismatch = runtime::cudaError_t::CUDA_ERROR_CDP_VERSION_MISMATCH as _,
111    StreamCaptureUnsupported = runtime::cudaError_t::CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED as _,
112    StreamCaptureInvalidated = runtime::cudaError_t::CUDA_ERROR_STREAM_CAPTURE_INVALIDATED as _,
113    StreamCaptureMerge = runtime::cudaError_t::CUDA_ERROR_STREAM_CAPTURE_MERGE as _,
114    StreamCaptureUnmatched = runtime::cudaError_t::CUDA_ERROR_STREAM_CAPTURE_UNMATCHED as _,
115    StreamCaptureUnjoined = runtime::cudaError_t::CUDA_ERROR_STREAM_CAPTURE_UNJOINED as _,
116    StreamCaptureIsolation = runtime::cudaError_t::CUDA_ERROR_STREAM_CAPTURE_ISOLATION as _,
117    StreamCaptureImplicit = runtime::cudaError_t::CUDA_ERROR_STREAM_CAPTURE_IMPLICIT as _,
118    CapturedEvent = runtime::cudaError_t::CUDA_ERROR_CAPTURED_EVENT as _,
119    StreamCaptureWrongThread = runtime::cudaError_t::CUDA_ERROR_STREAM_CAPTURE_WRONG_THREAD as _,
120    Timeout = runtime::cudaError_t::CUDA_ERROR_TIMEOUT as _,
121    GraphExecUpdateFailure = runtime::cudaError_t::CUDA_ERROR_GRAPH_EXEC_UPDATE_FAILURE as _,
122    ExternalDevice = runtime::cudaError_t::CUDA_ERROR_EXTERNAL_DEVICE as _,
123    InvalidClusterSize = runtime::cudaError_t::CUDA_ERROR_INVALID_CLUSTER_SIZE as _,
124    FunctionNotLoaded = runtime::cudaError_t::CUDA_ERROR_FUNCTION_NOT_LOADED as _,
125    InvalidResourceType = runtime::cudaError_t::CUDA_ERROR_INVALID_RESOURCE_TYPE as _,
126    InvalidResourceConfiguration =
127        runtime::cudaError_t::CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION as _,
128    KeyRotation = runtime::cudaError_t::CUDA_ERROR_KEY_ROTATION as _,
129    StreamDetached = runtime::cudaError_t::CUDA_ERROR_STREAM_DETACHED as _,
130    UnknownError = runtime::cudaError_t::CUDA_ERROR_UNKNOWN as _,
131    #[num_enum(catch_all)]
132    Unknown(u32),
133}
134
135impl From<runtime::cudaError_t> for Status {
136    fn from(value: runtime::cudaError_t) -> Self {
137        Self::from(value as u32)
138    }
139}
140
141impl From<Status> for runtime::cudaError_t {
142    fn from(value: Status) -> Self {
143        if let Status::Unknown(_) = value {
144            return runtime::cudaError_t::CUDA_ERROR_UNKNOWN;
145        }
146        let value: u32 = value.into();
147        unsafe { core::mem::transmute::<u32, Self>(value) }
148    }
149}
150
151impl Status {
152    pub fn description(self) -> String {
153        if let Self::Unknown(_) = self {
154            return String::from("unknown cuda error");
155        }
156        unsafe {
157            let ptr = runtime::cudaGetErrorString(self.into());
158            if ptr.is_null() {
159                String::from("unknown cuda error")
160            } else {
161                CStr::from_ptr(ptr).to_string_lossy().into_owned()
162            }
163        }
164    }
165}
166
167impl std::fmt::Display for Status {
168    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169        match self {
170            Self::Success => f.write_str("CUDA_SUCCESS"),
171            Self::InvalidValue => f.write_str("CUDA_ERROR_INVALID_VALUE"),
172            Self::OutOfMemory => f.write_str("CUDA_ERROR_OUT_OF_MEMORY"),
173            Self::NotInitialized => f.write_str("CUDA_ERROR_NOT_INITIALIZED"),
174            Self::Deinitialized => f.write_str("CUDA_ERROR_DEINITIALIZED"),
175            Self::ProfilerDisabled => f.write_str("CUDA_ERROR_PROFILER_DISABLED"),
176            Self::ProfilerNotInitialized => f.write_str("CUDA_ERROR_PROFILER_NOT_INITIALIZED"),
177            Self::ProfilerAlreadyStarted => f.write_str("CUDA_ERROR_PROFILER_ALREADY_STARTED"),
178            Self::ProfilerAlreadyStopped => f.write_str("CUDA_ERROR_PROFILER_ALREADY_STOPPED"),
179            Self::StubLibrary => f.write_str("CUDA_ERROR_STUB_LIBRARY"),
180            Self::CallRequiresNewerDriver => f.write_str("CUDA_ERROR_CALL_REQUIRES_NEWER_DRIVER"),
181            Self::DeviceUnavailable => f.write_str("CUDA_ERROR_DEVICE_UNAVAILABLE"),
182            Self::NoDevice => f.write_str("CUDA_ERROR_NO_DEVICE"),
183            Self::InvalidDevice => f.write_str("CUDA_ERROR_INVALID_DEVICE"),
184            Self::DeviceNotLicensed => f.write_str("CUDA_ERROR_DEVICE_NOT_LICENSED"),
185            Self::InvalidImage => f.write_str("CUDA_ERROR_INVALID_IMAGE"),
186            Self::InvalidContext => f.write_str("CUDA_ERROR_INVALID_CONTEXT"),
187            Self::ContextAlreadyCurrent => f.write_str("CUDA_ERROR_CONTEXT_ALREADY_CURRENT"),
188            Self::MapFailed => f.write_str("CUDA_ERROR_MAP_FAILED"),
189            Self::UnmapFailed => f.write_str("CUDA_ERROR_UNMAP_FAILED"),
190            Self::ArrayIsMapped => f.write_str("CUDA_ERROR_ARRAY_IS_MAPPED"),
191            Self::AlreadyMapped => f.write_str("CUDA_ERROR_ALREADY_MAPPED"),
192            Self::NoBinaryForGpu => f.write_str("CUDA_ERROR_NO_BINARY_FOR_GPU"),
193            Self::AlreadyAcquired => f.write_str("CUDA_ERROR_ALREADY_ACQUIRED"),
194            Self::NotMapped => f.write_str("CUDA_ERROR_NOT_MAPPED"),
195            Self::NotMappedAsArray => f.write_str("CUDA_ERROR_NOT_MAPPED_AS_ARRAY"),
196            Self::NotMappedAsPointer => f.write_str("CUDA_ERROR_NOT_MAPPED_AS_POINTER"),
197            Self::EccUncorrectable => f.write_str("CUDA_ERROR_ECC_UNCORRECTABLE"),
198            Self::UnsupportedLimit => f.write_str("CUDA_ERROR_UNSUPPORTED_LIMIT"),
199            Self::ContextAlreadyInUse => f.write_str("CUDA_ERROR_CONTEXT_ALREADY_IN_USE"),
200            Self::PeerAccessUnsupported => f.write_str("CUDA_ERROR_PEER_ACCESS_UNSUPPORTED"),
201            Self::InvalidPtx => f.write_str("CUDA_ERROR_INVALID_PTX"),
202            Self::InvalidGraphicsContext => f.write_str("CUDA_ERROR_INVALID_GRAPHICS_CONTEXT"),
203            Self::NvlinkUncorrectable => f.write_str("CUDA_ERROR_NVLINK_UNCORRECTABLE"),
204            Self::JitCompilerNotFound => f.write_str("CUDA_ERROR_JIT_COMPILER_NOT_FOUND"),
205            Self::UnsupportedPtxVersion => f.write_str("CUDA_ERROR_UNSUPPORTED_PTX_VERSION"),
206            Self::JitCompilationDisabled => f.write_str("CUDA_ERROR_JIT_COMPILATION_DISABLED"),
207            Self::UnsupportedExecAffinity => f.write_str("CUDA_ERROR_UNSUPPORTED_EXEC_AFFINITY"),
208            Self::UnsupportedDevsideSync => f.write_str("CUDA_ERROR_UNSUPPORTED_DEVSIDE_SYNC"),
209            Self::Contained => f.write_str("CUDA_ERROR_CONTAINED"),
210            Self::InvalidSource => f.write_str("CUDA_ERROR_INVALID_SOURCE"),
211            Self::FileNotFound => f.write_str("CUDA_ERROR_FILE_NOT_FOUND"),
212            Self::SharedObjectSymbolNotFound => {
213                f.write_str("CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND")
214            }
215            Self::SharedObjectInitFailed => f.write_str("CUDA_ERROR_SHARED_OBJECT_INIT_FAILED"),
216            Self::OperatingSystem => f.write_str("CUDA_ERROR_OPERATING_SYSTEM"),
217            Self::InvalidHandle => f.write_str("CUDA_ERROR_INVALID_HANDLE"),
218            Self::IllegalState => f.write_str("CUDA_ERROR_ILLEGAL_STATE"),
219            Self::LossyQuery => f.write_str("CUDA_ERROR_LOSSY_QUERY"),
220            Self::NotFound => f.write_str("CUDA_ERROR_NOT_FOUND"),
221            Self::NotReady => f.write_str("CUDA_ERROR_NOT_READY"),
222            Self::IllegalAddress => f.write_str("CUDA_ERROR_ILLEGAL_ADDRESS"),
223            Self::LaunchOutOfResources => f.write_str("CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES"),
224            Self::LaunchTimeout => f.write_str("CUDA_ERROR_LAUNCH_TIMEOUT"),
225            Self::LaunchIncompatibleTexturing => {
226                f.write_str("CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING")
227            }
228            Self::PeerAccessAlreadyEnabled => f.write_str("CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED"),
229            Self::PeerAccessNotEnabled => f.write_str("CUDA_ERROR_PEER_ACCESS_NOT_ENABLED"),
230            Self::PrimaryContextActive => f.write_str("CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE"),
231            Self::ContextIsDestroyed => f.write_str("CUDA_ERROR_CONTEXT_IS_DESTROYED"),
232            Self::Assert => f.write_str("CUDA_ERROR_ASSERT"),
233            Self::TooManyPeers => f.write_str("CUDA_ERROR_TOO_MANY_PEERS"),
234            Self::HostMemoryAlreadyRegistered => {
235                f.write_str("CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED")
236            }
237            Self::HostMemoryNotRegistered => f.write_str("CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED"),
238            Self::HardwareStackError => f.write_str("CUDA_ERROR_HARDWARE_STACK_ERROR"),
239            Self::IllegalInstruction => f.write_str("CUDA_ERROR_ILLEGAL_INSTRUCTION"),
240            Self::MisalignedAddress => f.write_str("CUDA_ERROR_MISALIGNED_ADDRESS"),
241            Self::InvalidAddressSpace => f.write_str("CUDA_ERROR_INVALID_ADDRESS_SPACE"),
242            Self::InvalidPc => f.write_str("CUDA_ERROR_INVALID_PC"),
243            Self::LaunchFailed => f.write_str("CUDA_ERROR_LAUNCH_FAILED"),
244            Self::CooperativeLaunchTooLarge => {
245                f.write_str("CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE")
246            }
247            Self::TensorMemoryLeak => f.write_str("CUDA_ERROR_TENSOR_MEMORY_LEAK"),
248            Self::NotPermitted => f.write_str("CUDA_ERROR_NOT_PERMITTED"),
249            Self::NotSupported => f.write_str("CUDA_ERROR_NOT_SUPPORTED"),
250            Self::SystemNotReady => f.write_str("CUDA_ERROR_SYSTEM_NOT_READY"),
251            Self::SystemDriverMismatch => f.write_str("CUDA_ERROR_SYSTEM_DRIVER_MISMATCH"),
252            Self::CompatNotSupportedOnDevice => {
253                f.write_str("CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE")
254            }
255            Self::MpsConnectionFailed => f.write_str("CUDA_ERROR_MPS_CONNECTION_FAILED"),
256            Self::MpsRpcFailure => f.write_str("CUDA_ERROR_MPS_RPC_FAILURE"),
257            Self::MpsServerNotReady => f.write_str("CUDA_ERROR_MPS_SERVER_NOT_READY"),
258            Self::MpsMaxClientsReached => f.write_str("CUDA_ERROR_MPS_MAX_CLIENTS_REACHED"),
259            Self::MpsMaxConnectionsReached => f.write_str("CUDA_ERROR_MPS_MAX_CONNECTIONS_REACHED"),
260            Self::MpsClientTerminated => f.write_str("CUDA_ERROR_MPS_CLIENT_TERMINATED"),
261            Self::CdpNotSupported => f.write_str("CUDA_ERROR_CDP_NOT_SUPPORTED"),
262            Self::CdpVersionMismatch => f.write_str("CUDA_ERROR_CDP_VERSION_MISMATCH"),
263            Self::StreamCaptureUnsupported => f.write_str("CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED"),
264            Self::StreamCaptureInvalidated => f.write_str("CUDA_ERROR_STREAM_CAPTURE_INVALIDATED"),
265            Self::StreamCaptureMerge => f.write_str("CUDA_ERROR_STREAM_CAPTURE_MERGE"),
266            Self::StreamCaptureUnmatched => f.write_str("CUDA_ERROR_STREAM_CAPTURE_UNMATCHED"),
267            Self::StreamCaptureUnjoined => f.write_str("CUDA_ERROR_STREAM_CAPTURE_UNJOINED"),
268            Self::StreamCaptureIsolation => f.write_str("CUDA_ERROR_STREAM_CAPTURE_ISOLATION"),
269            Self::StreamCaptureImplicit => f.write_str("CUDA_ERROR_STREAM_CAPTURE_IMPLICIT"),
270            Self::CapturedEvent => f.write_str("CUDA_ERROR_CAPTURED_EVENT"),
271            Self::StreamCaptureWrongThread => f.write_str("CUDA_ERROR_STREAM_CAPTURE_WRONG_THREAD"),
272            Self::Timeout => f.write_str("CUDA_ERROR_TIMEOUT"),
273            Self::GraphExecUpdateFailure => f.write_str("CUDA_ERROR_GRAPH_EXEC_UPDATE_FAILURE"),
274            Self::ExternalDevice => f.write_str("CUDA_ERROR_EXTERNAL_DEVICE"),
275            Self::InvalidClusterSize => f.write_str("CUDA_ERROR_INVALID_CLUSTER_SIZE"),
276            Self::FunctionNotLoaded => f.write_str("CUDA_ERROR_FUNCTION_NOT_LOADED"),
277            Self::InvalidResourceType => f.write_str("CUDA_ERROR_INVALID_RESOURCE_TYPE"),
278            Self::InvalidResourceConfiguration => {
279                f.write_str("CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION")
280            }
281            Self::KeyRotation => f.write_str("CUDA_ERROR_KEY_ROTATION"),
282            Self::StreamDetached => f.write_str("CUDA_ERROR_STREAM_DETACHED"),
283            Self::UnknownError => f.write_str("CUDA_ERROR_UNKNOWN"),
284            Self::Unknown(code) => write!(f, "UNKNOWN_CUDA_STATUS({code})"),
285        }
286    }
287}
288
289#[derive(Error, Debug)]
290#[non_exhaustive]
291pub enum Error {
292    #[error("cuda error ({code}): {message}")]
293    Cuda { code: Status, message: String },
294
295    #[error("nvrtc error ({code}): {message}")]
296    Nvrtc { code: NvrtcStatus, message: String },
297
298    #[error("nvvm error ({code}): {message}")]
299    Nvvm { code: NvvmStatus, message: String },
300
301    #[error("string contains interior nul byte")]
302    InteriorNul,
303
304    #[error("io error: {0}")]
305    Io(#[from] io::Error),
306
307    #[error("device not found")]
308    DeviceNotFound,
309
310    #[error("invalid memory access")]
311    InvalidMemoryAccess,
312    #[error("invalid memory allocation request")]
313    InvalidMemoryAllocationRequest,
314    #[error("unexpected null handle")]
315    NullHandle,
316    #[error("invalid value")]
317    InvalidValue,
318
319    #[error("`{name}` must be nonzero")]
320    ZeroValue { name: String },
321
322    #[error("`{name}` is out of range")]
323    OutOfRange { name: String },
324
325    #[error("operation graph required")]
326    GraphOperationRequired,
327    #[error("graph dependency mismatch")]
328    GraphDependencyMismatch,
329    #[error("graph node belongs to a different graph")]
330    GraphNodeMismatch,
331    #[error("graph belongs to a different cuda context")]
332    GraphContextMismatch,
333
334    #[error("stream belongs to a different cuda context")]
335    StreamContextMismatch,
336}
337
338pub type Result<T> = std::result::Result<T, Error>;
339
340impl From<runtime::cudaError_t> for Error {
341    fn from(code: runtime::cudaError_t) -> Self {
342        let message = unsafe {
343            let c_ptr = runtime::cudaGetErrorString(code);
344            if c_ptr.is_null() {
345                String::from("unknown cuda error")
346            } else {
347                CStr::from_ptr(c_ptr).to_string_lossy().into_owned()
348            }
349        };
350
351        Self::Cuda {
352            code: Status::from(code),
353            message,
354        }
355    }
356}
357
358impl From<Status> for Error {
359    fn from(code: Status) -> Self {
360        Self::Cuda {
361            code,
362            message: code.description(),
363        }
364    }
365}
366
367impl From<NulError> for Error {
368    fn from(_: NulError) -> Self {
369        Self::InteriorNul
370    }
371}
372
373impl From<nvrtc::nvrtcResult> for Error {
374    fn from(code: nvrtc::nvrtcResult) -> Self {
375        let code = NvrtcStatus::from(code);
376        Self::from(code)
377    }
378}
379
380impl From<NvrtcStatus> for Error {
381    fn from(code: NvrtcStatus) -> Self {
382        Self::Nvrtc {
383            code,
384            message: code.description(),
385        }
386    }
387}
388
389impl From<nvvm::nvvmResult> for Error {
390    fn from(code: nvvm::nvvmResult) -> Self {
391        let code = NvvmStatus::from(code);
392        Self::from(code)
393    }
394}
395
396impl From<NvvmStatus> for Error {
397    fn from(code: NvvmStatus) -> Self {
398        Self::Nvvm {
399            code,
400            message: code.description(),
401        }
402    }
403}
404
405#[macro_export]
406macro_rules! try_ffi {
407    ($expr:expr) => {{
408        let err = { $expr };
409        if err != singe_cuda_sys::runtime::cudaError_t::CUDA_SUCCESS {
410            Err($crate::error::Error::from(err))
411        } else {
412            Ok(())
413        }
414    }};
415}
416
417#[macro_export]
418macro_rules! try_nvrtc {
419    ($expr:expr) => {{
420        let err = { $expr };
421        if err != singe_cuda_sys::nvrtc::nvrtcResult::NVRTC_SUCCESS {
422            Err($crate::error::Error::from(err))
423        } else {
424            Ok(())
425        }
426    }};
427}
428
429#[macro_export]
430macro_rules! try_nvvm {
431    ($expr:expr) => {{
432        let err = { $expr };
433        if err != singe_cuda_sys::nvvm::nvvmResult::NVVM_SUCCESS {
434            Err($crate::error::Error::from(err))
435        } else {
436            Ok(())
437        }
438    }};
439}