Skip to main content

batuta/oracle/rag/quantization/
error.rs

1//! Error types for quantization operations (Jidoka halt conditions)
2
3use std::fmt;
4
5/// Error types for quantization operations (Jidoka halt conditions)
6#[derive(Debug, Clone, PartialEq)]
7pub enum QuantizationError {
8    /// Embedding dimension mismatch
9    DimensionMismatch { expected: usize, actual: usize },
10    /// Non-finite value detected (NaN/Inf)
11    NonFiniteValue { index: usize, value: f32 },
12    /// Empty embedding
13    EmptyEmbedding,
14    /// Calibration not initialized
15    CalibrationNotInitialized,
16    /// Scale factor invalid (zero or negative)
17    InvalidScale { scale: f32 },
18    /// Overflow during computation
19    ComputationOverflow,
20}
21
22impl fmt::Display for QuantizationError {
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        match self {
25            Self::DimensionMismatch { expected, actual } => {
26                write!(f, "Dimension mismatch: expected {}, got {}", expected, actual)
27            }
28            Self::NonFiniteValue { index, value } => {
29                write!(f, "Non-finite value {} at index {}", value, index)
30            }
31            Self::EmptyEmbedding => write!(f, "Empty embedding"),
32            Self::CalibrationNotInitialized => write!(f, "Calibration not initialized"),
33            Self::InvalidScale { scale } => write!(f, "Invalid scale factor: {}", scale),
34            Self::ComputationOverflow => write!(f, "Computation overflow"),
35        }
36    }
37}
38
39impl std::error::Error for QuantizationError {}
40
41/// Validate an embedding for common error conditions (Poka-Yoke)
42///
43/// Checks:
44/// 1. Non-empty
45/// 2. Correct dimensionality
46/// 3. All values finite (no NaN/Inf)
47pub fn validate_embedding(
48    embedding: &[f32],
49    expected_dims: usize,
50) -> Result<(), QuantizationError> {
51    if embedding.len() != expected_dims {
52        return Err(QuantizationError::DimensionMismatch {
53            expected: expected_dims,
54            actual: embedding.len(),
55        });
56    }
57    if embedding.is_empty() {
58        return Err(QuantizationError::EmptyEmbedding);
59    }
60    for (i, &v) in embedding.iter().enumerate() {
61        if !v.is_finite() {
62            return Err(QuantizationError::NonFiniteValue { index: i, value: v });
63        }
64    }
65    Ok(())
66}