//! Error types for RTX-NMF operations use thiserror::Error; /// NMF-specific errors #[derive(Error, Debug)] pub enum NMFError { #[error("Tensor operation failed: {0}")] TensorError(#[from] rtx_tensor::error::TensorError), #[error("Invalid matrix dimensions: expected {expected}, got {actual}")] InvalidDimensions { expected: String, actual: String }, #[error("Matrix contains negative values at indices: {indices:?}")] NegativeValues { indices: Vec<(usize, usize)> }, #[error("NMF failed to converge after {iterations} iterations")] ConvergenceFailure { iterations: usize }, #[error("Invalid number of components: {components}, must be > 0 and < min(m, n)")] InvalidComponents { components: usize }, #[error("GPU operation failed: {message}")] GpuError { message: String }, #[error("CUDA kernel compilation failed: {error}")] KernelCompilationError { error: String }, #[error("Invalid configuration: {message}")] ConfigurationError { message: String }, #[error("Invalid value: {message}")] ValueError { message: String }, #[error("IO error: {0}")] IoError(#[from] std::io::Error), #[error("Serialization error: {0}")] SerializationError(#[from] serde_json::Error), } impl NMFError { /// Create a new GPU error pub fn gpu_error(message: impl Into) -> Self { Self::GpuError { message: message.into(), } } /// Create a new kernel compilation error pub fn kernel_compilation_error(error: impl Into) -> Self { Self::KernelCompilationError { error: error.into(), } } /// Create a new configuration error pub fn configuration_error(message: impl Into) -> Self { Self::ConfigurationError { message: message.into(), } } /// Create a new value error pub fn value_error(message: impl Into) -> Self { Self::ValueError { message: message.into(), } } /// Check if error is recoverable (e.g., can retry with different parameters) pub fn is_recoverable(&self) -> bool { matches!( self, Self::ConvergenceFailure { .. } | Self::InvalidComponents { .. } ) } } /// Result type for NMF operations pub type Result = std::result::Result; #[cfg(test)] mod tests { use super::*; #[test] fn test_error_creation() { let error = NMFError::gpu_error("Test GPU error"); assert!(matches!(error, NMFError::GpuError { .. })); assert!(!error.is_recoverable()); let error = NMFError::ConvergenceFailure { iterations: 100 }; assert!(error.is_recoverable()); } }