Skip to main content

StridedView

Struct StridedView 

pub struct StridedView<'a, T, Op = Identity> { /* private fields */ }
Expand description

Dynamic-rank immutable strided view with lazy element operations.

This is the Julia-equivalent StridedView type with:

  • Dynamic rank, with metadata stored inline for up to INLINE_RANK dimensions (StridedView::new copies the caller’s layout, so the view borrows only the element data)
  • Lazy element operations via the Op type parameter
  • Zero-copy transformations (permute, transpose, adjoint, conj)

§Type Parameters

  • 'a: Lifetime of the underlying data
  • T: Element type
  • Op: Element operation applied lazily on access (default: Identity)

§Size

The inline metadata makes the view 184 bytes on 64-bit targets for usize/isize strides.

§Auto traits

The view borrows its elements, so it is Send only when T: Sync (a shared slice is). A view of non-Sync data is not Send:

ⓘ
use std::cell::Cell;
use strided_view::StridedView;

fn assert_send<T: Send>() {}
assert_send::<StridedView<'static, Cell<i32>>>();

Implementations§

§

impl<'a, T, Op> StridedView<'a, T, Op>

pub fn new( data: &'a [T], dims: &[usize], strides: &[isize], offset: isize, ) -> Result<StridedView<'a, T, Op>, StridedError>

Create an immutable strided view, copying the caller’s metadata inline.

The layout is copied into the view’s inline storage, so it does not need to outlive the view and no heap allocation happens at rank <= INLINE_RANK. The view’s lifetime is tied to data only.

§Examples
use strided_view::StridedView;

let data = [1.0f64, 2.0, 3.0, 4.0, 5.0, 6.0];
let view = StridedView::<f64>::new(&data, &[2, 3], &[1, 2], 0).unwrap();
assert_eq!(view.dims(), &[2, 3]);
assert_eq!(view.get(&[1, 2]), 6.0);

pub unsafe fn new_unchecked( data: &'a [T], dims: &[usize], strides: &[isize], offset: isize, ) -> StridedView<'a, T, Op>

Create a view without bounds checking, copying the caller’s metadata.

§Safety

The caller must ensure all index combinations stay within bounds.

§Examples
use strided_view::StridedView;

let data = [1.0f64, 2.0, 3.0, 4.0];
let view = unsafe { StridedView::<f64>::new_unchecked(&data, &[2, 2], &[1, 2], 0) };
assert_eq!(view.ndim(), 2);

pub fn dims(&self) -> &[usize]

Returns the shape (dimension sizes) of this view.

pub fn strides(&self) -> &[isize]

Returns the strides (in units of T) for each dimension.

pub fn offset(&self) -> isize

Returns the byte offset into the backing data.

pub fn ndim(&self) -> usize

Returns the number of dimensions (rank).

pub fn len(&self) -> usize

Returns the total number of elements.

§Panics

Panics when the element count does not fit usize, which only a broadcast (stride-0) layout can reach.

pub fn is_empty(&self) -> bool

Returns true if any dimension is zero.

pub fn data(&self) -> &'a [T]

Returns a reference to the backing data slice.

pub fn ptr(&self) -> *const T

Raw const pointer to element at the view’s base offset.

pub fn permute( &self, perm: &[usize], ) -> Result<StridedView<'a, T, Op>, StridedError>

Permute dimensions.

pub fn diagonal_view( &self, axis_pairs: &[(usize, usize)], ) -> Result<StridedView<'a, T, Op>, StridedError>

Create a diagonal view by fusing repeated axis pairs via stride trick (zero-copy).

Each pair (a, b) ties axes a and b to one index. Pairs that share an axis chain into one class ([(0, 1), (1, 2)] and [(0, 1), (0, 2)] both tie axes 0, 1 and 2), and each class becomes one axis:

  • New stride = the sum of the strides of the axes in the class
  • New dim = the minimum of their dims
  • The class sits at its lowest-numbered axis; the others are removed
  • Pairs use original axis numbering; their order does not matter, and repeating a pair has no further effect
§Errors

Returns StridedError::InvalidAxis when a pair names an axis outside the rank or names the same axis twice, and StridedError::OffsetOverflow when a fused stride does not fit isize or the fused layout reaches past the backing allocation.

§Example

A[i,i,j] shape=[n,n,m] strides=[s0,s1,s2] -> shape=[n,m] strides=[s0+s1, s2]

pub fn broadcast( &self, target_dims: &[usize], ) -> Result<StridedView<'a, T, Op>, StridedError>

Broadcast this view to a target shape.

Size-1 dimensions are expanded (stride set to 0) to match target.

§

impl<'a, T, Op> StridedView<'a, T, Op>

Composition methods: require T: ElementOpApply and Op: ComposableElementOp<T>.

pub fn transpose_2d( &self, ) -> Result<StridedView<'a, T, <Op as ComposableElementOp<T>>::ComposeTranspose>, StridedError>

Transpose a 2D view: reverses dimensions and composes the Transpose element op.

Julia equivalent: Base.transpose(a::AbstractStridedView{<:Any, 2})

pub fn adjoint_2d( &self, ) -> Result<StridedView<'a, T, <Op as ComposableElementOp<T>>::ComposeAdjoint>, StridedError>

Adjoint (conjugate transpose) of a 2D view.

Julia equivalent: Base.adjoint(a::AbstractStridedView{<:Any, 2})

pub fn conj( &self, ) -> StridedView<'a, T, <Op as ComposableElementOp<T>>::ComposeConj>

Complex conjugate (compose Conj without changing dims/strides).

Julia equivalent: Base.conj(a::AbstractStridedView)

§

impl<'a, T, Op> StridedView<'a, T, Op>
where T: Copy, Op: ElementOp<T>,

Element access: requires Op: ElementOp<T>.

pub fn get(&self, indices: &[usize]) -> T

Get an element with the element operation applied.

§Panics

Panics if indices.len() is not the view’s rank, an index is out of bounds, or the indexed offset does not fit isize.

pub unsafe fn get_unchecked(&self, indices: &[usize]) -> T

Get an element without bounds checking.

§Safety

Caller must ensure indices are within bounds.

Trait Implementations§

§

impl<T, Op> Clone for StridedView<'_, T, Op>

§

fn clone(&self) -> StridedView<'_, T, Op>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl<T, Op> Debug for StridedView<'_, T, Op>
where T: Debug,

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<T, Op> Send for StridedView<'_, T, Op>
where T: Sync, Op: Send,

§

impl<T, Op> Sync for StridedView<'_, T, Op>
where T: Sync, Op: Sync,

Auto Trait Implementations§

§

impl<'a, T, Op> Freeze for StridedView<'a, T, Op>

§

impl<'a, T, Op> RefUnwindSafe for StridedView<'a, T, Op>

§

impl<'a, T, Op> Unpin for StridedView<'a, T, Op>
where Op: Unpin,

§

impl<'a, T, Op> UnsafeUnpin for StridedView<'a, T, Op>

§

impl<'a, T, Op> UnwindSafe for StridedView<'a, T, Op>
where T: RefUnwindSafe, Op: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

§

fn simd_from(_simd: S, value: T) -> T

§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

§

fn simd_into(self, simd: S) -> T

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.