1use oxicuda_blas::BlasError;
8use oxicuda_driver::CudaError;
9use oxicuda_ptx::PtxGenError;
10use thiserror::Error;
11
12#[derive(Debug, Error)]
17pub enum SparseError {
18 #[error("CUDA driver error: {0}")]
20 Cuda(#[from] CudaError),
21
22 #[error("BLAS error: {0}")]
24 Blas(#[from] BlasError),
25
26 #[error("PTX generation error: {0}")]
28 PtxGeneration(String),
29
30 #[error("invalid sparse format: {0}")]
32 InvalidFormat(String),
33
34 #[error("dimension mismatch: {0}")]
36 DimensionMismatch(String),
37
38 #[error("matrix has zero non-zeros")]
40 ZeroNnz,
41
42 #[error("singular matrix detected")]
44 SingularMatrix,
45
46 #[error("convergence failure: {0}")]
48 ConvergenceFailure(String),
49
50 #[error("internal error: {0}")]
52 InternalError(String),
53
54 #[error("invalid argument: {0}")]
56 InvalidArgument(String),
57
58 #[error("I/O error: {0}")]
60 Io(#[from] std::io::Error),
61}
62
63impl From<PtxGenError> for SparseError {
64 fn from(err: PtxGenError) -> Self {
65 Self::PtxGeneration(err.to_string())
66 }
67}
68
69pub type SparseResult<T> = Result<T, SparseError>;
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn display_zero_nnz() {
78 let err = SparseError::ZeroNnz;
79 assert!(err.to_string().contains("zero non-zeros"));
80 }
81
82 #[test]
83 fn display_dimension_mismatch() {
84 let err = SparseError::DimensionMismatch("A.cols != B.rows".to_string());
85 assert!(err.to_string().contains("A.cols != B.rows"));
86 }
87
88 #[test]
89 fn from_cuda_error() {
90 let cuda_err = CudaError::NotInitialized;
91 let sparse_err: SparseError = cuda_err.into();
92 assert!(matches!(sparse_err, SparseError::Cuda(_)));
93 }
94}