Struct Layout

Source
pub struct Layout<D>
where D: DimBaseAPI,
{ /* private fields */ }
Expand description

Layout of tensor.

Layout is a struct that contains shape, stride, and offset of tensor.

  • Shape is the size of each dimension of tensor.
  • Stride is the number of elements to skip to get to the next element in each dimension.
  • Offset is the starting position of tensor.

§Layout API document

Layout defines how elements will be accessed alongwith vector of data.

§Definition

We use notation $n$ as number of dimension, and $0 \leqslant k < n$ as a specific dimension.

Layout $L(\bm{d}, \bm{t}, s)$ contains three components:

  • shape $\bm{d} = (d_0, d_1, \cdots, d_{n - 1})$, where $d_k \geqslant 0$, getter function Layout::shape.
  • stride $\bm{t} = (t_0, t_1, \cdots, t_{n - 1})$, where $t_k \neq 0$, getter function Layout::stride.
  • offset $s$, where $s \geqslant 0$, getter function Layout::offset.

For index computation, indices will also be involved:

  • indices $\bm{i} = (i_0, i_1, \cdots, i_{n - 1})$, where $0 \leqslant i_k < d_k$

For a tensor, we generally use an array ($m_z$, $z \geqslant 0$) to store data in memory. With layout $L(\bm{d}, \bm{t}, s)$, the memory pointer for element at index $\bm{i}$ should be $$ z(\bm{i}) = s + \bm{i} \cdot \bm{t} = s + \sum_{k = 0}^{n - 1} i_k t_k $$

Note that in actual program, it is allowed to have negative indices $\tilde i_k \in [-d_k, d_k)$: $$ i_k = \begin{cases} \tilde i_k & i_k \in [0, d_k) \\ \tilde i_k + d_k & i_k \in [-d_k, 0) \end{cases} $$

Implementations§

Source§

impl<D> Layout<D>
where D: DimBaseAPI,

Source

pub fn size_non_broadcast(&self) -> usize

Get the size of the non-broadcasted part.

Equivalent to size() if there is no broadcast (setting axis size = 1 where stride = 0).

Source

pub fn is_broadcasted(&self) -> bool

Check whether current layout has been broadcasted.

This check is done by checking whether any stride of axis is zero.

Source§

impl<D> Layout<D>
where D: DimBaseAPI,

Getter/setter functions for layout.

Source

pub fn shape(&self) -> &D

Shape of tensor. Getter function.

Source

pub fn stride(&self) -> &<D as DimBaseAPI>::Stride

Stride of tensor. Getter function.

Source

pub fn offset(&self) -> usize

Starting offset of tensor. Getter function.

Source

pub fn ndim(&self) -> usize

Number of dimensions of tensor.

Source

pub fn size(&self) -> usize

Total number of elements in tensor.

§Note

This function uses cached size, instead of evaluating from shape.

Source

pub unsafe fn set_offset(&mut self, offset: usize) -> &mut Layout<D>

Manually set offset.

§Safety

We will not check whether this offset is valid or not. In most cases, it is not intended to be used by user.

Source§

impl<D> Layout<D>

Properties of layout.

Source

pub fn f_prefer(&self) -> bool

Whether this tensor is f-preferred.

Source

pub fn c_prefer(&self) -> bool

Whether this tensor is c-preferred.

Source

pub fn ndim_of_f_contig(&self) -> usize

Least number of dimensions that is f-contiguous for layout.

This function can be useful determining when to iterate by contiguous, and when to iterate by index.

Source

pub fn ndim_of_c_contig(&self) -> usize

Least number of dimensions that is c-contiguous for layout.

This function can be useful determining when to iterate by contiguous, and when to iterate by index.

Source

pub fn f_contig(&self) -> bool

Whether this tensor is f-contiguous.

Special cases

  • When length of a dimension is one, then stride to that dimension is not important.
  • When length of a dimension is zero, then tensor contains no elements, thus f-contiguous.
Source

pub fn c_contig(&self) -> bool

Whether this tensor is c-contiguous.

Special cases

  • When length of a dimension is one, then stride to that dimension is not important.
  • When length of a dimension is zero, then tensor contains no elements, thus c-contiguous.
Source

pub fn index_f(&self, index: &[isize]) -> Result<usize, Error>

Index of tensor by list of indexes to dimensions.

This function does not optimized for performance.

Source

pub fn index(&self, index: &[isize]) -> usize

Index of tensor by list of indexes to dimensions.

This function does not optimized for performance. Negative index allowed.

§Panics
  • Index greater than shape
Source

pub fn bounds_index(&self) -> Result<(usize, usize), Error>

Index range bounds of current layout. This bound is [min, max), which could be feed into range (min..max). If min == max, then this layout should not contains any element.

This function will raise error when minimum index is smaller than zero.

Source

pub fn check_strides(&self) -> Result<(), Error>

Check if strides is correct (no elemenets can overlap).

This will check if all number of elements in dimension of small strides is less than larger strides. For example of valid stride:

shape:  (3,    2,  6)  -> sorted ->  ( 3,   6,   2)
stride: (3, -300, 15)  -> sorted ->  ( 3,  15, 300)
number of elements:                    9,  90,
stride of next dimension              15, 300,
number of elem < stride of next dim?   +,   +,

Special cases

  • if length of tensor is zero, then strides will always be correct.
  • if certain dimension is one, then check for this stride will be ignored.
§TODO

Correctness of this function is not fully ensured.

Source

pub fn diagonal( &self, offset: Option<isize>, axis1: Option<isize>, axis2: Option<isize>, ) -> Result<Layout<<D as DimSmallerOneAPI>::SmallerOne>, Error>
where D: DimSmallerOneAPI,

Source§

impl<D> Layout<D>
where D: DimBaseAPI,

Constructors of layout. See also DimLayoutContigAPI layout from shape directly.

Source

pub fn new( shape: D, stride: <D as DimBaseAPI>::Stride, offset: usize, ) -> Result<Layout<D>, Error>

Generate new layout by providing everything.

§Error when
  • Shape and stride length mismatch
  • Strides is correct (no elements can overlap)
  • Minimum bound is not negative
Source

pub unsafe fn new_unchecked( shape: D, stride: <D as DimBaseAPI>::Stride, offset: usize, ) -> Layout<D>

Generate new layout by providing everything, without checking bounds and strides.

§Safety

This function does not check whether layout is valid.

Source

pub fn new_shape(&self) -> D

New zero shape, which number of dimensions are the same to current layout.

Source

pub fn new_stride(&self) -> <D as DimBaseAPI>::Stride

New zero stride, which number of dimensions are the same to current layout.

Source§

impl<D> Layout<D>

Manuplation of layout.

Source

pub fn transpose(&self, axes: &[isize]) -> Result<Layout<D>, Error>

Transpose layout by permutation.

§See also
Source

pub fn permute_dims(&self, axes: &[isize]) -> Result<Layout<D>, Error>

Transpose layout by permutation.

This is the same function to Layout::transpose

Source

pub fn reverse_axes(&self) -> Layout<D>

Reverse axes of layout.

Source

pub fn swapaxes(&self, axis1: isize, axis2: isize) -> Result<Layout<D>, Error>

Swap axes of layout.

Source§

impl<D> Layout<D>

Fast indexing and utilities of layout.

These functions are mostly internal to this crate.

Source

pub unsafe fn index_uncheck(&self, index: &[usize]) -> isize

Index of tensor by list of indexes to dimensions.

§Safety

This function does not check for bounds, including

  • Negative index
  • Index greater than shape

Due to these reasons, this function may well give index smaller than zero, which may occur in iterator; so this function returns isize.

Source§

impl<D> Layout<D>
where D: DimBaseAPI,

Source

pub fn into_dim<D2>(self) -> Result<Layout<D2>, Error>
where D2: DimBaseAPI, D: DimIntoAPI<D2>,

Convert layout to another dimension.

Source

pub fn to_dim<D2>(&self) -> Result<Layout<D2>, Error>
where D2: DimBaseAPI, D: DimIntoAPI<D2>,

Convert layout to another dimension.

Trait Implementations§

Source§

impl<D> Clone for Layout<D>
where D: Clone + DimBaseAPI, <D as DimBaseAPI>::Stride: Clone,

Source§

fn clone(&self) -> Layout<D>

Returns a duplicate of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl<D> Debug for Layout<D>
where D: DimDevAPI,

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<T, D> EmptyAPI<(T, D)> for Layout<D>
where D: DimAPI,

Source§

type Out = TensorBase<Storage<DataOwned<<DeviceFaer as DeviceRawAPI<T>>::Raw>, T, DeviceFaer>, Vec<usize>>

Source§

unsafe fn empty_f(self) -> Result<Self::Out>

Safety Read more
Source§

unsafe fn empty(self) -> Self::Out
where Self: Sized,

Safety Read more
Source§

impl<const N: usize> From<[usize; N]> for Layout<[usize; N]>

Source§

fn from(shape: [usize; N]) -> Layout<[usize; N]>

Converts to this type from the input type.
Source§

impl From<Vec<usize>> for Layout<Vec<usize>>

Source§

fn from(shape: Vec<usize>) -> Layout<Vec<usize>>

Converts to this type from the input type.
Source§

impl<D> IndexerDynamicAPI for Layout<D>
where D: DimDevAPI,

Source§

fn dim_slice(&self, indexers: &[Indexer]) -> Result<Layout<Vec<usize>>, Error>

Index tensor by a list of indexers.
Source§

fn dim_split_at( &self, axis: isize, ) -> Result<(Layout<Vec<usize>>, Layout<Vec<usize>>), Error>

Split current layout into two layouts at axis, with offset unchanged.
Source§

fn dim_split_axes( &self, axes: &[isize], ) -> Result<(Layout<Vec<usize>>, Layout<Vec<usize>>), Error>

Source§

impl<D> IndexerLargerOneAPI for Layout<D>
where D: DimDevAPI + DimLargerOneAPI, <D as DimLargerOneAPI>::LargerOne: DimDevAPI,

Source§

type DOut = <D as DimLargerOneAPI>::LargerOne

Source§

fn dim_insert( &self, axis: isize, ) -> Result<Layout<<Layout<D> as IndexerLargerOneAPI>::DOut>, Error>

Insert dimension after, with shape 1. Number of dimension will increase by 1.
Source§

impl<D> IndexerPreserveAPI for Layout<D>
where D: DimDevAPI,

Source§

fn dim_narrow( &self, axis: isize, slice: Slice<isize>, ) -> Result<Layout<D>, Error>

Narrowing tensor by slicing at a specific axis.
Source§

impl<D> IndexerSmallerOneAPI for Layout<D>
where D: DimDevAPI + DimSmallerOneAPI, <D as DimSmallerOneAPI>::SmallerOne: DimDevAPI,

Source§

type DOut = <D as DimSmallerOneAPI>::SmallerOne

Source§

fn dim_select( &self, axis: isize, index: isize, ) -> Result<Layout<<Layout<D> as IndexerSmallerOneAPI>::DOut>, Error>

Select dimension at index. Number of dimension will decrease by 1.
Source§

fn dim_eliminate( &self, axis: isize, ) -> Result<Layout<<Layout<D> as IndexerSmallerOneAPI>::DOut>, Error>

Eliminate dimension at index. Number of dimension will decrease by 1.
Source§

impl<T, D> OnesAPI<(T, D)> for Layout<D>
where T: Num + Clone, D: DimAPI,

Source§

type Out = TensorBase<Storage<DataOwned<<DeviceFaer as DeviceRawAPI<T>>::Raw>, T, DeviceFaer>, Vec<usize>>

Source§

fn ones_f(self) -> Result<Self::Out>

Source§

fn ones(self) -> Self::Out
where Self: Sized,

Source§

impl<D> PartialEq for Layout<D>
where D: DimBaseAPI,

Source§

fn eq(&self, other: &Layout<D>) -> bool

For layout, shape must be the same, while stride should be the same when shape is not zero or one, but can be arbitary otherwise.

1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T, D> ZerosAPI<(T, D)> for Layout<D>
where T: Num + Clone, D: DimAPI,

Source§

type Out = TensorBase<Storage<DataOwned<<DeviceFaer as DeviceRawAPI<T>>::Raw>, T, DeviceFaer>, Vec<usize>>

Source§

fn zeros_f(self) -> Result<Self::Out>

Source§

fn zeros(self) -> Self::Out
where Self: Sized,

Source§

impl<D> Send for Layout<D>
where D: DimBaseAPI,

Source§

impl<D> Sync for Layout<D>
where D: DimBaseAPI,

Auto Trait Implementations§

§

impl<D> Freeze for Layout<D>
where D: Freeze, <D as DimBaseAPI>::Stride: Freeze,

§

impl<D> RefUnwindSafe for Layout<D>

§

impl<D> Unpin for Layout<D>
where D: Unpin, <D as DimBaseAPI>::Stride: Unpin,

§

impl<D> UnwindSafe for Layout<D>

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> ByRef<T> for T

Source§

fn by_ref(&self) -> &T

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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

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

Initializes a with the given initializer. Read more
Source§

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

Dereferences the given pointer. Read more
Source§

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

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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.
Source§

impl<T> ValWriteAPI<T> for T

Source§

fn write(&mut self, val: T) -> &mut T