From 986c28d8c4bcc94727adf86c1efec87346d2c6f8 Mon Sep 17 00:00:00 2001 From: Adam Kern Date: Wed, 7 Jan 2026 09:07:27 -0500 Subject: [PATCH 1/2] Revert #1567 to prepare for a patch release. This reverts commit 953f2e9e856139f637feb3c7b321b5bb3fcae533. The commit will now live on the `refactor` branch until more of the new layout code is ready --- src/layout/bitset.rs | 271 ---------------------------------------- src/layout/layoutfmt.rs | 32 +++++ src/layout/mod.rs | 250 +++++++++++++++++++++++++++++++++++- 3 files changed, 279 insertions(+), 274 deletions(-) delete mode 100644 src/layout/bitset.rs create mode 100644 src/layout/layoutfmt.rs diff --git a/src/layout/bitset.rs b/src/layout/bitset.rs deleted file mode 100644 index 4b087ad35..000000000 --- a/src/layout/bitset.rs +++ /dev/null @@ -1,271 +0,0 @@ -//! Compact representations of array layouts. - -use alloc::fmt; - -// Layout is a bitset used for internal layout description of -// arrays, producers and sets of producers. -// The type is public but users don't interact with it. -#[doc(hidden)] -/// Memory layout description -#[derive(Copy, Clone)] -pub struct LayoutBitset(pub(super) u32); - -#[deprecated(since = "0.18.0", note = "Layout has been renamed to LayoutBitset")] -#[allow(dead_code)] -/// Memory layout description, deprecated. See [`LayoutBitset`] instead. -pub type Layout = LayoutBitset; - -impl LayoutBitset -{ - pub(crate) const CORDER: u32 = 0b01; - pub(crate) const FORDER: u32 = 0b10; - pub(crate) const CPREFER: u32 = 0b0100; - pub(crate) const FPREFER: u32 = 0b1000; - - #[inline(always)] - pub(crate) fn is(self, flag: u32) -> bool - { - self.0 & flag != 0 - } - - /// Return layout common to both inputs - #[inline(always)] - pub(crate) fn intersect(self, other: LayoutBitset) -> LayoutBitset - { - LayoutBitset(self.0 & other.0) - } - - /// Return a layout that simultaneously "is" what both of the inputs are - #[inline(always)] - pub(crate) fn also(self, other: LayoutBitset) -> LayoutBitset - { - LayoutBitset(self.0 | other.0) - } - - #[inline(always)] - pub(crate) fn one_dimensional() -> LayoutBitset - { - LayoutBitset::c().also(LayoutBitset::f()) - } - - #[inline(always)] - pub(crate) fn c() -> LayoutBitset - { - LayoutBitset(LayoutBitset::CORDER | LayoutBitset::CPREFER) - } - - #[inline(always)] - pub(crate) fn f() -> LayoutBitset - { - LayoutBitset(LayoutBitset::FORDER | LayoutBitset::FPREFER) - } - - #[inline(always)] - pub(crate) fn cpref() -> LayoutBitset - { - LayoutBitset(LayoutBitset::CPREFER) - } - - #[inline(always)] - pub(crate) fn fpref() -> LayoutBitset - { - LayoutBitset(LayoutBitset::FPREFER) - } - - #[inline(always)] - pub(crate) fn none() -> LayoutBitset - { - LayoutBitset(0) - } - - /// A simple "score" method which scores positive for preferring C-order, negative for F-order - /// Subject to change when we can describe other layouts - #[inline] - pub(crate) fn tendency(self) -> i32 - { - (self.is(LayoutBitset::CORDER) as i32 - self.is(LayoutBitset::FORDER) as i32) - + (self.is(LayoutBitset::CPREFER) as i32 - self.is(LayoutBitset::FPREFER) as i32) - } -} - -const LAYOUT_NAMES: &[&str] = &["C", "F", "c", "f"]; - -impl fmt::Debug for LayoutBitset -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result - { - if self.0 == 0 { - write!(f, "Custom")? - } else { - (0..32).filter(|&i| self.is(1 << i)).try_fold((), |_, i| { - if let Some(name) = LAYOUT_NAMES.get(i) { - write!(f, "{}", name) - } else { - write!(f, "{:#x}", i) - } - })?; - }; - write!(f, " ({:#x})", self.0) - } -} - -#[cfg(test)] -mod tests -{ - use super::*; - use crate::imp_prelude::*; - use crate::NdProducer; - - type M = Array2; - type M1 = Array1; - type M0 = Array0; - - macro_rules! assert_layouts { - ($mat:expr, $($layout:ident),*) => {{ - let layout = $mat.view().layout(); - $( - assert!(layout.is(LayoutBitset::$layout), - "Assertion failed: array {:?} is not layout {}", - $mat, - stringify!($layout)); - )* - }}; - } - - macro_rules! assert_not_layouts { - ($mat:expr, $($layout:ident),*) => {{ - let layout = $mat.view().layout(); - $( - assert!(!layout.is(LayoutBitset::$layout), - "Assertion failed: array {:?} show not have layout {}", - $mat, - stringify!($layout)); - )* - }}; - } - - #[test] - fn contig_layouts() - { - let a = M::zeros((5, 5)); - let b = M::zeros((5, 5).f()); - let ac = a.view().layout(); - let af = b.view().layout(); - assert!(ac.is(LayoutBitset::CORDER) && ac.is(LayoutBitset::CPREFER)); - assert!(!ac.is(LayoutBitset::FORDER) && !ac.is(LayoutBitset::FPREFER)); - assert!(!af.is(LayoutBitset::CORDER) && !af.is(LayoutBitset::CPREFER)); - assert!(af.is(LayoutBitset::FORDER) && af.is(LayoutBitset::FPREFER)); - } - - #[test] - fn contig_cf_layouts() - { - let a = M::zeros((5, 1)); - let b = M::zeros((1, 5).f()); - assert_layouts!(a, CORDER, CPREFER, FORDER, FPREFER); - assert_layouts!(b, CORDER, CPREFER, FORDER, FPREFER); - - let a = M1::zeros(5); - let b = M1::zeros(5.f()); - assert_layouts!(a, CORDER, CPREFER, FORDER, FPREFER); - assert_layouts!(b, CORDER, CPREFER, FORDER, FPREFER); - - let a = M0::zeros(()); - assert_layouts!(a, CORDER, CPREFER, FORDER, FPREFER); - - let a = M::zeros((5, 5)); - let b = M::zeros((5, 5).f()); - let arow = a.slice(s![..1, ..]); - let bcol = b.slice(s![.., ..1]); - assert_layouts!(arow, CORDER, CPREFER, FORDER, FPREFER); - assert_layouts!(bcol, CORDER, CPREFER, FORDER, FPREFER); - - let acol = a.slice(s![.., ..1]); - let brow = b.slice(s![..1, ..]); - assert_not_layouts!(acol, CORDER, CPREFER, FORDER, FPREFER); - assert_not_layouts!(brow, CORDER, CPREFER, FORDER, FPREFER); - } - - #[test] - fn stride_layouts() - { - let a = M::zeros((5, 5)); - - { - let v1 = a.slice(s![1.., ..]).layout(); - let v2 = a.slice(s![.., 1..]).layout(); - - assert!(v1.is(LayoutBitset::CORDER) && v1.is(LayoutBitset::CPREFER)); - assert!(!v1.is(LayoutBitset::FORDER) && !v1.is(LayoutBitset::FPREFER)); - assert!(!v2.is(LayoutBitset::CORDER) && v2.is(LayoutBitset::CPREFER)); - assert!(!v2.is(LayoutBitset::FORDER) && !v2.is(LayoutBitset::FPREFER)); - } - - let b = M::zeros((5, 5).f()); - - { - let v1 = b.slice(s![1.., ..]).layout(); - let v2 = b.slice(s![.., 1..]).layout(); - - assert!(!v1.is(LayoutBitset::CORDER) && !v1.is(LayoutBitset::CPREFER)); - assert!(!v1.is(LayoutBitset::FORDER) && v1.is(LayoutBitset::FPREFER)); - assert!(!v2.is(LayoutBitset::CORDER) && !v2.is(LayoutBitset::CPREFER)); - assert!(v2.is(LayoutBitset::FORDER) && v2.is(LayoutBitset::FPREFER)); - } - } - - #[test] - fn no_layouts() - { - let a = M::zeros((5, 5)); - let b = M::zeros((5, 5).f()); - - // 2D row/column matrixes - let arow = a.slice(s![0..1, ..]); - let acol = a.slice(s![.., 0..1]); - let brow = b.slice(s![0..1, ..]); - let bcol = b.slice(s![.., 0..1]); - assert_layouts!(arow, CORDER, FORDER); - assert_not_layouts!(acol, CORDER, CPREFER, FORDER, FPREFER); - assert_layouts!(bcol, CORDER, FORDER); - assert_not_layouts!(brow, CORDER, CPREFER, FORDER, FPREFER); - - // 2D row/column matrixes - now made with insert axis - for &axis in &[Axis(0), Axis(1)] { - let arow = a.slice(s![0, ..]).insert_axis(axis); - let acol = a.slice(s![.., 0]).insert_axis(axis); - let brow = b.slice(s![0, ..]).insert_axis(axis); - let bcol = b.slice(s![.., 0]).insert_axis(axis); - assert_layouts!(arow, CORDER, FORDER); - assert_not_layouts!(acol, CORDER, CPREFER, FORDER, FPREFER); - assert_layouts!(bcol, CORDER, FORDER); - assert_not_layouts!(brow, CORDER, CPREFER, FORDER, FPREFER); - } - } - - #[test] - fn skip_layouts() - { - let a = M::zeros((5, 5)); - { - let v1 = a.slice(s![..;2, ..]).layout(); - let v2 = a.slice(s![.., ..;2]).layout(); - - assert!(!v1.is(LayoutBitset::CORDER) && v1.is(LayoutBitset::CPREFER)); - assert!(!v1.is(LayoutBitset::FORDER) && !v1.is(LayoutBitset::FPREFER)); - assert!(!v2.is(LayoutBitset::CORDER) && !v2.is(LayoutBitset::CPREFER)); - assert!(!v2.is(LayoutBitset::FORDER) && !v2.is(LayoutBitset::FPREFER)); - } - - let b = M::zeros((5, 5).f()); - { - let v1 = b.slice(s![..;2, ..]).layout(); - let v2 = b.slice(s![.., ..;2]).layout(); - - assert!(!v1.is(LayoutBitset::CORDER) && !v1.is(LayoutBitset::CPREFER)); - assert!(!v1.is(LayoutBitset::FORDER) && !v1.is(LayoutBitset::FPREFER)); - assert!(!v2.is(LayoutBitset::CORDER) && !v2.is(LayoutBitset::CPREFER)); - assert!(!v2.is(LayoutBitset::FORDER) && v2.is(LayoutBitset::FPREFER)); - } - } -} diff --git a/src/layout/layoutfmt.rs b/src/layout/layoutfmt.rs new file mode 100644 index 000000000..f4cf3396f --- /dev/null +++ b/src/layout/layoutfmt.rs @@ -0,0 +1,32 @@ +// Copyright 2017 bluss and ndarray developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::LayoutBitset; + +const LAYOUT_NAMES: &[&str] = &["C", "F", "c", "f"]; + +use std::fmt; + +impl fmt::Debug for LayoutBitset +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + if self.0 == 0 { + write!(f, "Custom")? + } else { + (0..32).filter(|&i| self.is(1 << i)).try_fold((), |_, i| { + if let Some(name) = LAYOUT_NAMES.get(i) { + write!(f, "{}", name) + } else { + write!(f, "{:#x}", i) + } + })?; + }; + write!(f, " ({:#x})", self.0) + } +} diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 7f549ebb2..4c9833e23 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -1,4 +1,248 @@ -mod bitset; +mod layoutfmt; -#[allow(deprecated)] -pub use bitset::{Layout, LayoutBitset}; +// Layout is a bitset used for internal layout description of +// arrays, producers and sets of producers. +// The type is public but users don't interact with it. +#[doc(hidden)] +/// Memory layout description +#[derive(Copy, Clone)] +pub struct LayoutBitset(u32); + +#[deprecated(since = "0.18.0", note = "Layout has been renamed to LayoutBitset")] +#[allow(dead_code)] +/// Memory layout description, deprecated. See [`LayoutBitset`] instead. +pub type Layout = LayoutBitset; + +impl LayoutBitset +{ + pub(crate) const CORDER: u32 = 0b01; + pub(crate) const FORDER: u32 = 0b10; + pub(crate) const CPREFER: u32 = 0b0100; + pub(crate) const FPREFER: u32 = 0b1000; + + #[inline(always)] + pub(crate) fn is(self, flag: u32) -> bool + { + self.0 & flag != 0 + } + + /// Return layout common to both inputs + #[inline(always)] + pub(crate) fn intersect(self, other: LayoutBitset) -> LayoutBitset + { + LayoutBitset(self.0 & other.0) + } + + /// Return a layout that simultaneously "is" what both of the inputs are + #[inline(always)] + pub(crate) fn also(self, other: LayoutBitset) -> LayoutBitset + { + LayoutBitset(self.0 | other.0) + } + + #[inline(always)] + pub(crate) fn one_dimensional() -> LayoutBitset + { + LayoutBitset::c().also(LayoutBitset::f()) + } + + #[inline(always)] + pub(crate) fn c() -> LayoutBitset + { + LayoutBitset(LayoutBitset::CORDER | LayoutBitset::CPREFER) + } + + #[inline(always)] + pub(crate) fn f() -> LayoutBitset + { + LayoutBitset(LayoutBitset::FORDER | LayoutBitset::FPREFER) + } + + #[inline(always)] + pub(crate) fn cpref() -> LayoutBitset + { + LayoutBitset(LayoutBitset::CPREFER) + } + + #[inline(always)] + pub(crate) fn fpref() -> LayoutBitset + { + LayoutBitset(LayoutBitset::FPREFER) + } + + #[inline(always)] + pub(crate) fn none() -> LayoutBitset + { + LayoutBitset(0) + } + + /// A simple "score" method which scores positive for preferring C-order, negative for F-order + /// Subject to change when we can describe other layouts + #[inline] + pub(crate) fn tendency(self) -> i32 + { + (self.is(LayoutBitset::CORDER) as i32 - self.is(LayoutBitset::FORDER) as i32) + + (self.is(LayoutBitset::CPREFER) as i32 - self.is(LayoutBitset::FPREFER) as i32) + } +} + +#[cfg(test)] +mod tests +{ + use super::*; + use crate::imp_prelude::*; + use crate::NdProducer; + + type M = Array2; + type M1 = Array1; + type M0 = Array0; + + macro_rules! assert_layouts { + ($mat:expr, $($layout:ident),*) => {{ + let layout = $mat.view().layout(); + $( + assert!(layout.is(LayoutBitset::$layout), + "Assertion failed: array {:?} is not layout {}", + $mat, + stringify!($layout)); + )* + }}; + } + + macro_rules! assert_not_layouts { + ($mat:expr, $($layout:ident),*) => {{ + let layout = $mat.view().layout(); + $( + assert!(!layout.is(LayoutBitset::$layout), + "Assertion failed: array {:?} show not have layout {}", + $mat, + stringify!($layout)); + )* + }}; + } + + #[test] + fn contig_layouts() + { + let a = M::zeros((5, 5)); + let b = M::zeros((5, 5).f()); + let ac = a.view().layout(); + let af = b.view().layout(); + assert!(ac.is(LayoutBitset::CORDER) && ac.is(LayoutBitset::CPREFER)); + assert!(!ac.is(LayoutBitset::FORDER) && !ac.is(LayoutBitset::FPREFER)); + assert!(!af.is(LayoutBitset::CORDER) && !af.is(LayoutBitset::CPREFER)); + assert!(af.is(LayoutBitset::FORDER) && af.is(LayoutBitset::FPREFER)); + } + + #[test] + fn contig_cf_layouts() + { + let a = M::zeros((5, 1)); + let b = M::zeros((1, 5).f()); + assert_layouts!(a, CORDER, CPREFER, FORDER, FPREFER); + assert_layouts!(b, CORDER, CPREFER, FORDER, FPREFER); + + let a = M1::zeros(5); + let b = M1::zeros(5.f()); + assert_layouts!(a, CORDER, CPREFER, FORDER, FPREFER); + assert_layouts!(b, CORDER, CPREFER, FORDER, FPREFER); + + let a = M0::zeros(()); + assert_layouts!(a, CORDER, CPREFER, FORDER, FPREFER); + + let a = M::zeros((5, 5)); + let b = M::zeros((5, 5).f()); + let arow = a.slice(s![..1, ..]); + let bcol = b.slice(s![.., ..1]); + assert_layouts!(arow, CORDER, CPREFER, FORDER, FPREFER); + assert_layouts!(bcol, CORDER, CPREFER, FORDER, FPREFER); + + let acol = a.slice(s![.., ..1]); + let brow = b.slice(s![..1, ..]); + assert_not_layouts!(acol, CORDER, CPREFER, FORDER, FPREFER); + assert_not_layouts!(brow, CORDER, CPREFER, FORDER, FPREFER); + } + + #[test] + fn stride_layouts() + { + let a = M::zeros((5, 5)); + + { + let v1 = a.slice(s![1.., ..]).layout(); + let v2 = a.slice(s![.., 1..]).layout(); + + assert!(v1.is(LayoutBitset::CORDER) && v1.is(LayoutBitset::CPREFER)); + assert!(!v1.is(LayoutBitset::FORDER) && !v1.is(LayoutBitset::FPREFER)); + assert!(!v2.is(LayoutBitset::CORDER) && v2.is(LayoutBitset::CPREFER)); + assert!(!v2.is(LayoutBitset::FORDER) && !v2.is(LayoutBitset::FPREFER)); + } + + let b = M::zeros((5, 5).f()); + + { + let v1 = b.slice(s![1.., ..]).layout(); + let v2 = b.slice(s![.., 1..]).layout(); + + assert!(!v1.is(LayoutBitset::CORDER) && !v1.is(LayoutBitset::CPREFER)); + assert!(!v1.is(LayoutBitset::FORDER) && v1.is(LayoutBitset::FPREFER)); + assert!(!v2.is(LayoutBitset::CORDER) && !v2.is(LayoutBitset::CPREFER)); + assert!(v2.is(LayoutBitset::FORDER) && v2.is(LayoutBitset::FPREFER)); + } + } + + #[test] + fn no_layouts() + { + let a = M::zeros((5, 5)); + let b = M::zeros((5, 5).f()); + + // 2D row/column matrixes + let arow = a.slice(s![0..1, ..]); + let acol = a.slice(s![.., 0..1]); + let brow = b.slice(s![0..1, ..]); + let bcol = b.slice(s![.., 0..1]); + assert_layouts!(arow, CORDER, FORDER); + assert_not_layouts!(acol, CORDER, CPREFER, FORDER, FPREFER); + assert_layouts!(bcol, CORDER, FORDER); + assert_not_layouts!(brow, CORDER, CPREFER, FORDER, FPREFER); + + // 2D row/column matrixes - now made with insert axis + for &axis in &[Axis(0), Axis(1)] { + let arow = a.slice(s![0, ..]).insert_axis(axis); + let acol = a.slice(s![.., 0]).insert_axis(axis); + let brow = b.slice(s![0, ..]).insert_axis(axis); + let bcol = b.slice(s![.., 0]).insert_axis(axis); + assert_layouts!(arow, CORDER, FORDER); + assert_not_layouts!(acol, CORDER, CPREFER, FORDER, FPREFER); + assert_layouts!(bcol, CORDER, FORDER); + assert_not_layouts!(brow, CORDER, CPREFER, FORDER, FPREFER); + } + } + + #[test] + fn skip_layouts() + { + let a = M::zeros((5, 5)); + { + let v1 = a.slice(s![..;2, ..]).layout(); + let v2 = a.slice(s![.., ..;2]).layout(); + + assert!(!v1.is(LayoutBitset::CORDER) && v1.is(LayoutBitset::CPREFER)); + assert!(!v1.is(LayoutBitset::FORDER) && !v1.is(LayoutBitset::FPREFER)); + assert!(!v2.is(LayoutBitset::CORDER) && !v2.is(LayoutBitset::CPREFER)); + assert!(!v2.is(LayoutBitset::FORDER) && !v2.is(LayoutBitset::FPREFER)); + } + + let b = M::zeros((5, 5).f()); + { + let v1 = b.slice(s![..;2, ..]).layout(); + let v2 = b.slice(s![.., ..;2]).layout(); + + assert!(!v1.is(LayoutBitset::CORDER) && !v1.is(LayoutBitset::CPREFER)); + assert!(!v1.is(LayoutBitset::FORDER) && !v1.is(LayoutBitset::FPREFER)); + assert!(!v2.is(LayoutBitset::CORDER) && !v2.is(LayoutBitset::CPREFER)); + assert!(!v2.is(LayoutBitset::FORDER) && v2.is(LayoutBitset::FPREFER)); + } + } +} From 60a60b03e6496d39ab00cfcafabcaf8b13ae240d Mon Sep 17 00:00:00 2001 From: Adam Kern Date: Wed, 7 Jan 2026 09:08:25 -0500 Subject: [PATCH 2/2] Revert #1563 to prepare for a patch release. This reverts commit d573745d6adee1e96aca8a6d9f47cd48316d331b. The commit will now live on the `refactor` branch until more of the new layout code is ready --- src/indexes.rs | 8 ++-- src/iterators/chunks.rs | 2 +- src/iterators/lanes.rs | 2 +- src/iterators/macros.rs | 2 +- src/iterators/mod.rs | 8 ++-- src/iterators/windows.rs | 4 +- src/layout/layoutfmt.rs | 4 +- src/layout/mod.rs | 89 +++++++++++++++++------------------ src/lib.rs | 3 +- src/parallel/send_producer.rs | 4 +- src/zip/mod.rs | 32 ++++++------- src/zip/ndproducer.rs | 12 ++--- 12 files changed, 82 insertions(+), 88 deletions(-) diff --git a/src/indexes.rs b/src/indexes.rs index a73c7fcb4..0fa2b50fb 100644 --- a/src/indexes.rs +++ b/src/indexes.rs @@ -10,7 +10,7 @@ use crate::dimension::IntoDimension; use crate::split_at::SplitAt; use crate::zip::Offset; use crate::Axis; -use crate::LayoutBitset; +use crate::Layout; use crate::NdProducer; use crate::{ArrayBase, Data}; @@ -193,12 +193,12 @@ impl NdProducer for Indices IndexPtr { index: self.start } } - fn layout(&self) -> LayoutBitset + fn layout(&self) -> Layout { if self.dim.ndim() <= 1 { - LayoutBitset::one_dimensional() + Layout::one_dimensional() } else { - LayoutBitset::none() + Layout::none() } } diff --git a/src/iterators/chunks.rs b/src/iterators/chunks.rs index aff194d53..178ead7e0 100644 --- a/src/iterators/chunks.rs +++ b/src/iterators/chunks.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use crate::imp_prelude::*; use crate::Baseiter; use crate::IntoDimension; -use crate::{LayoutBitset, NdProducer}; +use crate::{Layout, NdProducer}; impl_ndproducer! { ['a, A, D: Dimension] diff --git a/src/iterators/lanes.rs b/src/iterators/lanes.rs index 2f5e14774..9fd39607b 100644 --- a/src/iterators/lanes.rs +++ b/src/iterators/lanes.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use super::LanesIter; use super::LanesIterMut; use crate::imp_prelude::*; -use crate::{LayoutBitset, NdProducer}; +use crate::{Layout, NdProducer}; impl_ndproducer! { ['a, A, D: Dimension] diff --git a/src/iterators/macros.rs b/src/iterators/macros.rs index 041d09021..78697ec25 100644 --- a/src/iterators/macros.rs +++ b/src/iterators/macros.rs @@ -67,7 +67,7 @@ impl<$($typarm)*> NdProducer for $fulltype { self.$base.raw_dim() } - fn layout(&self) -> LayoutBitset { + fn layout(&self) -> Layout { self.$base.layout() } diff --git a/src/iterators/mod.rs b/src/iterators/mod.rs index 85ef78c8c..f7892a8c9 100644 --- a/src/iterators/mod.rs +++ b/src/iterators/mod.rs @@ -1191,9 +1191,9 @@ impl NdProducer for AxisIter<'_, A, D> type Ptr = *mut A; type Stride = isize; - fn layout(&self) -> crate::LayoutBitset + fn layout(&self) -> crate::Layout { - crate::LayoutBitset::one_dimensional() + crate::Layout::one_dimensional() } fn raw_dim(&self) -> Self::Dim @@ -1250,9 +1250,9 @@ impl NdProducer for AxisIterMut<'_, A, D> type Ptr = *mut A; type Stride = isize; - fn layout(&self) -> crate::LayoutBitset + fn layout(&self) -> crate::Layout { - crate::LayoutBitset::one_dimensional() + crate::Layout::one_dimensional() } fn raw_dim(&self) -> Self::Dim diff --git a/src/iterators/windows.rs b/src/iterators/windows.rs index f64b9fd4d..e6fccce46 100644 --- a/src/iterators/windows.rs +++ b/src/iterators/windows.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use super::Baseiter; use crate::imp_prelude::*; use crate::IntoDimension; -use crate::LayoutBitset; +use crate::Layout; use crate::NdProducer; use crate::Slice; @@ -176,7 +176,7 @@ impl<'a, A, D: Dimension> NdProducer for AxisWindows<'a, A, D> Ix1(self.base.raw_dim()[self.axis_idx]) } - fn layout(&self) -> LayoutBitset + fn layout(&self) -> Layout { self.base.layout() } diff --git a/src/layout/layoutfmt.rs b/src/layout/layoutfmt.rs index f4cf3396f..f20f0caaa 100644 --- a/src/layout/layoutfmt.rs +++ b/src/layout/layoutfmt.rs @@ -6,13 +6,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::LayoutBitset; +use super::Layout; const LAYOUT_NAMES: &[&str] = &["C", "F", "c", "f"]; use std::fmt; -impl fmt::Debug for LayoutBitset +impl fmt::Debug for Layout { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 4c9833e23..36853848e 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -6,14 +6,9 @@ mod layoutfmt; #[doc(hidden)] /// Memory layout description #[derive(Copy, Clone)] -pub struct LayoutBitset(u32); +pub struct Layout(u32); -#[deprecated(since = "0.18.0", note = "Layout has been renamed to LayoutBitset")] -#[allow(dead_code)] -/// Memory layout description, deprecated. See [`LayoutBitset`] instead. -pub type Layout = LayoutBitset; - -impl LayoutBitset +impl Layout { pub(crate) const CORDER: u32 = 0b01; pub(crate) const FORDER: u32 = 0b10; @@ -28,52 +23,52 @@ impl LayoutBitset /// Return layout common to both inputs #[inline(always)] - pub(crate) fn intersect(self, other: LayoutBitset) -> LayoutBitset + pub(crate) fn intersect(self, other: Layout) -> Layout { - LayoutBitset(self.0 & other.0) + Layout(self.0 & other.0) } /// Return a layout that simultaneously "is" what both of the inputs are #[inline(always)] - pub(crate) fn also(self, other: LayoutBitset) -> LayoutBitset + pub(crate) fn also(self, other: Layout) -> Layout { - LayoutBitset(self.0 | other.0) + Layout(self.0 | other.0) } #[inline(always)] - pub(crate) fn one_dimensional() -> LayoutBitset + pub(crate) fn one_dimensional() -> Layout { - LayoutBitset::c().also(LayoutBitset::f()) + Layout::c().also(Layout::f()) } #[inline(always)] - pub(crate) fn c() -> LayoutBitset + pub(crate) fn c() -> Layout { - LayoutBitset(LayoutBitset::CORDER | LayoutBitset::CPREFER) + Layout(Layout::CORDER | Layout::CPREFER) } #[inline(always)] - pub(crate) fn f() -> LayoutBitset + pub(crate) fn f() -> Layout { - LayoutBitset(LayoutBitset::FORDER | LayoutBitset::FPREFER) + Layout(Layout::FORDER | Layout::FPREFER) } #[inline(always)] - pub(crate) fn cpref() -> LayoutBitset + pub(crate) fn cpref() -> Layout { - LayoutBitset(LayoutBitset::CPREFER) + Layout(Layout::CPREFER) } #[inline(always)] - pub(crate) fn fpref() -> LayoutBitset + pub(crate) fn fpref() -> Layout { - LayoutBitset(LayoutBitset::FPREFER) + Layout(Layout::FPREFER) } #[inline(always)] - pub(crate) fn none() -> LayoutBitset + pub(crate) fn none() -> Layout { - LayoutBitset(0) + Layout(0) } /// A simple "score" method which scores positive for preferring C-order, negative for F-order @@ -81,8 +76,8 @@ impl LayoutBitset #[inline] pub(crate) fn tendency(self) -> i32 { - (self.is(LayoutBitset::CORDER) as i32 - self.is(LayoutBitset::FORDER) as i32) - + (self.is(LayoutBitset::CPREFER) as i32 - self.is(LayoutBitset::FPREFER) as i32) + (self.is(Layout::CORDER) as i32 - self.is(Layout::FORDER) as i32) + + (self.is(Layout::CPREFER) as i32 - self.is(Layout::FPREFER) as i32) } } @@ -101,7 +96,7 @@ mod tests ($mat:expr, $($layout:ident),*) => {{ let layout = $mat.view().layout(); $( - assert!(layout.is(LayoutBitset::$layout), + assert!(layout.is(Layout::$layout), "Assertion failed: array {:?} is not layout {}", $mat, stringify!($layout)); @@ -113,7 +108,7 @@ mod tests ($mat:expr, $($layout:ident),*) => {{ let layout = $mat.view().layout(); $( - assert!(!layout.is(LayoutBitset::$layout), + assert!(!layout.is(Layout::$layout), "Assertion failed: array {:?} show not have layout {}", $mat, stringify!($layout)); @@ -128,10 +123,10 @@ mod tests let b = M::zeros((5, 5).f()); let ac = a.view().layout(); let af = b.view().layout(); - assert!(ac.is(LayoutBitset::CORDER) && ac.is(LayoutBitset::CPREFER)); - assert!(!ac.is(LayoutBitset::FORDER) && !ac.is(LayoutBitset::FPREFER)); - assert!(!af.is(LayoutBitset::CORDER) && !af.is(LayoutBitset::CPREFER)); - assert!(af.is(LayoutBitset::FORDER) && af.is(LayoutBitset::FPREFER)); + assert!(ac.is(Layout::CORDER) && ac.is(Layout::CPREFER)); + assert!(!ac.is(Layout::FORDER) && !ac.is(Layout::FPREFER)); + assert!(!af.is(Layout::CORDER) && !af.is(Layout::CPREFER)); + assert!(af.is(Layout::FORDER) && af.is(Layout::FPREFER)); } #[test] @@ -172,10 +167,10 @@ mod tests let v1 = a.slice(s![1.., ..]).layout(); let v2 = a.slice(s![.., 1..]).layout(); - assert!(v1.is(LayoutBitset::CORDER) && v1.is(LayoutBitset::CPREFER)); - assert!(!v1.is(LayoutBitset::FORDER) && !v1.is(LayoutBitset::FPREFER)); - assert!(!v2.is(LayoutBitset::CORDER) && v2.is(LayoutBitset::CPREFER)); - assert!(!v2.is(LayoutBitset::FORDER) && !v2.is(LayoutBitset::FPREFER)); + assert!(v1.is(Layout::CORDER) && v1.is(Layout::CPREFER)); + assert!(!v1.is(Layout::FORDER) && !v1.is(Layout::FPREFER)); + assert!(!v2.is(Layout::CORDER) && v2.is(Layout::CPREFER)); + assert!(!v2.is(Layout::FORDER) && !v2.is(Layout::FPREFER)); } let b = M::zeros((5, 5).f()); @@ -184,10 +179,10 @@ mod tests let v1 = b.slice(s![1.., ..]).layout(); let v2 = b.slice(s![.., 1..]).layout(); - assert!(!v1.is(LayoutBitset::CORDER) && !v1.is(LayoutBitset::CPREFER)); - assert!(!v1.is(LayoutBitset::FORDER) && v1.is(LayoutBitset::FPREFER)); - assert!(!v2.is(LayoutBitset::CORDER) && !v2.is(LayoutBitset::CPREFER)); - assert!(v2.is(LayoutBitset::FORDER) && v2.is(LayoutBitset::FPREFER)); + assert!(!v1.is(Layout::CORDER) && !v1.is(Layout::CPREFER)); + assert!(!v1.is(Layout::FORDER) && v1.is(Layout::FPREFER)); + assert!(!v2.is(Layout::CORDER) && !v2.is(Layout::CPREFER)); + assert!(v2.is(Layout::FORDER) && v2.is(Layout::FPREFER)); } } @@ -228,10 +223,10 @@ mod tests let v1 = a.slice(s![..;2, ..]).layout(); let v2 = a.slice(s![.., ..;2]).layout(); - assert!(!v1.is(LayoutBitset::CORDER) && v1.is(LayoutBitset::CPREFER)); - assert!(!v1.is(LayoutBitset::FORDER) && !v1.is(LayoutBitset::FPREFER)); - assert!(!v2.is(LayoutBitset::CORDER) && !v2.is(LayoutBitset::CPREFER)); - assert!(!v2.is(LayoutBitset::FORDER) && !v2.is(LayoutBitset::FPREFER)); + assert!(!v1.is(Layout::CORDER) && v1.is(Layout::CPREFER)); + assert!(!v1.is(Layout::FORDER) && !v1.is(Layout::FPREFER)); + assert!(!v2.is(Layout::CORDER) && !v2.is(Layout::CPREFER)); + assert!(!v2.is(Layout::FORDER) && !v2.is(Layout::FPREFER)); } let b = M::zeros((5, 5).f()); @@ -239,10 +234,10 @@ mod tests let v1 = b.slice(s![..;2, ..]).layout(); let v2 = b.slice(s![.., ..;2]).layout(); - assert!(!v1.is(LayoutBitset::CORDER) && !v1.is(LayoutBitset::CPREFER)); - assert!(!v1.is(LayoutBitset::FORDER) && !v1.is(LayoutBitset::FPREFER)); - assert!(!v2.is(LayoutBitset::CORDER) && !v2.is(LayoutBitset::CPREFER)); - assert!(!v2.is(LayoutBitset::FORDER) && v2.is(LayoutBitset::FPREFER)); + assert!(!v1.is(Layout::CORDER) && !v1.is(Layout::CPREFER)); + assert!(!v1.is(Layout::FORDER) && !v1.is(Layout::FPREFER)); + assert!(!v2.is(Layout::CORDER) && !v2.is(Layout::CPREFER)); + assert!(!v2.is(Layout::FORDER) && v2.is(Layout::FPREFER)); } } } diff --git a/src/lib.rs b/src/lib.rs index 2b9b656e3..41e5ca350 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -222,8 +222,7 @@ mod dimension; pub use crate::zip::{FoldWhile, IntoNdProducer, NdProducer, Zip}; -#[allow(deprecated)] -pub use crate::layout::{Layout, LayoutBitset}; +pub use crate::layout::Layout; /// Implementation's prelude. Common types used everywhere. mod imp_prelude diff --git a/src/parallel/send_producer.rs b/src/parallel/send_producer.rs index ebf973091..ecfb77af0 100644 --- a/src/parallel/send_producer.rs +++ b/src/parallel/send_producer.rs @@ -1,5 +1,5 @@ use crate::imp_prelude::*; -use crate::{LayoutBitset, NdProducer}; +use crate::{Layout, NdProducer}; use std::ops::{Deref, DerefMut}; /// An NdProducer that is unconditionally `Send`. @@ -66,7 +66,7 @@ where P: NdProducer } #[inline(always)] - fn layout(&self) -> LayoutBitset + fn layout(&self) -> Layout { self.inner.layout() } diff --git a/src/zip/mod.rs b/src/zip/mod.rs index 16555721d..668eac093 100644 --- a/src/zip/mod.rs +++ b/src/zip/mod.rs @@ -17,7 +17,7 @@ use crate::imp_prelude::*; use crate::partial::Partial; use crate::AssignElem; use crate::IntoDimension; -use crate::LayoutBitset; +use crate::Layout; use crate::dimension; use crate::indexes::{indices, Indices}; @@ -51,35 +51,35 @@ where E: IntoDimension } /// Compute `Layout` hints for array shape dim, strides -fn array_layout(dim: &D, strides: &D) -> LayoutBitset +fn array_layout(dim: &D, strides: &D) -> Layout { let n = dim.ndim(); if dimension::is_layout_c(dim, strides) { // effectively one-dimensional => C and F layout compatible if n <= 1 || dim.slice().iter().filter(|&&len| len > 1).count() <= 1 { - LayoutBitset::one_dimensional() + Layout::one_dimensional() } else { - LayoutBitset::c() + Layout::c() } } else if n > 1 && dimension::is_layout_f(dim, strides) { - LayoutBitset::f() + Layout::f() } else if n > 1 { if dim[0] > 1 && strides[0] == 1 { - LayoutBitset::fpref() + Layout::fpref() } else if dim[n - 1] > 1 && strides[n - 1] == 1 { - LayoutBitset::cpref() + Layout::cpref() } else { - LayoutBitset::none() + Layout::none() } } else { - LayoutBitset::none() + Layout::none() } } impl LayoutRef where D: Dimension { - pub(crate) fn layout_impl(&self) -> LayoutBitset + pub(crate) fn layout_impl(&self) -> Layout { array_layout(self._dim(), self._strides()) } @@ -194,7 +194,7 @@ pub struct Zip { parts: Parts, dimension: D, - layout: LayoutBitset, + layout: Layout, /// The sum of the layout tendencies of the parts; /// positive for c- and negative for f-layout preference. layout_tendency: i32, @@ -277,7 +277,7 @@ where D: Dimension fn prefer_f(&self) -> bool { - !self.layout.is(LayoutBitset::CORDER) && (self.layout.is(LayoutBitset::FORDER) || self.layout_tendency < 0) + !self.layout.is(Layout::CORDER) && (self.layout.is(Layout::FORDER) || self.layout_tendency < 0) } /// Return an *approximation* to the max stride axis; if @@ -313,7 +313,7 @@ where D: Dimension { if self.dimension.ndim() == 0 { function(acc, unsafe { self.parts.as_ref(self.parts.as_ptr()) }) - } else if self.layout.is(LayoutBitset::CORDER | LayoutBitset::FORDER) { + } else if self.layout.is(Layout::CORDER | Layout::FORDER) { self.for_each_core_contiguous(acc, function) } else { self.for_each_core_strided(acc, function) @@ -325,7 +325,7 @@ where D: Dimension F: FnMut(Acc, P::Item) -> FoldWhile, P: ZippableTuple, { - debug_assert!(self.layout.is(LayoutBitset::CORDER | LayoutBitset::FORDER)); + debug_assert!(self.layout.is(Layout::CORDER | Layout::FORDER)); let size = self.dimension.size(); let ptrs = self.parts.as_ptr(); let inner_strides = self.parts.contiguous_stride(); @@ -442,7 +442,7 @@ where #[inline] pub(crate) fn debug_assert_c_order(self) -> Self { - debug_assert!(self.layout.is(LayoutBitset::CORDER) || self.layout_tendency >= 0 || + debug_assert!(self.layout.is(Layout::CORDER) || self.layout_tendency >= 0 || self.dimension.slice().iter().filter(|&&d| d > 1).count() <= 1, "Assertion failed: traversal is not c-order or 1D for \ layout {:?}, tendency {}, dimension {:?}", @@ -841,7 +841,7 @@ macro_rules! map_impl { // debug assert that the output is contiguous in the memory layout we need if cfg!(debug_assertions) { let out_layout = output.layout(); - assert!(out_layout.is(LayoutBitset::CORDER | LayoutBitset::FORDER)); + assert!(out_layout.is(Layout::CORDER | Layout::FORDER)); assert!( (self.layout_tendency <= 0 && out_layout.tendency() <= 0) || (self.layout_tendency >= 0 && out_layout.tendency() >= 0), diff --git a/src/zip/ndproducer.rs b/src/zip/ndproducer.rs index f06497c29..fe666e81e 100644 --- a/src/zip/ndproducer.rs +++ b/src/zip/ndproducer.rs @@ -1,6 +1,6 @@ use crate::imp_prelude::*; use crate::ArrayRef; -use crate::LayoutBitset; +use crate::Layout; use crate::NdIndex; #[cfg(not(feature = "std"))] use alloc::vec::Vec; @@ -74,7 +74,7 @@ pub trait NdProducer type Stride: Copy; #[doc(hidden)] - fn layout(&self) -> LayoutBitset; + fn layout(&self) -> Layout; /// Return the shape of the producer. fn raw_dim(&self) -> Self::Dim; #[doc(hidden)] @@ -282,7 +282,7 @@ impl<'a, A, D: Dimension> NdProducer for ArrayView<'a, A, D> (**self).as_ptr() as _ } - fn layout(&self) -> LayoutBitset + fn layout(&self) -> Layout { self.layout_impl() } @@ -340,7 +340,7 @@ impl<'a, A, D: Dimension> NdProducer for ArrayViewMut<'a, A, D> (**self).as_ptr() as _ } - fn layout(&self) -> LayoutBitset + fn layout(&self) -> Layout { self.layout_impl() } @@ -398,7 +398,7 @@ impl NdProducer for RawArrayView self.as_ptr() as _ } - fn layout(&self) -> LayoutBitset + fn layout(&self) -> Layout { AsRef::>::as_ref(self).layout_impl() } @@ -457,7 +457,7 @@ impl NdProducer for RawArrayViewMut self.as_ptr() as _ } - fn layout(&self) -> LayoutBitset + fn layout(&self) -> Layout { AsRef::>::as_ref(self).layout_impl() }