use std::fmt;
pub type RusTorchResult<T> = crate::error::RusTorchResult<T>;
#[derive(Debug)]
pub enum RusTorchError {
TensorError(TensorError),
GpuError(GpuError),
DistributedError(DistributedError),
NeuralNetworkError(NeuralNetworkError),
OptimizationError(OptimizationError),
DataError(DataError),
MemoryError(MemoryError),
IoError(std::io::Error),
Generic(String),
}
#[derive(Debug, Clone)]
pub enum TensorError {
ShapeMismatch {
expected: Vec<usize>,
actual: Vec<usize>,
},
DimensionMismatch {
lhs: Vec<usize>,
rhs: Vec<usize>,
},
InsufficientDimensions {
required: usize,
actual: usize,
},
InvalidShape(Vec<usize>),
InvalidIndex(Vec<usize>),
InvalidOperation(String),
EmptyTensor,
DataTypeError(String),
}
#[derive(Debug, Clone)]
pub enum GpuError {
DeviceNotFound(usize),
DeviceNotSupported(String),
MemoryAllocationFailed(usize),
MemoryTransferFailed(String),
KernelCompilationFailed(String),
KernelExecutionFailed(String),
ContextCreationFailed(String),
InvalidDevice(String),
OutOfMemory,
DriverError(String),
}
#[derive(Debug, Clone)]
pub enum DistributedError {
BackendNotSupported(String),
CommunicationFailed(String),
ProcessGroupError(String),
SynchronizationFailed(String),
NodeConnectionFailed(String),
InvalidRank(i32),
InvalidWorldSize(i32),
TimeoutError(String),
NetworkError(String),
}
#[derive(Debug, Clone)]
pub enum NeuralNetworkError {
LayerError(String),
ActivationError(String),
LossError(String),
ForwardPassError(String),
BackwardPassError(String),
ParameterError(String),
ModelError(String),
}
#[derive(Debug, Clone)]
pub enum OptimizationError {
OptimizerError(String),
SchedulerError(String),
GradientError(String),
ConvergenceError(String),
LearningRateError(String),
}
#[derive(Debug, Clone)]
pub enum DataError {
DatasetError(String),
DataLoaderError(String),
BatchError(String),
TransformError(String),
FileError(String),
}
#[derive(Debug, Clone)]
pub enum MemoryError {
AllocationFailed(usize),
DeallocationFailed(String),
AlignmentError(usize),
PoolExhausted,
InvalidPointer,
MemoryLeak(String),
}
impl fmt::Display for RusTorchError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RusTorchError::TensorError(e) => write!(f, "Tensor error: {}", e),
RusTorchError::GpuError(e) => write!(f, "GPU error: {}", e),
RusTorchError::DistributedError(e) => write!(f, "Distributed error: {}", e),
RusTorchError::NeuralNetworkError(e) => write!(f, "Neural network error: {}", e),
RusTorchError::OptimizationError(e) => write!(f, "Optimization error: {}", e),
RusTorchError::DataError(e) => write!(f, "Data error: {}", e),
RusTorchError::MemoryError(e) => write!(f, "Memory error: {}", e),
RusTorchError::IoError(e) => write!(f, "I/O error: {}", e),
RusTorchError::Generic(msg) => write!(f, "Error: {}", msg),
}
}
}
impl fmt::Display for TensorError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TensorError::ShapeMismatch { expected, actual } => {
write!(
f,
"Shape mismatch: expected {:?}, got {:?}",
expected, actual
)
}
TensorError::DimensionMismatch { lhs, rhs } => {
write!(f, "Dimension mismatch: {:?} vs {:?}", lhs, rhs)
}
TensorError::InsufficientDimensions { required, actual } => {
write!(
f,
"Insufficient dimensions: required {}, got {}",
required, actual
)
}
TensorError::InvalidShape(shape) => write!(f, "Invalid shape: {:?}", shape),
TensorError::InvalidIndex(index) => write!(f, "Invalid index: {:?}", index),
TensorError::InvalidOperation(op) => write!(f, "Invalid operation: {}", op),
TensorError::EmptyTensor => write!(f, "Operation on empty tensor"),
TensorError::DataTypeError(msg) => write!(f, "Data type error: {}", msg),
}
}
}
impl fmt::Display for GpuError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
GpuError::DeviceNotFound(id) => write!(f, "GPU device {} not found", id),
GpuError::DeviceNotSupported(device) => {
write!(f, "GPU device not supported: {}", device)
}
GpuError::MemoryAllocationFailed(size) => {
write!(f, "GPU memory allocation failed: {} bytes", size)
}
GpuError::MemoryTransferFailed(msg) => write!(f, "GPU memory transfer failed: {}", msg),
GpuError::KernelCompilationFailed(msg) => {
write!(f, "GPU kernel compilation failed: {}", msg)
}
GpuError::KernelExecutionFailed(msg) => {
write!(f, "GPU kernel execution failed: {}", msg)
}
GpuError::ContextCreationFailed(msg) => {
write!(f, "GPU context creation failed: {}", msg)
}
GpuError::InvalidDevice(device) => write!(f, "Invalid GPU device: {}", device),
GpuError::OutOfMemory => write!(f, "GPU out of memory"),
GpuError::DriverError(msg) => write!(f, "GPU driver error: {}", msg),
}
}
}
impl fmt::Display for DistributedError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DistributedError::BackendNotSupported(backend) => {
write!(f, "Distributed backend not supported: {}", backend)
}
DistributedError::CommunicationFailed(msg) => {
write!(f, "Distributed communication failed: {}", msg)
}
DistributedError::ProcessGroupError(msg) => {
write!(f, "Process group error: {}", msg)
}
DistributedError::SynchronizationFailed(msg) => {
write!(f, "Synchronization failed: {}", msg)
}
DistributedError::NodeConnectionFailed(msg) => {
write!(f, "Node connection failed: {}", msg)
}
DistributedError::InvalidRank(rank) => write!(f, "Invalid rank: {}", rank),
DistributedError::InvalidWorldSize(size) => write!(f, "Invalid world size: {}", size),
DistributedError::TimeoutError(msg) => write!(f, "Timeout error: {}", msg),
DistributedError::NetworkError(msg) => write!(f, "Network error: {}", msg),
}
}
}
impl fmt::Display for NeuralNetworkError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NeuralNetworkError::LayerError(msg) => write!(f, "Layer error: {}", msg),
NeuralNetworkError::ActivationError(msg) => write!(f, "Activation error: {}", msg),
NeuralNetworkError::LossError(msg) => write!(f, "Loss error: {}", msg),
NeuralNetworkError::ForwardPassError(msg) => write!(f, "Forward pass error: {}", msg),
NeuralNetworkError::BackwardPassError(msg) => write!(f, "Backward pass error: {}", msg),
NeuralNetworkError::ParameterError(msg) => write!(f, "Parameter error: {}", msg),
NeuralNetworkError::ModelError(msg) => write!(f, "Model error: {}", msg),
}
}
}
impl fmt::Display for OptimizationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
OptimizationError::OptimizerError(msg) => write!(f, "Optimizer error: {}", msg),
OptimizationError::SchedulerError(msg) => write!(f, "Scheduler error: {}", msg),
OptimizationError::GradientError(msg) => write!(f, "Gradient error: {}", msg),
OptimizationError::ConvergenceError(msg) => write!(f, "Convergence error: {}", msg),
OptimizationError::LearningRateError(msg) => write!(f, "Learning rate error: {}", msg),
}
}
}
impl fmt::Display for DataError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DataError::DatasetError(msg) => write!(f, "Dataset error: {}", msg),
DataError::DataLoaderError(msg) => write!(f, "DataLoader error: {}", msg),
DataError::BatchError(msg) => write!(f, "Batch error: {}", msg),
DataError::TransformError(msg) => write!(f, "Transform error: {}", msg),
DataError::FileError(msg) => write!(f, "File error: {}", msg),
}
}
}
impl fmt::Display for MemoryError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MemoryError::AllocationFailed(size) => {
write!(f, "Memory allocation failed: {} bytes", size)
}
MemoryError::DeallocationFailed(msg) => {
write!(f, "Memory deallocation failed: {}", msg)
}
MemoryError::AlignmentError(alignment) => {
write!(f, "Memory alignment error: {} bytes", alignment)
}
MemoryError::PoolExhausted => write!(f, "Memory pool exhausted"),
MemoryError::InvalidPointer => write!(f, "Invalid memory pointer"),
MemoryError::MemoryLeak(msg) => write!(f, "Memory leak detected: {}", msg),
}
}
}
impl std::error::Error for RusTorchError {}
impl std::error::Error for TensorError {}
impl std::error::Error for GpuError {}
impl std::error::Error for DistributedError {}
impl std::error::Error for NeuralNetworkError {}
impl std::error::Error for OptimizationError {}
impl std::error::Error for DataError {}
impl std::error::Error for MemoryError {}
impl From<std::io::Error> for RusTorchError {
fn from(err: std::io::Error) -> Self {
RusTorchError::IoError(err)
}
}
impl From<TensorError> for RusTorchError {
fn from(err: TensorError) -> Self {
RusTorchError::TensorError(err)
}
}
impl From<GpuError> for RusTorchError {
fn from(err: GpuError) -> Self {
RusTorchError::GpuError(err)
}
}
impl From<DistributedError> for RusTorchError {
fn from(err: DistributedError) -> Self {
RusTorchError::DistributedError(err)
}
}
impl From<NeuralNetworkError> for RusTorchError {
fn from(err: NeuralNetworkError) -> Self {
RusTorchError::NeuralNetworkError(err)
}
}
impl From<OptimizationError> for RusTorchError {
fn from(err: OptimizationError) -> Self {
RusTorchError::OptimizationError(err)
}
}
impl From<DataError> for RusTorchError {
fn from(err: DataError) -> Self {
RusTorchError::DataError(err)
}
}
impl From<MemoryError> for RusTorchError {
fn from(err: MemoryError) -> Self {
RusTorchError::MemoryError(err)
}
}
#[macro_export]
macro_rules! tensor_error {
($variant:ident) => {
RusTorchError::TensorError(TensorError::$variant)
};
($variant:ident, $($arg:expr),+) => {
RusTorchError::TensorError(TensorError::$variant { $($arg),+ })
};
}
#[macro_export]
macro_rules! gpu_error {
($variant:ident) => {
RusTorchError::GpuError(GpuError::$variant)
};
($variant:ident, $arg:expr) => {
RusTorchError::GpuError(GpuError::$variant($arg))
};
}
#[macro_export]
macro_rules! distributed_error {
($variant:ident, $arg:expr) => {
RusTorchError::DistributedError(DistributedError::$variant($arg))
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let tensor_err = RusTorchError::TensorError(TensorError::EmptyTensor);
assert!(tensor_err.to_string().contains("empty tensor"));
let gpu_err = RusTorchError::GpuError(GpuError::OutOfMemory);
assert!(gpu_err.to_string().contains("out of memory"));
}
#[test]
fn test_error_conversion() {
let tensor_err = TensorError::EmptyTensor;
let rustorch_err: RusTorchError = tensor_err.into();
matches!(rustorch_err, RusTorchError::TensorError(_));
}
#[test]
fn test_error_macros() {
let err = tensor_error!(EmptyTensor);
matches!(err, RusTorchError::TensorError(TensorError::EmptyTensor));
let err = gpu_error!(OutOfMemory);
matches!(err, RusTorchError::GpuError(GpuError::OutOfMemory));
}
}