Skip to content

Commit 5056ef8

Browse files
authored
Add traits and types to capture dimensionality (#1568)
ndarray has a history of encoding arrays’ dimensionality in the type system; this turns out to be useful both for debugging and for writing complex array libraries. However, some arrays don’t (or can’t) have their dimensionality known at compile time. One good example of this is the output of ArrayBase::squeeze: even if the array’s dimensionality is known before the operation, the dimensionality of the output depends on how many axes have length one. The Dimensionality trait is intended to unify both the known- and unknown-dimensionality cases. Compile-time dimensionalities are represented using NDim, while cases where the dimensionality cannot be known at compile time are represented using DDyn. A key design choice is that there is no way to recover the number of dimensions as a runtime value from a type implementing Dimensionality. A dynamic dimensionality here does not mean “known at runtime”, but rather “cannot be known at compile time”. The actual number of axes is always taken from the array’s shape, which avoids having two separate sources of truth.
1 parent 953f2e9 commit 5056ef8

File tree

5 files changed

+364
-1
lines changed

5 files changed

+364
-1
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ matrixmultiply-threading = ["matrixmultiply/threading"]
7474

7575
portable-atomic-critical-section = ["portable-atomic/critical-section"]
7676

77+
unstable = []
78+
7779

7880
[target.'cfg(not(target_has_atomic = "ptr"))'.dependencies]
7981
portable-atomic = { version = "1.6.0" }

src/dimension/dimension_trait.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use super::conversion::Convert;
1717
use super::ops::DimAdd;
1818
use super::{stride_offset, stride_offset_checked};
1919
use crate::itertools::{enumerate, zip};
20+
#[cfg(feature = "unstable")]
21+
use crate::layout::dimensionality::*;
2022
use crate::IntoDimension;
2123
use crate::RemoveAxis;
2224
use crate::{ArrayView1, ArrayViewMut1};
@@ -76,6 +78,10 @@ pub trait Dimension:
7678
/// Next larger dimension
7779
type Larger: Dimension + RemoveAxis;
7880

81+
/// The dimensionality of the type, under the new, unstable API.
82+
#[cfg(feature = "unstable")]
83+
type Rank: Dimensionality;
84+
7985
/// Returns the number of dimensions (number of axes).
8086
fn ndim(&self) -> usize;
8187

@@ -420,6 +426,8 @@ impl Dimension for Dim<[Ix; 0]>
420426
type Pattern = ();
421427
type Smaller = Self;
422428
type Larger = Ix1;
429+
#[cfg(feature = "unstable")]
430+
type Rank = D0;
423431
// empty product is 1 -> size is 1
424432
#[inline]
425433
fn ndim(&self) -> usize
@@ -470,6 +478,8 @@ impl Dimension for Dim<[Ix; 1]>
470478
type Pattern = Ix;
471479
type Smaller = Ix0;
472480
type Larger = Ix2;
481+
#[cfg(feature = "unstable")]
482+
type Rank = D1;
473483
#[inline]
474484
fn ndim(&self) -> usize
475485
{
@@ -603,6 +613,8 @@ impl Dimension for Dim<[Ix; 2]>
603613
type Pattern = (Ix, Ix);
604614
type Smaller = Ix1;
605615
type Larger = Ix3;
616+
#[cfg(feature = "unstable")]
617+
type Rank = D2;
606618
#[inline]
607619
fn ndim(&self) -> usize
608620
{
@@ -778,6 +790,8 @@ impl Dimension for Dim<[Ix; 3]>
778790
type Pattern = (Ix, Ix, Ix);
779791
type Smaller = Ix2;
780792
type Larger = Ix4;
793+
#[cfg(feature = "unstable")]
794+
type Rank = D3;
781795
#[inline]
782796
fn ndim(&self) -> usize
783797
{
@@ -910,6 +924,8 @@ macro_rules! large_dim {
910924
type Pattern = $pattern;
911925
type Smaller = Dim<[Ix; $n - 1]>;
912926
type Larger = $larger;
927+
#[cfg(feature = "unstable")]
928+
type Rank = NDim<$n>;
913929
#[inline]
914930
fn ndim(&self) -> usize { $n }
915931
#[inline]
@@ -960,6 +976,8 @@ impl Dimension for IxDyn
960976
type Pattern = Self;
961977
type Smaller = Self;
962978
type Larger = Self;
979+
#[cfg(feature = "unstable")]
980+
type Rank = DDyn;
963981
#[inline]
964982
fn ndim(&self) -> usize
965983
{

0 commit comments

Comments
 (0)