Skip to main content

tenferro/
error.rs

1//! Error types for the tenferro crate.
2//!
3//! # Examples
4//!
5//! ```ignore
6//! use tenferro::error::Error;
7//!
8//! let err = Error::InvalidSubscripts("bad label".into());
9//! assert!(err.to_string().contains("bad label"));
10//! ```
11
12use tenferro_tensor::DType;
13
14/// Errors produced by einsum, eval, and other tenferro operations.
15///
16/// # Examples
17///
18/// ```ignore
19/// use tenferro::error::Error;
20///
21/// let err = Error::InvalidSubscripts("rank mismatch".into());
22/// ```
23#[derive(Debug, thiserror::Error)]
24pub enum Error {
25    /// Einsum subscript string is invalid or cannot be parsed.
26    #[error("invalid subscripts: {0}")]
27    InvalidSubscripts(String),
28
29    /// Contraction optimization failed (shape mismatch, bad path, etc.).
30    #[error("contraction error: {0}")]
31    ContractionError(String),
32
33    /// A required input tensor is missing from the inputs map.
34    #[error("missing input: {0}")]
35    MissingInput(String),
36
37    /// Reverse-mode gradient requires a scalar output.
38    #[error("grad requires a scalar output, got shape {shape:?}")]
39    NonScalarGrad { shape: Vec<usize> },
40
41    /// Runtime tensor execution failed in the backend layer.
42    #[error(transparent)]
43    TensorRuntime(#[from] tenferro_tensor::Error),
44
45    /// A `TracedTensor` passed to `eval_with_inputs` bindings is not a
46    /// placeholder (has attached data).
47    #[error(
48        "binding #{binding_index} is not a placeholder; \
49         only tensors built via input_concrete_shape / input_symbolic_shape \
50         can be bound"
51    )]
52    UnexpectedBinding { binding_index: usize },
53
54    /// A placeholder appearing in the graph has no binding supplied.
55    #[error("placeholder {input_key} has no binding in eval_with_inputs")]
56    UnboundPlaceholder { input_key: String },
57
58    /// The same placeholder was bound more than once in the `bindings` slice.
59    #[error("placeholder {input_key} was bound more than once")]
60    DuplicateBinding { input_key: String },
61
62    /// A binding tensor's dtype does not match the placeholder's dtype.
63    #[error("binding dtype mismatch for placeholder: expected {expected:?}, got {actual:?}")]
64    PlaceholderDtypeMismatch { expected: DType, actual: DType },
65
66    /// A binding tensor's shape does not match an `input_concrete_shape`
67    /// placeholder's fixed shape.
68    #[error(
69        "binding shape mismatch for concrete-shape placeholder: \
70         expected {expected:?}, got {actual:?}"
71    )]
72    PlaceholderShapeMismatch {
73        expected: Vec<usize>,
74        actual: Vec<usize>,
75    },
76
77    /// A binding tensor's rank does not match an `input_symbolic_shape`
78    /// placeholder's declared rank.
79    #[error(
80        "binding rank mismatch for symbolic-shape placeholder: \
81         expected rank {expected}, got rank {actual}"
82    )]
83    PlaceholderRankMismatch { expected: usize, actual: usize },
84
85    /// An unexpected internal error.
86    #[error("internal error: {0}")]
87    Internal(String),
88}
89
90/// Result type alias for tenferro operations.
91pub type Result<T> = std::result::Result<T, Error>;