Skip to main content

shrew_core/
error.rs

1use crate::shape::Shape;
2
3/// All errors that can occur within Shrew.
4///
5/// This enum captures every failure mode: shape mismatches, dtype mismatches,
6/// device mismatches, out-of-bounds indexing, and backend-specific errors.
7/// Using a single error type across the library simplifies error propagation.
8#[derive(Debug, thiserror::Error)]
9pub enum Error {
10    /// Shape mismatch between two tensors (e.g., trying to add [2,3] + [4,5]).
11    #[error("shape mismatch: expected {expected}, got {got}")]
12    ShapeMismatch { expected: Shape, got: Shape },
13
14    /// Operation requires a specific rank (number of dimensions).
15    #[error("rank mismatch: expected rank {expected}, got {got}")]
16    RankMismatch { expected: usize, got: usize },
17
18    /// DType mismatch between tensors in a binary operation.
19    #[error("dtype mismatch: expected {expected:?}, got {got:?}")]
20    DTypeMismatch {
21        expected: crate::DType,
22        got: crate::DType,
23    },
24
25    /// Dimension index out of range for the tensor's rank.
26    #[error("dimension out of range: dim {dim} for tensor with {rank} dimensions")]
27    DimOutOfRange { dim: usize, rank: usize },
28
29    /// Narrow/slice operation out of bounds.
30    #[error("narrow out of bounds: dim {dim}, start {start}, len {len}, dim_size {dim_size}")]
31    NarrowOutOfBounds {
32        dim: usize,
33        start: usize,
34        len: usize,
35        dim_size: usize,
36    },
37
38    /// Tried to access a scalar from a non-scalar tensor.
39    #[error("not a scalar: tensor has shape {shape}")]
40    NotAScalar { shape: Shape },
41
42    /// Element count mismatch when creating from a vec.
43    #[error("element count mismatch: shape {shape} requires {expected} elements, got {got}")]
44    ElementCountMismatch {
45        shape: Shape,
46        expected: usize,
47        got: usize,
48    },
49
50    /// Matrix multiplication dimension mismatch.
51    #[error("matmul shape mismatch: [{m}x{k1}] @ [{k2}x{n}] — inner dims must match")]
52    MatmulShapeMismatch {
53        m: usize,
54        k1: usize,
55        k2: usize,
56        n: usize,
57    },
58
59    /// Cannot reshape because element counts differ.
60    #[error(
61        "cannot reshape: source has {src} elements, target shape {dst_shape} has {dst} elements"
62    )]
63    ReshapeElementMismatch {
64        src: usize,
65        dst: usize,
66        dst_shape: Shape,
67    },
68
69    /// Generic message for cases not covered above.
70    #[error("{0}")]
71    Msg(String),
72}
73
74impl Error {
75    /// Create an error from any string message.
76    pub fn msg(s: impl Into<String>) -> Self {
77        Error::Msg(s.into())
78    }
79}
80
81/// Convenience Result type used throughout Shrew.
82pub type Result<T> = std::result::Result<T, Error>;
83
84/// Macro for early return with a formatted error message.
85/// Usage: `bail!("something went wrong: {}", detail)`
86#[macro_export]
87macro_rules! bail {
88    ($($arg:tt)*) => {
89        return Err($crate::Error::Msg(format!($($arg)*)))
90    };
91}