use std::mem::MaybeUninit;
use icicle_cuda_runtime::error::CudaError;
use crate::traits::IcicleResultWrap;
#[repr(u32)]
#[must_use]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum IcicleErrorCode {
IcicleSuccess = 0,
InvalidArgument = 1,
MemoryAllocationError = 2,
InternalCudaError = 199999999,
UndefinedError = 999999999,
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct IcicleError {
icicle_error_code: IcicleErrorCode,
cuda_error: Option<CudaError>,
reason: Option<&'static str>,
}
pub type IcicleResult<T> = Result<T, IcicleError>;
impl IcicleError {
pub fn from_cuda_error(cuda_error: CudaError) -> Self {
let icicle_error_code = match cuda_error {
CudaError::cudaSuccess => IcicleErrorCode::IcicleSuccess,
_ => IcicleErrorCode::InternalCudaError,
};
IcicleError {
icicle_error_code,
cuda_error: Some(cuda_error),
reason: Some("Runtime CUDA error."),
}
}
pub fn from_code_and_reason(icicle_error_code: IcicleErrorCode, reason: &'static str) -> Self {
IcicleError {
icicle_error_code,
reason: Some(reason),
cuda_error: None,
}
}
pub fn get_icicle_error_code(&self) -> IcicleErrorCode {
self.icicle_error_code
}
pub fn get_cuda_error(&self) -> Option<CudaError> {
self.cuda_error
}
}
impl IcicleResultWrap for CudaError {
fn wrap(self) -> IcicleResult<()> {
self.wrap_value(())
}
fn wrap_value<T>(self, value: T) -> IcicleResult<T> {
if self == CudaError::cudaSuccess {
Ok(value)
} else {
Err(IcicleError::from_cuda_error(self))
}
}
fn wrap_maybe_uninit<T>(self, value: MaybeUninit<T>) -> IcicleResult<T> {
self.wrap_value(unsafe { value.assume_init() })
}
}