axonml_core/
error.rs

1//! Error Types - Axonml Core Error Handling
2//!
3//! Provides comprehensive error types for all operations within the Axonml
4//! framework, including device errors, memory allocation failures, and
5//! type mismatches.
6//!
7//! # Key Features
8//! - Unified error type for all Axonml operations
9//! - Detailed error context for debugging
10//! - Integration with `std::error::Error`
11//!
12//! @version 0.1.0
13//! @author `AutomataNexus` Development Team
14
15use thiserror::Error;
16
17use crate::device::Device;
18use crate::dtype::DType;
19
20// =============================================================================
21// Error Types
22// =============================================================================
23
24/// The main error type for Axonml operations.
25#[derive(Error, Debug, Clone, PartialEq)]
26pub enum Error {
27    /// Shape mismatch between tensors.
28    #[error("Shape mismatch: expected {expected:?}, got {actual:?}")]
29    ShapeMismatch {
30        /// The expected shape.
31        expected: Vec<usize>,
32        /// The actual shape.
33        actual: Vec<usize>,
34    },
35
36    /// Data type mismatch between tensors.
37    #[error("DType mismatch: expected {expected:?}, got {actual:?}")]
38    DTypeMismatch {
39        /// The expected data type.
40        expected: DType,
41        /// The actual data type.
42        actual: DType,
43    },
44
45    /// Device mismatch between tensors.
46    #[error("Device mismatch: expected {expected:?}, got {actual:?}")]
47    DeviceMismatch {
48        /// The expected device.
49        expected: Device,
50        /// The actual device.
51        actual: Device,
52    },
53
54    /// Invalid dimension index.
55    #[error("Invalid dimension: index {index} for tensor with {ndim} dimensions")]
56    InvalidDimension {
57        /// The invalid dimension index.
58        index: i64,
59        /// Number of dimensions in the tensor.
60        ndim: usize,
61    },
62
63    /// Index out of bounds.
64    #[error("Index out of bounds: index {index} for dimension of size {size}")]
65    IndexOutOfBounds {
66        /// The invalid index.
67        index: usize,
68        /// The size of the dimension.
69        size: usize,
70    },
71
72    /// Memory allocation failed.
73    #[error("Memory allocation failed: requested {size} bytes on {device:?}")]
74    AllocationFailed {
75        /// The requested size in bytes.
76        size: usize,
77        /// The device on which allocation failed.
78        device: Device,
79    },
80
81    /// Device not available.
82    #[error("Device not available: {device:?}")]
83    DeviceNotAvailable {
84        /// The unavailable device.
85        device: Device,
86    },
87
88    /// Invalid operation for the given tensor.
89    #[error("Invalid operation: {message}")]
90    InvalidOperation {
91        /// Description of why the operation is invalid.
92        message: String,
93    },
94
95    /// Broadcasting failed between shapes.
96    #[error("Cannot broadcast shapes {shape1:?} and {shape2:?}")]
97    BroadcastError {
98        /// The first shape.
99        shape1: Vec<usize>,
100        /// The second shape.
101        shape2: Vec<usize>,
102    },
103
104    /// Empty tensor error.
105    #[error("Operation not supported on empty tensor")]
106    EmptyTensor,
107
108    /// Contiguous tensor required.
109    #[error("Operation requires contiguous tensor")]
110    NotContiguous,
111
112    /// Gradient computation error.
113    #[error("Gradient error: {message}")]
114    GradientError {
115        /// Description of the gradient error.
116        message: String,
117    },
118
119    /// Serialization/deserialization error.
120    #[error("Serialization error: {message}")]
121    SerializationError {
122        /// Description of the serialization error.
123        message: String,
124    },
125
126    /// Internal error (should not happen).
127    #[error("Internal error: {message}")]
128    InternalError {
129        /// Description of the internal error.
130        message: String,
131    },
132}
133
134// =============================================================================
135// Result Type
136// =============================================================================
137
138/// A specialized Result type for Axonml operations.
139pub type Result<T> = core::result::Result<T, Error>;
140
141// =============================================================================
142// Helper Functions
143// =============================================================================
144
145impl Error {
146    /// Creates a new shape mismatch error.
147    #[must_use]
148    pub fn shape_mismatch(expected: &[usize], actual: &[usize]) -> Self {
149        Self::ShapeMismatch {
150            expected: expected.to_vec(),
151            actual: actual.to_vec(),
152        }
153    }
154
155    /// Creates a new invalid operation error.
156    #[must_use]
157    pub fn invalid_operation(message: impl Into<String>) -> Self {
158        Self::InvalidOperation {
159            message: message.into(),
160        }
161    }
162
163    /// Creates a new internal error.
164    #[must_use]
165    pub fn internal(message: impl Into<String>) -> Self {
166        Self::InternalError {
167            message: message.into(),
168        }
169    }
170}
171
172// =============================================================================
173// Tests
174// =============================================================================
175
176#[cfg(test)]
177mod tests {
178    use super::*;
179
180    #[test]
181    fn test_error_display() {
182        let err = Error::shape_mismatch(&[2, 3], &[2, 4]);
183        assert!(err.to_string().contains("Shape mismatch"));
184    }
185
186    #[test]
187    fn test_error_equality() {
188        let err1 = Error::EmptyTensor;
189        let err2 = Error::EmptyTensor;
190        assert_eq!(err1, err2);
191    }
192}