1use core::fmt;
2use std::ffi::CStr;
3
4use sp1_gpu_sys::runtime::{
5 CudaRustError, CUDA_ERROR_NOT_READY_SLOP, CUDA_OUT_OF_MEMORY, CUDA_SUCCESS_CSL,
6};
7use thiserror::Error;
8
9#[derive(Clone, Copy, PartialEq, Eq)]
10pub struct OtherError(CudaRustError);
11
12#[derive(Clone, Debug, Copy, PartialEq, Eq, Error)]
13pub enum CudaError {
14 #[error("out of GPU memory")]
15 OutOfMemory,
16 #[error("not ready")]
17 NotReady,
18 #[error("other CUDA error: {0}")]
19 Other(#[from] OtherError),
20}
21
22unsafe impl Send for CudaError {}
23unsafe impl Sync for CudaError {}
24
25impl CudaError {
26 #[inline]
32 pub fn result_from_ffi(maybe_error: CudaRustError) -> Result<(), Self> {
33 unsafe {
36 match maybe_error {
37 e if e == CUDA_SUCCESS_CSL => Ok(()),
38 e if e == CUDA_OUT_OF_MEMORY => Err(Self::OutOfMemory),
39 e if e == CUDA_ERROR_NOT_READY_SLOP => Err(Self::NotReady),
40 _ => Err(Self::Other(OtherError(maybe_error))),
41 }
42 }
43 }
44}
45
46impl fmt::Debug for OtherError {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 let message = unsafe { CStr::from_ptr(self.0.message).to_str().map_err(|_| fmt::Error)? };
51 write!(f, "CudaRustError: {message}")
52 }
53}
54
55impl fmt::Display for OtherError {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 write!(f, "{self:?}")
58 }
59}
60
61impl core::error::Error for OtherError {}