pub struct ArrayLayout<const N: usize> { /* private fields */ }
Expand description
An array layout allow N dimensions inlined.
Implementations§
Source§impl<const N: usize> ArrayLayout<N>
impl<const N: usize> ArrayLayout<N>
Source§impl<const N: usize> ArrayLayout<N>
impl<const N: usize> ArrayLayout<N>
Sourcepub fn broadcast(&self, axis: usize, times: usize) -> Self
pub fn broadcast(&self, axis: usize, times: usize) -> Self
广播变换将指定的长度为 1 的阶扩增指定的倍数,并将其步长固定为 0。
let layout = ArrayLayout::<3>::new(&[1, 5, 2], &[10, 2, 1], 0).broadcast(0, 10);
assert_eq!(layout.shape(), &[10, 5, 2]);
assert_eq!(layout.strides(), &[0, 2, 1]);
assert_eq!(layout.offset(), 0);
Sourcepub fn broadcast_many(&self, args: &[BroadcastArg]) -> Self
pub fn broadcast_many(&self, args: &[BroadcastArg]) -> Self
一次对多个阶进行广播变换。
Source§impl<const N: usize> ArrayLayout<N>
impl<const N: usize> ArrayLayout<N>
Sourcepub fn index(&self, axis: usize, index: usize) -> Self
pub fn index(&self, axis: usize, index: usize) -> Self
索引变换是选择张量指定阶上一项数据的变换,例如指定向量中的一个数、指定矩阵的一行或一列。 索引变换导致张量降阶,确定索引的阶从张量表示移除。
let layout = ArrayLayout::<3>::new(&[2, 3, 4], &[12, 4, 1], 0).index(1, 2);
assert_eq!(layout.shape(), &[2, 4]);
assert_eq!(layout.strides(), &[12, 1]);
assert_eq!(layout.offset(), 8);
Sourcepub fn index_many(&self, args: &[IndexArg]) -> Self
pub fn index_many(&self, args: &[IndexArg]) -> Self
一次对多个阶进行索引变换。
Source§impl<const N: usize> ArrayLayout<N>
impl<const N: usize> ArrayLayout<N>
Sourcepub fn merge_be(&self, start: usize, len: usize) -> Option<Self>
pub fn merge_be(&self, start: usize, len: usize) -> Option<Self>
合并变换是将多个连续维度划分合并的变换。 大端合并对维度从后到前依次合并。
let layout = ArrayLayout::<3>::new(&[2, 3, 4], &[12, 4, 1], 0).merge_be(0, 3).unwrap();
assert_eq!(layout.shape(), &[24]);
assert_eq!(layout.strides(), &[1]);
assert_eq!(layout.offset(), 0);
Sourcepub fn merge_le(&self, start: usize, len: usize) -> Option<Self>
pub fn merge_le(&self, start: usize, len: usize) -> Option<Self>
合并变换是将多个连续维度划分合并的变换。 小端合并对维度从前到后依次合并。
let layout = ArrayLayout::<3>::new(&[4, 3, 2], &[1, 4, 12], 0).merge_le(0, 3).unwrap();
assert_eq!(layout.shape(), &[24]);
assert_eq!(layout.strides(), &[1]);
assert_eq!(layout.offset(), 0);
Sourcepub fn merge_free(&self, start: usize, len: usize) -> Option<Self>
pub fn merge_free(&self, start: usize, len: usize) -> Option<Self>
合并变换是将多个连续维度划分合并的变换。 任意合并只考虑维度的存储连续性。
let layout = ArrayLayout::<3>::new(&[3, 2, 4], &[4, 12, 1], 0).merge_free(0, 3).unwrap();
assert_eq!(layout.shape(), &[24]);
assert_eq!(layout.strides(), &[1]);
assert_eq!(layout.offset(), 0);
Sourcepub fn merge_many(&self, args: &[MergeArg]) -> Option<Self>
pub fn merge_many(&self, args: &[MergeArg]) -> Option<Self>
一次对多个阶进行合并变换。
Source§impl<const N: usize> ArrayLayout<N>
impl<const N: usize> ArrayLayout<N>
Sourcepub fn slice(&self, axis: usize, start: usize, step: isize, len: usize) -> Self
pub fn slice(&self, axis: usize, start: usize, step: isize, len: usize) -> Self
切片变换是裁剪张量指定阶上一组连续数据的变换。
// axis = 1, start = 1, step = -1, len = 2
let layout = ArrayLayout::<3>::new(&[2, 3, 4], &[12, 4, 1], 0).slice(1, 2, -1, 2);
assert_eq!(layout.shape(), &[2, 2, 4]);
assert_eq!(layout.strides(), &[12, -4, 1]);
assert_eq!(layout.offset(), 8);
Sourcepub fn slice_many(&self, args: &[SliceArg]) -> Self
pub fn slice_many(&self, args: &[SliceArg]) -> Self
一次对多个阶进行切片变换。
Source§impl<const N: usize> ArrayLayout<N>
impl<const N: usize> ArrayLayout<N>
Sourcepub fn split<'a>(&'a self, axis: usize, parts: &'a [usize]) -> Split<'a, N> ⓘ
pub fn split<'a>(&'a self, axis: usize, parts: &'a [usize]) -> Split<'a, N> ⓘ
切分变换讲单个张量沿某个维度切分成多个张量,因此可以支持不均匀的切分。
let layout = ArrayLayout::<3>::new(&[2, 3, 4], &[12, 4, 1], 0);
let mut splits = layout.split(2, &[1, 3]);
let layout = splits.next().unwrap();
assert_eq!(layout.shape(), &[2, 3, 1]);
assert_eq!(layout.strides(), &[12, 4, 1]);
assert_eq!(layout.offset(), 0);
let layout = splits.next().unwrap();
assert_eq!(layout.shape(), &[2, 3, 3]);
assert_eq!(layout.strides(), &[12, 4, 1]);
assert_eq!(layout.offset(), 1);
Source§impl<const N: usize> ArrayLayout<N>
impl<const N: usize> ArrayLayout<N>
Sourcepub fn tile_be(&self, axis: usize, tiles: &[usize]) -> Self
pub fn tile_be(&self, axis: usize, tiles: &[usize]) -> Self
分块变换是将单个维度划分为多个分块的变换。 大端分块使得分块后范围更大的维度在形状中更靠前的位置。
let layout = ArrayLayout::<3>::new(&[2, 3, 6], &[18, 6, 1], 0).tile_be(2, &[2, 3]);
assert_eq!(layout.shape(), &[2, 3, 2, 3]);
assert_eq!(layout.strides(), &[18, 6, 3, 1]);
assert_eq!(layout.offset(), 0);
Sourcepub fn tile_le(&self, axis: usize, tiles: &[usize]) -> Self
pub fn tile_le(&self, axis: usize, tiles: &[usize]) -> Self
分块变换是将单个维度划分为多个分块的变换。 小端分块使得分块后范围更小的维度在形状中更靠前的位置。
let layout = ArrayLayout::<3>::new(&[2, 3, 6], &[18, 6, 1], 0).tile_le(2, &[2, 3]);
assert_eq!(layout.shape(), &[2, 3, 2, 3]);
assert_eq!(layout.strides(), &[18, 6, 1, 2]);
assert_eq!(layout.offset(), 0);
Source§impl<const N: usize> ArrayLayout<N>
impl<const N: usize> ArrayLayout<N>
Source§impl<const N: usize> ArrayLayout<N>
impl<const N: usize> ArrayLayout<N>
Sourcepub fn new(shape: &[usize], strides: &[isize], offset: isize) -> Self
pub fn new(shape: &[usize], strides: &[isize], offset: isize) -> Self
Creates a new Layout with the given shape, strides, and offset.
let layout = ArrayLayout::<4>::new(&[2, 3, 4], &[12, -4, 1], 20);
assert_eq!(layout.offset(), 20);
assert_eq!(layout.shape(), &[2, 3, 4]);
assert_eq!(layout.strides(), &[12, -4, 1]);
Sourcepub fn new_contiguous(
shape: &[usize],
endian: Endian,
element_size: usize,
) -> Self
pub fn new_contiguous( shape: &[usize], endian: Endian, element_size: usize, ) -> Self
Creates a new contiguous Layout with the given shape.
let layout = ArrayLayout::<4>::new_contiguous(&[2, 3, 4], Endian::LittleEndian, 4);
assert_eq!(layout.offset(), 0);
assert_eq!(layout.shape(), &[2, 3, 4]);
assert_eq!(layout.strides(), &[4, 8, 24]);
Sourcepub fn to_inline_size<const M: usize>(&self) -> ArrayLayout<M>
pub fn to_inline_size<const M: usize>(&self) -> ArrayLayout<M>
Copy data to another ArrayLayout
with inline size M
.
let layout = ArrayLayout::<4>::new_contiguous(&[3, 4], BigEndian, 0);
assert_eq!(size_of_val(&layout), (2 * 4 + 2) * size_of::<usize>());
let layout = layout.to_inline_size::<2>();
assert_eq!(size_of_val(&layout), (2 * 2 + 2) * size_of::<usize>());
Sourcepub fn num_elements(&self) -> usize
pub fn num_elements(&self) -> usize
Calculates the number of elements in the array.
let layout = ArrayLayout::<4>::new_contiguous(&[2, 3, 4], BigEndian, 20);
assert_eq!(layout.num_elements(), 24);
Sourcepub fn element_offset(&self, index: usize, endian: Endian) -> isize
pub fn element_offset(&self, index: usize, endian: Endian) -> isize
Calculates the offset of element at the given index
.
let layout = ArrayLayout::<4>::new_contiguous(&[2, 3, 4], BigEndian, 4);
assert_eq!(layout.element_offset(22, BigEndian), 88); // 88 <- (22 % 4 * 4) + (22 / 4 % 3 * 16) + (22 / 4 / 3 % 2 * 48)
Sourcepub fn data_range(&self) -> RangeInclusive<isize>
pub fn data_range(&self) -> RangeInclusive<isize>
Calculates the range of data in bytes to determine the location of the memory area that the array needs to access.
let layout = ArrayLayout::<4>::new(&[2, 3, 4],&[12, -4, 1], 20);
let range = layout.data_range();
assert_eq!(range, 12..=35);