Coverage Report

Created: 2025-10-10 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ndarray-0.16.1/src/layout/mod.rs
Line
Count
Source
1
mod layoutfmt;
2
3
// Layout it a bitset used for internal layout description of
4
// arrays, producers and sets of producers.
5
// The type is public but users don't interact with it.
6
#[doc(hidden)]
7
/// Memory layout description
8
#[derive(Copy, Clone)]
9
pub struct Layout(u32);
10
11
impl Layout
12
{
13
    pub(crate) const CORDER: u32 = 0b01;
14
    pub(crate) const FORDER: u32 = 0b10;
15
    pub(crate) const CPREFER: u32 = 0b0100;
16
    pub(crate) const FPREFER: u32 = 0b1000;
17
18
    #[inline(always)]
19
0
    pub(crate) fn is(self, flag: u32) -> bool
20
    {
21
0
        self.0 & flag != 0
22
0
    }
23
24
    /// Return layout common to both inputs
25
    #[inline(always)]
26
0
    pub(crate) fn intersect(self, other: Layout) -> Layout
27
    {
28
0
        Layout(self.0 & other.0)
29
0
    }
30
31
    /// Return a layout that simultaneously "is" what both of the inputs are
32
    #[inline(always)]
33
0
    pub(crate) fn also(self, other: Layout) -> Layout
34
    {
35
0
        Layout(self.0 | other.0)
36
0
    }
37
38
    #[inline(always)]
39
0
    pub(crate) fn one_dimensional() -> Layout
40
    {
41
0
        Layout::c().also(Layout::f())
42
0
    }
43
44
    #[inline(always)]
45
0
    pub(crate) fn c() -> Layout
46
    {
47
0
        Layout(Layout::CORDER | Layout::CPREFER)
48
0
    }
49
50
    #[inline(always)]
51
0
    pub(crate) fn f() -> Layout
52
    {
53
0
        Layout(Layout::FORDER | Layout::FPREFER)
54
0
    }
55
56
    #[inline(always)]
57
0
    pub(crate) fn cpref() -> Layout
58
    {
59
0
        Layout(Layout::CPREFER)
60
0
    }
61
62
    #[inline(always)]
63
0
    pub(crate) fn fpref() -> Layout
64
    {
65
0
        Layout(Layout::FPREFER)
66
0
    }
67
68
    #[inline(always)]
69
0
    pub(crate) fn none() -> Layout
70
    {
71
0
        Layout(0)
72
0
    }
73
74
    /// A simple "score" method which scores positive for preferring C-order, negative for F-order
75
    /// Subject to change when we can describe other layouts
76
    #[inline]
77
0
    pub(crate) fn tendency(self) -> i32
78
    {
79
0
        (self.is(Layout::CORDER) as i32 - self.is(Layout::FORDER) as i32)
80
0
            + (self.is(Layout::CPREFER) as i32 - self.is(Layout::FPREFER) as i32)
81
0
    }
Unexecuted instantiation: <ndarray::layout::Layout>::tendency
Unexecuted instantiation: <ndarray::layout::Layout>::tendency
82
}
83
84
#[cfg(test)]
85
mod tests
86
{
87
    use super::*;
88
    use crate::imp_prelude::*;
89
    use crate::NdProducer;
90
91
    type M = Array2<f32>;
92
    type M1 = Array1<f32>;
93
    type M0 = Array0<f32>;
94
95
    macro_rules! assert_layouts {
96
        ($mat:expr, $($layout:ident),*) => {{
97
            let layout = $mat.view().layout();
98
            $(
99
            assert!(layout.is(Layout::$layout),
100
                "Assertion failed: array {:?} is not layout {}",
101
                $mat,
102
                stringify!($layout));
103
            )*
104
        }};
105
    }
106
107
    macro_rules! assert_not_layouts {
108
        ($mat:expr, $($layout:ident),*) => {{
109
            let layout = $mat.view().layout();
110
            $(
111
            assert!(!layout.is(Layout::$layout),
112
                "Assertion failed: array {:?} show not have layout {}",
113
                $mat,
114
                stringify!($layout));
115
            )*
116
        }};
117
    }
118
119
    #[test]
120
    fn contig_layouts()
121
    {
122
        let a = M::zeros((5, 5));
123
        let b = M::zeros((5, 5).f());
124
        let ac = a.view().layout();
125
        let af = b.view().layout();
126
        assert!(ac.is(Layout::CORDER) && ac.is(Layout::CPREFER));
127
        assert!(!ac.is(Layout::FORDER) && !ac.is(Layout::FPREFER));
128
        assert!(!af.is(Layout::CORDER) && !af.is(Layout::CPREFER));
129
        assert!(af.is(Layout::FORDER) && af.is(Layout::FPREFER));
130
    }
131
132
    #[test]
133
    fn contig_cf_layouts()
134
    {
135
        let a = M::zeros((5, 1));
136
        let b = M::zeros((1, 5).f());
137
        assert_layouts!(a, CORDER, CPREFER, FORDER, FPREFER);
138
        assert_layouts!(b, CORDER, CPREFER, FORDER, FPREFER);
139
140
        let a = M1::zeros(5);
141
        let b = M1::zeros(5.f());
142
        assert_layouts!(a, CORDER, CPREFER, FORDER, FPREFER);
143
        assert_layouts!(b, CORDER, CPREFER, FORDER, FPREFER);
144
145
        let a = M0::zeros(());
146
        assert_layouts!(a, CORDER, CPREFER, FORDER, FPREFER);
147
148
        let a = M::zeros((5, 5));
149
        let b = M::zeros((5, 5).f());
150
        let arow = a.slice(s![..1, ..]);
151
        let bcol = b.slice(s![.., ..1]);
152
        assert_layouts!(arow, CORDER, CPREFER, FORDER, FPREFER);
153
        assert_layouts!(bcol, CORDER, CPREFER, FORDER, FPREFER);
154
155
        let acol = a.slice(s![.., ..1]);
156
        let brow = b.slice(s![..1, ..]);
157
        assert_not_layouts!(acol, CORDER, CPREFER, FORDER, FPREFER);
158
        assert_not_layouts!(brow, CORDER, CPREFER, FORDER, FPREFER);
159
    }
160
161
    #[test]
162
    fn stride_layouts()
163
    {
164
        let a = M::zeros((5, 5));
165
166
        {
167
            let v1 = a.slice(s![1.., ..]).layout();
168
            let v2 = a.slice(s![.., 1..]).layout();
169
170
            assert!(v1.is(Layout::CORDER) && v1.is(Layout::CPREFER));
171
            assert!(!v1.is(Layout::FORDER) && !v1.is(Layout::FPREFER));
172
            assert!(!v2.is(Layout::CORDER) && v2.is(Layout::CPREFER));
173
            assert!(!v2.is(Layout::FORDER) && !v2.is(Layout::FPREFER));
174
        }
175
176
        let b = M::zeros((5, 5).f());
177
178
        {
179
            let v1 = b.slice(s![1.., ..]).layout();
180
            let v2 = b.slice(s![.., 1..]).layout();
181
182
            assert!(!v1.is(Layout::CORDER) && !v1.is(Layout::CPREFER));
183
            assert!(!v1.is(Layout::FORDER) && v1.is(Layout::FPREFER));
184
            assert!(!v2.is(Layout::CORDER) && !v2.is(Layout::CPREFER));
185
            assert!(v2.is(Layout::FORDER) && v2.is(Layout::FPREFER));
186
        }
187
    }
188
189
    #[test]
190
    fn no_layouts()
191
    {
192
        let a = M::zeros((5, 5));
193
        let b = M::zeros((5, 5).f());
194
195
        // 2D row/column matrixes
196
        let arow = a.slice(s![0..1, ..]);
197
        let acol = a.slice(s![.., 0..1]);
198
        let brow = b.slice(s![0..1, ..]);
199
        let bcol = b.slice(s![.., 0..1]);
200
        assert_layouts!(arow, CORDER, FORDER);
201
        assert_not_layouts!(acol, CORDER, CPREFER, FORDER, FPREFER);
202
        assert_layouts!(bcol, CORDER, FORDER);
203
        assert_not_layouts!(brow, CORDER, CPREFER, FORDER, FPREFER);
204
205
        // 2D row/column matrixes - now made with insert axis
206
        for &axis in &[Axis(0), Axis(1)] {
207
            let arow = a.slice(s![0, ..]).insert_axis(axis);
208
            let acol = a.slice(s![.., 0]).insert_axis(axis);
209
            let brow = b.slice(s![0, ..]).insert_axis(axis);
210
            let bcol = b.slice(s![.., 0]).insert_axis(axis);
211
            assert_layouts!(arow, CORDER, FORDER);
212
            assert_not_layouts!(acol, CORDER, CPREFER, FORDER, FPREFER);
213
            assert_layouts!(bcol, CORDER, FORDER);
214
            assert_not_layouts!(brow, CORDER, CPREFER, FORDER, FPREFER);
215
        }
216
    }
217
218
    #[test]
219
    fn skip_layouts()
220
    {
221
        let a = M::zeros((5, 5));
222
        {
223
            let v1 = a.slice(s![..;2, ..]).layout();
224
            let v2 = a.slice(s![.., ..;2]).layout();
225
226
            assert!(!v1.is(Layout::CORDER) && v1.is(Layout::CPREFER));
227
            assert!(!v1.is(Layout::FORDER) && !v1.is(Layout::FPREFER));
228
            assert!(!v2.is(Layout::CORDER) && !v2.is(Layout::CPREFER));
229
            assert!(!v2.is(Layout::FORDER) && !v2.is(Layout::FPREFER));
230
        }
231
232
        let b = M::zeros((5, 5).f());
233
        {
234
            let v1 = b.slice(s![..;2, ..]).layout();
235
            let v2 = b.slice(s![.., ..;2]).layout();
236
237
            assert!(!v1.is(Layout::CORDER) && !v1.is(Layout::CPREFER));
238
            assert!(!v1.is(Layout::FORDER) && !v1.is(Layout::FPREFER));
239
            assert!(!v2.is(Layout::CORDER) && !v2.is(Layout::CPREFER));
240
            assert!(!v2.is(Layout::FORDER) && v2.is(Layout::FPREFER));
241
        }
242
    }
243
}