use oxicuda_blas::BlasError;
use oxicuda_driver::CudaError;
use oxicuda_ptx::PtxGenError;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum SparseError {
#[error("CUDA driver error: {0}")]
Cuda(#[from] CudaError),
#[error("BLAS error: {0}")]
Blas(#[from] BlasError),
#[error("PTX generation error: {0}")]
PtxGeneration(String),
#[error("invalid sparse format: {0}")]
InvalidFormat(String),
#[error("dimension mismatch: {0}")]
DimensionMismatch(String),
#[error("matrix has zero non-zeros")]
ZeroNnz,
#[error("singular matrix detected")]
SingularMatrix,
#[error("convergence failure: {0}")]
ConvergenceFailure(String),
#[error("internal error: {0}")]
InternalError(String),
#[error("invalid argument: {0}")]
InvalidArgument(String),
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
}
impl From<PtxGenError> for SparseError {
fn from(err: PtxGenError) -> Self {
Self::PtxGeneration(err.to_string())
}
}
pub type SparseResult<T> = Result<T, SparseError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display_zero_nnz() {
let err = SparseError::ZeroNnz;
assert!(err.to_string().contains("zero non-zeros"));
}
#[test]
fn display_dimension_mismatch() {
let err = SparseError::DimensionMismatch("A.cols != B.rows".to_string());
assert!(err.to_string().contains("A.cols != B.rows"));
}
#[test]
fn from_cuda_error() {
let cuda_err = CudaError::NotInitialized;
let sparse_err: SparseError = cuda_err.into();
assert!(matches!(sparse_err, SparseError::Cuda(_)));
}
}