pub struct Tensor<T, const N: usize, A: TensorAllocator> {
pub storage: TensorStorage<T, A>,
pub shape: [usize; N],
pub strides: [usize; N],
}Expand description
A data structure to represent a multi-dimensional tensor.
NOTE: Internally, the data is stored as an arrow::ScalarBuffer which represents a contiguous memory
region that can be shared with other buffers and across thread boundaries.
§Attributes
storage- The storage of the tensor.shape- The shape of the tensor.strides- The strides of the tensor data in memory.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data: Vec<u8> = vec![1, 2, 3, 4];
let t = Tensor::<u8, 2, CpuAllocator>::from_shape_vec([2, 2], data, CpuAllocator).unwrap();
assert_eq!(t.shape, [2, 2]);Fields§
§storage: TensorStorage<T, A>The storage of the tensor.
shape: [usize; N]The shape of the tensor.
strides: [usize; N]The strides of the tensor data in memory.
Implementations§
Source§impl<T, const N: usize, A> Tensor<T, N, A>where
A: 'static + TensorAllocator,
impl<T, const N: usize, A> Tensor<T, N, A>where
A: 'static + TensorAllocator,
Sourcepub fn as_slice_mut(&mut self) -> &mut [T]
pub fn as_slice_mut(&mut self) -> &mut [T]
Get the data of the tensor as a mutable slice.
§Returns
A mutable slice containing the data of the tensor.
Sourcepub fn as_mut_ptr(&mut self) -> *mut T
pub fn as_mut_ptr(&mut self) -> *mut T
Get the data of the tensor as a mutable pointer.
§Returns
A mutable pointer to the data of the tensor.
Sourcepub fn into_vec(self) -> Vec<T>
pub fn into_vec(self) -> Vec<T>
Consumes the tensor and returns the underlying vector.
This method destroys the tensor and returns ownership of the underlying data. The returned vector will have a length equal to the total number of elements in the tensor.
Sourcepub fn from_shape_vec(
shape: [usize; N],
data: Vec<T>,
alloc: A,
) -> Result<Self, TensorError>
pub fn from_shape_vec( shape: [usize; N], data: Vec<T>, alloc: A, ) -> Result<Self, TensorError>
Creates a new Tensor with the given shape and data.
§Arguments
shape- An array containing the shape of the tensor.data- A vector containing the data of the tensor.alloc- The allocator to use.
§Returns
A new Tensor instance.
§Errors
If the number of elements in the data does not match the shape of the tensor, an error is returned.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data: Vec<u8> = vec![1, 2, 3, 4];
let t = Tensor::<u8, 2, CpuAllocator>::from_shape_vec([2, 2], data, CpuAllocator).unwrap();
assert_eq!(t.shape, [2, 2]);Sourcepub fn from_shape_slice(
shape: [usize; N],
data: &[T],
alloc: A,
) -> Result<Self, TensorError>where
T: Clone,
pub fn from_shape_slice(
shape: [usize; N],
data: &[T],
alloc: A,
) -> Result<Self, TensorError>where
T: Clone,
Creates a new Tensor with the given shape and slice of data.
§Arguments
shape- An array containing the shape of the tensor.data- A slice containing the data of the tensor.alloc- The allocator to use.
§Returns
A new Tensor instance.
§Errors
If the number of elements in the data does not match the shape of the tensor, an error is returned.
Sourcepub fn from_shape_val(shape: [usize; N], value: T, alloc: A) -> Selfwhere
T: Clone,
pub fn from_shape_val(shape: [usize; N], value: T, alloc: A) -> Selfwhere
T: Clone,
Creates a new Tensor with the given shape and a default value.
§Arguments
shape- An array containing the shape of the tensor.value- The default value to fill the tensor with.
§Returns
A new Tensor instance.
§Example
use kornia_core::{Tensor, CpuAllocator};
let t = Tensor::<u8, 1, CpuAllocator>::from_shape_val([4], 0, CpuAllocator);
assert_eq!(t.as_slice(), vec![0, 0, 0, 0]);
let t = Tensor::<u8, 2, CpuAllocator>::from_shape_val([2, 2], 1, CpuAllocator);
assert_eq!(t.as_slice(), vec![1, 1, 1, 1]);
let t = Tensor::<u8, 3, CpuAllocator>::from_shape_val([2, 1, 3], 2, CpuAllocator);
assert_eq!(t.as_slice(), vec![2, 2, 2, 2, 2, 2]);Sourcepub fn from_shape_fn<F>(shape: [usize; N], alloc: A, f: F) -> Self
pub fn from_shape_fn<F>(shape: [usize; N], alloc: A, f: F) -> Self
Create a new Tensor with the given shape and a function to generate the data.
The function f is called with the index of the element to generate.
§Arguments
shape- An array containing the shape of the tensor.f- The function to generate the data.
§Returns
A new Tensor instance.
§Example
use kornia_core::{Tensor, CpuAllocator};
let t = Tensor::<u8, 1, CpuAllocator>::from_shape_fn([4], CpuAllocator, |[i]| i as u8);
assert_eq!(t.as_slice(), vec![0, 1, 2, 3]);
let t = Tensor::<u8, 2, CpuAllocator>::from_shape_fn([2, 2], CpuAllocator, |[i, j]| (i * 2 + j) as u8);
assert_eq!(t.as_slice(), vec![0, 1, 2, 3]);Sourcepub fn get_iter_offset_unchecked(&self, index: [usize; N]) -> usize
pub fn get_iter_offset_unchecked(&self, index: [usize; N]) -> usize
Sourcepub fn get_index_unchecked(&self, offset: usize) -> [usize; N]
pub fn get_index_unchecked(&self, offset: usize) -> [usize; N]
Sourcepub fn get_unchecked(&self, index: [usize; N]) -> &T
pub fn get_unchecked(&self, index: [usize; N]) -> &T
Get the element at the given index without checking if the index is out of bounds.
§Arguments
index- The list of indices to get the element from.
§Returns
A reference to the element at the given index.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data: Vec<u8> = vec![1, 2, 3, 4];
let t = Tensor::<u8, 2, CpuAllocator>::from_shape_vec([2, 2], data, CpuAllocator).unwrap();
assert_eq!(*t.get_unchecked([0, 0]), 1);
assert_eq!(*t.get_unchecked([0, 1]), 2);
assert_eq!(*t.get_unchecked([1, 0]), 3);
assert_eq!(*t.get_unchecked([1, 1]), 4);Sourcepub fn get(&self, index: [usize; N]) -> Option<&T>
pub fn get(&self, index: [usize; N]) -> Option<&T>
Get the element at the given index, checking if the index is out of bounds.
§Arguments
index- The list of indices to get the element from.
§Returns
A reference to the element at the given index.
§Errors
If the index is out of bounds, an error is returned.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data: Vec<u8> = vec![1, 2, 3, 4];
let t = Tensor::<u8, 2, CpuAllocator>::from_shape_vec([2, 2], data, CpuAllocator).unwrap();
assert_eq!(t.get([0, 0]), Some(&1));
assert_eq!(t.get([0, 1]), Some(&2));
assert_eq!(t.get([1, 0]), Some(&3));
assert_eq!(t.get([1, 1]), Some(&4));
assert!(t.get([2, 0]).is_none());Sourcepub fn reshape<const M: usize>(
&self,
shape: [usize; M],
) -> Result<TensorView<'_, T, M, A>, TensorError>
pub fn reshape<const M: usize>( &self, shape: [usize; M], ) -> Result<TensorView<'_, T, M, A>, TensorError>
Reshape the tensor to a new shape.
§Arguments
shape- The new shape of the tensor.
§Returns
A new TensorView instance.
§Errors
If the number of elements in the new shape does not match the number of elements in the tensor, an error is returned.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data: Vec<u8> = vec![1, 2, 3, 4];
let t = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data, CpuAllocator).unwrap();
let t2 = t.reshape([2, 2]).unwrap();
assert_eq!(t2.shape, [2, 2]);
assert_eq!(t2.as_slice(), vec![1, 2, 3, 4]);
assert_eq!(t2.strides, [2, 1]);
assert_eq!(t2.numel(), 4);Sourcepub fn permute_axes(&self, axes: [usize; N]) -> TensorView<'_, T, N, A>
pub fn permute_axes(&self, axes: [usize; N]) -> TensorView<'_, T, N, A>
Permute the dimensions of the tensor.
The permutation is given as an array of indices, where the value at each index is the new index of the dimension. The data is not moved, only the order of the dimensions is changed.
§Arguments
axes- The new order of the dimensions.
§Returns
A view of the tensor with the dimensions permuted.
Sourcepub fn view(&self) -> TensorView<'_, T, N, A>
pub fn view(&self) -> TensorView<'_, T, N, A>
Return a view of the tensor.
The view is a reference to the tensor storage with a different shape and strides.
§Returns
A TensorView instance.
Sourcepub fn map<U, F>(&self, f: F) -> Tensor<U, N, A>
pub fn map<U, F>(&self, f: F) -> Tensor<U, N, A>
Apply a function to each element of the tensor.
§Arguments
f- The function to apply to each element.
§Returns
A new Tensor instance.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data: Vec<u8> = vec![1, 2, 3, 4];
let t = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data, CpuAllocator).unwrap();
let t2 = t.map(|x| *x + 1);
assert_eq!(t2.as_slice(), vec![2, 3, 4, 5]);Sourcepub fn mean(&self) -> Result<T, TensorError>where
T: Float,
pub fn mean(&self) -> Result<T, TensorError>where
T: Float,
Sourcepub fn cast<U>(&self) -> Tensor<U, N, CpuAllocator>
pub fn cast<U>(&self) -> Tensor<U, N, CpuAllocator>
Cast the tensor to a new type.
§Returns
A new Tensor instance.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data: Vec<u8> = vec![1, 2, 3, 4];
let t = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data, CpuAllocator).unwrap();
let t2 = t.cast::<f32>();
assert_eq!(t2.as_slice(), vec![1.0, 2.0, 3.0, 4.0]);Sourcepub fn element_wise_op<F>(
&self,
other: &Tensor<T, N, CpuAllocator>,
op: F,
) -> Result<Tensor<T, N, CpuAllocator>, TensorError>
pub fn element_wise_op<F>( &self, other: &Tensor<T, N, CpuAllocator>, op: F, ) -> Result<Tensor<T, N, CpuAllocator>, TensorError>
Perform an element-wise operation on two tensors.
§Arguments
other- The other tensor to perform the operation with.op- The operation to perform.
§Returns
A new Tensor instance.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data1: Vec<u8> = vec![1, 2, 3, 4];
let t1 = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data1, CpuAllocator).unwrap();
let data2: Vec<u8> = vec![1, 2, 3, 4];
let t2 = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data2, CpuAllocator).unwrap();
let t3 = t1.element_wise_op(&t2, |a, b| *a + *b).unwrap();
assert_eq!(t3.as_slice(), vec![2, 4, 6, 8]);
let t4 = t1.element_wise_op(&t2, |a, b| *a - *b).unwrap();
assert_eq!(t4.as_slice(), vec![0, 0, 0, 0]);
let t5 = t1.element_wise_op(&t2, |a, b| *a * *b).unwrap();
assert_eq!(t5.as_slice(), vec![1, 4, 9, 16]);
let t6 = t1.element_wise_op(&t2, |a, b| *a / *b).unwrap();
assert_eq!(t6.as_slice(), vec![1, 1, 1, 1]);Sourcepub fn add(
&self,
other: &Tensor<T, N, CpuAllocator>,
) -> Tensor<T, N, CpuAllocator>
pub fn add( &self, other: &Tensor<T, N, CpuAllocator>, ) -> Tensor<T, N, CpuAllocator>
Perform an element-wise addition on two tensors.
§Arguments
other- The other tensor to add.
§Returns
A new Tensor instance.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data1: Vec<u8> = vec![1, 2, 3, 4];
let t1 = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data1, CpuAllocator).unwrap();
let data2: Vec<u8> = vec![1, 2, 3, 4];
let t2 = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data2, CpuAllocator).unwrap();
let t3 = t1.add(&t2);
assert_eq!(t3.as_slice(), vec![2, 4, 6, 8]);Sourcepub fn sub(
&self,
other: &Tensor<T, N, CpuAllocator>,
) -> Tensor<T, N, CpuAllocator>
pub fn sub( &self, other: &Tensor<T, N, CpuAllocator>, ) -> Tensor<T, N, CpuAllocator>
Perform an element-wise subtraction on two tensors.
§Arguments
other- The other tensor to subtract.
§Returns
A new Tensor instance.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data1: Vec<u8> = vec![1, 2, 3, 4];
let t1 = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data1, CpuAllocator).unwrap();
let data2: Vec<u8> = vec![1, 2, 3, 4];
let t2 = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data2, CpuAllocator).unwrap();
let t3 = t1.sub(&t2);
assert_eq!(t3.as_slice(), vec![0, 0, 0, 0]);Sourcepub fn mul(
&self,
other: &Tensor<T, N, CpuAllocator>,
) -> Tensor<T, N, CpuAllocator>
pub fn mul( &self, other: &Tensor<T, N, CpuAllocator>, ) -> Tensor<T, N, CpuAllocator>
Perform an element-wise multiplication on two tensors.
§Arguments
other- The other tensor to multiply.
§Returns
A new Tensor instance.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data1: Vec<u8> = vec![1, 2, 3, 4];
let t1 = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data1, CpuAllocator).unwrap();
let data2: Vec<u8> = vec![1, 2, 3, 4];
let t2 = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data2, CpuAllocator).unwrap();
let t3 = t1.mul(&t2);
assert_eq!(t3.as_slice(), vec![1, 4, 9, 16]);Sourcepub fn div(
&self,
other: &Tensor<T, N, CpuAllocator>,
) -> Tensor<T, N, CpuAllocator>
pub fn div( &self, other: &Tensor<T, N, CpuAllocator>, ) -> Tensor<T, N, CpuAllocator>
Perform an element-wise division on two tensors.
§Arguments
other- The other tensor to divide.
§Returns
A new Tensor instance.
§Example
use kornia_core::{Tensor, CpuAllocator};
let data1: Vec<u8> = vec![1, 2, 3, 4];
let t1 = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data1, CpuAllocator).unwrap();
let data2: Vec<u8> = vec![1, 2, 3, 4];
let t2 = Tensor::<u8, 1, CpuAllocator>::from_shape_vec([4], data2, CpuAllocator).unwrap();
let t3 = t1.div(&t2);
assert_eq!(t3.as_slice(), vec![1, 1, 1, 1]);