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}