rten_tensor/errors.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
//! Error types that are reported by various tensor operations.
use std::error::Error;
use std::fmt::{Display, Formatter};
use crate::slice_range::SliceRange;
/// Error in a tensor operation if the dimension count is incorrect.
#[derive(Debug, PartialEq)]
pub struct DimensionError {}
impl Display for DimensionError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "dim count is incorrect")
}
}
impl Error for DimensionError {}
/// Errors that can occur when constructing a tensor from existing data.
#[derive(Debug, PartialEq)]
pub enum FromDataError {
/// Some indices will map to offsets that are beyond the end of the storage.
StorageTooShort,
/// The storage length was expected to exactly match the product of the
/// shape, and it did not.
StorageLengthMismatch,
/// Some indices will map to the same offset within the storage.
///
/// This error can only occur when the storage is mutable.
MayOverlap,
}
impl Display for FromDataError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
FromDataError::StorageTooShort => write!(f, "data too short"),
FromDataError::StorageLengthMismatch => write!(f, "data length mismatch"),
FromDataError::MayOverlap => write!(f, "may have internal overlap"),
}
}
}
impl Error for FromDataError {}
/// Errors that can occur when slicing a tensor.
#[derive(Clone, Debug, PartialEq)]
pub enum SliceError {
/// The slice spec has more dimensions than the tensor being sliced.
TooManyDims {
/// Number of axes in the tensor.
ndim: usize,
/// Number of items in the slice spec.
range_ndim: usize,
},
/// An index in the slice spec is out of bounds for the corresponding tensor
/// dimension.
InvalidIndex {
/// Axis that the error applies to.
axis: usize,
/// Index in the slice range.
index: isize,
/// Size of the dimension.
size: usize,
},
/// A range in the slice spec is out of bounds for the corresponding tensor
/// dimension.
InvalidRange {
/// Axis that the error applies to.
axis: usize,
/// The range item.
range: SliceRange,
/// Size of the dimension.
size: usize,
},
/// The step in a slice range is negative, in a context where this is not
/// supported.
InvalidStep {
/// Axis that the error applies to.
axis: usize,
/// Size of the dimension.
step: isize,
},
/// There is a mismatch between the actual and expected number of axes
/// in the output slice.
OutputDimsMismatch { actual: usize, expected: usize },
}
impl Display for SliceError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
SliceError::TooManyDims { ndim, range_ndim } => {
write!(
f,
"slice range has {} items but tensor has only {} dims",
range_ndim, ndim
)
}
SliceError::InvalidIndex { axis, index, size } => write!(
f,
"slice index {} is invalid for axis ({}) of size {}",
index, axis, size
),
SliceError::InvalidRange { axis, range, size } => write!(
f,
"slice range {:?} is invalid for axis ({}) of size {}",
range, axis, size
),
SliceError::InvalidStep { axis, step } => {
write!(f, "slice step {} is invalid for axis {}", step, axis)
}
SliceError::OutputDimsMismatch { actual, expected } => {
write!(
f,
"slice output dims {} does not match expected dims {}",
actual, expected
)
}
}
}
}
impl Error for SliceError {}
/// Errors that can occur while reshaping a layout or tensor.
#[derive(Clone, Debug, PartialEq)]
pub enum ReshapeError {
/// Attempted to reshape a tensor without copying data, but the layout
/// is not contiguous.
NotContiguous,
/// The reshaped layout would have a different length than the current
/// layout.
LengthMismatch,
}
impl std::fmt::Display for ReshapeError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ReshapeError::NotContiguous => write!(f, "view is not contiguous"),
ReshapeError::LengthMismatch => write!(f, "new shape has a different length"),
}
}
}
/// Errors that can occur while expanding a tensor.
#[derive(Clone, Debug, PartialEq)]
pub enum ExpandError {
/// The shape of the source and destination tensor do not match, excluding
/// the dimensions along which expansion is happening.
ShapeMismatch,
/// The tensor cannot be resized without copying into a new buffer.
InsufficientCapacity,
}
impl std::fmt::Display for ExpandError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ExpandError::ShapeMismatch => {
write!(
f,
"non-expanding dimensions of source and destination do not match"
)
}
ExpandError::InsufficientCapacity => {
write!(f, "insufficient capacity for new dimension size")
}
}
}
}