ruda_test_utils/test_tensor/
strides.rs1use ruda_kernel::dsl as kernel_dsl;
2use ruda_kernel::dsl::zspace::Shape;
3use ruda_kernel::dsl::zspace::Strides;
4
5#[derive(Debug, PartialEq, Eq, Default)]
6pub enum StrideSpec {
7 #[default]
8 RowMajor,
9 ColMajor,
10 Custom(Vec<usize>),
11}
12
13pub fn physical_extent(shape: &Shape, strides: &Strides) -> usize {
20 let mut max_offset = 0usize;
21 for (s, d) in strides.iter().zip(shape.iter()) {
22 if *d > 0 && *s > 0 {
23 max_offset += (d - 1) * s;
24 }
25 }
26 max_offset + 1
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32
33 #[test]
34 fn physical_extent_contiguous_row_major() {
35 let shape = Shape::from(vec![2, 3]);
37 let strides = Strides::new(&[3, 1]);
38 assert_eq!(physical_extent(&shape, &strides), 6);
39 }
40
41 #[test]
42 fn physical_extent_jumpy_strides_exceed_logical() {
43 let shape = Shape::from(vec![256, 256]);
46 let strides = Strides::new(&[512, 1]);
47 assert_eq!(physical_extent(&shape, &strides), 130816);
48 assert!(physical_extent(&shape, &strides) > 256 * 256);
50 }
51
52 #[test]
53 fn physical_extent_broadcast_strides_undercount_logical() {
54 let shape = Shape::from(vec![4, 3]);
58 let strides = Strides::new(&[0, 1]);
59 assert_eq!(physical_extent(&shape, &strides), 3);
60 assert!(physical_extent(&shape, &strides) < 4 * 3);
62 }
63}
64
65impl StrideSpec {
66 pub fn compute_strides(&self, shape: &Shape) -> Strides {
67 let n = shape.len();
68 match self {
69 StrideSpec::RowMajor => {
70 assert!(n >= 2, "RowMajor requires at least 2 dimensions");
71 let mut strides = vec![0; n];
72 strides[n - 1] = 1;
73 for i in (0..n - 1).rev() {
74 strides[i] = strides[i + 1] * shape[i + 1];
75 }
76 Strides::new(&strides)
77 }
78 StrideSpec::ColMajor => {
79 assert!(n >= 2, "ColMajor requires at least 2 dimensions");
80 let mut strides = vec![0; n];
81 strides[n - 2] = 1;
82 strides[n - 1] = shape[n - 2];
83 for i in (0..n - 2).rev() {
84 strides[i] = strides[i + 1] * shape[i + 1];
85 }
86 Strides::new(&strides)
87 }
88 StrideSpec::Custom(strides) => {
89 assert!(
90 strides.len() == n,
91 "Custom strides must have the same rank as the shape"
92 );
93 strides.clone().into()
94 }
95 }
96 }
97}