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")
            }
        }
    }
}