#[derive(Debug, Clone, PartialEq, Eq)]
pub enum OpError {
OutOfVocabulary {
id: u32,
vocab_size: usize,
position: usize,
},
ShapeMismatch {
expected: Vec<usize>,
got: Vec<usize>,
},
AllPaddingRow {
row: usize,
},
LengthMismatch {
ids: usize,
mask: usize,
},
ZeroDimension {
which: &'static str,
},
ShapeOverflow {
dims: Vec<usize>,
},
NonBinaryMaskValue {
value: u8,
position: usize,
},
NonFiniteInput {
position: usize,
},
InvalidEpsilon {
eps_bits: u32,
},
}
impl OpError {
pub(crate) fn invalid_epsilon(eps: f32) -> Self {
Self::InvalidEpsilon {
eps_bits: eps.to_bits(),
}
}
#[must_use]
pub fn epsilon(&self) -> Option<f32> {
match self {
Self::InvalidEpsilon { eps_bits } => Some(f32::from_bits(*eps_bits)),
_ => None,
}
}
}
impl std::fmt::Display for OpError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::OutOfVocabulary {
id,
vocab_size,
position,
} => write!(
f,
"OpError::OutOfVocabulary(id {id} >= vocab_size {vocab_size} at flat position {position})"
),
Self::ShapeMismatch { expected, got } => {
let want: Vec<String> = expected
.iter()
.map(|d| if *d == 0 { "*".to_string() } else { d.to_string() })
.collect();
write!(
f,
"OpError::ShapeMismatch(expected [{}], got {got:?})",
want.join(", ")
)
}
Self::AllPaddingRow { row } => write!(
f,
"OpError::AllPaddingRow(row {row} has no valid position; denominator would be zero)"
),
Self::LengthMismatch { ids, mask } => write!(
f,
"OpError::LengthMismatch(expected {ids} positions, got a slice of length {mask})"
),
Self::ZeroDimension { which } => {
write!(f, "OpError::ZeroDimension({which} is zero)")
}
Self::ShapeOverflow { dims } => write!(
f,
"OpError::ShapeOverflow(product of {dims:?} overflows usize)"
),
Self::NonBinaryMaskValue { value, position } => write!(
f,
"OpError::NonBinaryMaskValue({value} at flat position {position}; only 0 and 1 are valid)"
),
Self::NonFiniteInput { position } => write!(
f,
"OpError::NonFiniteInput(non-finite value at flat position {position})"
),
Self::InvalidEpsilon { eps_bits } => write!(
f,
"OpError::InvalidEpsilon({}; the epsilon floor must be finite and > 0)",
f32::from_bits(*eps_bits)
),
}
}
}
impl std::error::Error for OpError {}