1use oxicuda_blas::BlasError;
8use oxicuda_driver::CudaError;
9use thiserror::Error;
10
11#[derive(Debug, Error)]
13pub enum DnnError {
14 #[error("CUDA driver error: {0}")]
16 Cuda(#[from] CudaError),
17
18 #[error("BLAS error: {0}")]
20 Blas(#[from] BlasError),
21
22 #[error("PTX generation error: {0}")]
24 PtxGeneration(String),
25
26 #[error("invalid tensor dimensions: {0}")]
29 InvalidDimension(String),
30
31 #[error("buffer too small: expected {expected} bytes, got {actual} bytes")]
33 BufferTooSmall {
34 expected: usize,
36 actual: usize,
38 },
39
40 #[error("unsupported operation: {0}")]
43 UnsupportedOperation(String),
44
45 #[error("invalid argument: {0}")]
47 InvalidArgument(String),
48
49 #[error("workspace required: need at least {0} bytes")]
52 WorkspaceRequired(usize),
53
54 #[error("kernel launch failed: {0}")]
56 LaunchFailed(String),
57
58 #[error("I/O error: {0}")]
60 Io(#[from] std::io::Error),
61}
62
63impl From<oxicuda_ptx::PtxGenError> for DnnError {
64 fn from(e: oxicuda_ptx::PtxGenError) -> Self {
65 Self::PtxGeneration(e.to_string())
66 }
67}
68
69pub type DnnResult<T> = Result<T, DnnError>;
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn display_buffer_too_small() {
78 let e = DnnError::BufferTooSmall {
79 expected: 4096,
80 actual: 1024,
81 };
82 assert!(e.to_string().contains("4096"));
83 assert!(e.to_string().contains("1024"));
84 }
85
86 #[test]
87 fn display_workspace_required() {
88 let e = DnnError::WorkspaceRequired(8192);
89 assert!(e.to_string().contains("8192"));
90 }
91
92 #[test]
93 fn from_cuda_error() {
94 let cuda_err = CudaError::InvalidValue;
95 let dnn_err: DnnError = cuda_err.into();
96 assert!(matches!(dnn_err, DnnError::Cuda(_)));
97 }
98}