pub struct Tensor<R>where
R: Runtime,{ /* private fields */ }Expand description
N-dimensional array stored on a compute device
Tensor is the fundamental data structure in numr. It consists of:
- Storage: Reference-counted device memory
- Layout: Shape, strides, and offset defining the view into storage
- DType: Element type (determined at runtime)
§Zero-Copy Views
Operations like transpose, slice, and reshape create new tensors
that share the same underlying storage. This is achieved through:
- Arc-wrapped storage (reference counting)
- Modified layout (different strides/offset)
§Example
let a = Tensor::<CpuRuntime>::from_slice(&[1.0f32, 2.0, 3.0, 4.0], &[2, 2], &device);
let b = a.transpose(-1, -2); // Zero-copy, shares storage with aImplementations§
Source§impl<R> Tensor<R>where
R: Runtime,
impl<R> Tensor<R>where
R: Runtime,
Sourcepub fn from_parts(storage: Storage<R>, layout: Layout) -> Tensor<R>
pub fn from_parts(storage: Storage<R>, layout: Layout) -> Tensor<R>
Create a tensor from storage and layout
Sourcepub fn empty(
shape: &[usize],
dtype: <R as Runtime>::DType,
device: &<R as Runtime>::Device,
) -> Tensor<R>
pub fn empty( shape: &[usize], dtype: <R as Runtime>::DType, device: &<R as Runtime>::Device, ) -> Tensor<R>
Create an uninitialized tensor
§Safety
The contents are uninitialized. Reading before writing is undefined behavior.
§Panics
Panics if allocation fails. Use Self::try_empty in fallible contexts.
Sourcepub fn try_empty(
shape: &[usize],
dtype: <R as Runtime>::DType,
device: &<R as Runtime>::Device,
) -> Result<Tensor<R>, Error>
pub fn try_empty( shape: &[usize], dtype: <R as Runtime>::DType, device: &<R as Runtime>::Device, ) -> Result<Tensor<R>, Error>
Create an uninitialized tensor (fallible version)
Sourcepub fn is_contiguous(&self) -> bool
pub fn is_contiguous(&self) -> bool
Check if the tensor is contiguous in memory
Sourcepub fn size(&self, dim: isize) -> Option<usize>
pub fn size(&self, dim: isize) -> Option<usize>
Get size along a dimension (supports negative indexing)
Sourcepub fn dim(&self, index: isize) -> Result<usize, Error>
pub fn dim(&self, index: isize) -> Result<usize, Error>
Get size along a dimension, returning error on invalid index
Sourcepub fn elem_count(&self) -> usize
pub fn elem_count(&self) -> usize
Total number of elements (alias for numel)
Sourcepub fn ptr(&self) -> u64
pub fn ptr(&self) -> u64
Data pointer adjusted for layout offset. This is the pointer to the first element of this tensor’s view.
Sourcepub fn owns_memory(&self) -> bool
pub fn owns_memory(&self) -> bool
Whether the underlying storage is owned (will deallocate on drop)
Check if two tensors share the same storage
Sourcepub fn dims5(&self) -> Result<(usize, usize, usize, usize, usize), Error>
pub fn dims5(&self) -> Result<(usize, usize, usize, usize, usize), Error>
Unpack shape of a 5D tensor
Sourcepub fn from_storage_contiguous(
storage: Storage<R>,
shape: &[usize],
) -> Tensor<R>
pub fn from_storage_contiguous( storage: Storage<R>, shape: &[usize], ) -> Tensor<R>
Create tensor from storage and contiguous layout
Sourcepub fn transpose(&self, dim0: isize, dim1: isize) -> Result<Tensor<R>, Error>
pub fn transpose(&self, dim0: isize, dim1: isize) -> Result<Tensor<R>, Error>
Transpose two dimensions (zero-copy)
Sourcepub fn reshape(&self, shape: &[usize]) -> Result<Tensor<R>, Error>
pub fn reshape(&self, shape: &[usize]) -> Result<Tensor<R>, Error>
Reshape to a new shape (zero-copy if contiguous)
Sourcepub fn view(&self, shape: &[usize]) -> Result<Tensor<R>, Error>
pub fn view(&self, shape: &[usize]) -> Result<Tensor<R>, Error>
View tensor with different shape (alias for reshape)
Sourcepub fn permute(&self, dims: &[usize]) -> Result<Tensor<R>, Error>
pub fn permute(&self, dims: &[usize]) -> Result<Tensor<R>, Error>
Permute dimensions (zero-copy)
Reorders the dimensions of the tensor according to the given permutation. This is a view operation - no data is copied.
§Arguments
dims- New order of dimensions. Must be a permutation of 0..ndim.
§Example
let tensor = Tensor::<CpuRuntime>::from_slice(&data, &[2, 3, 4], &device);
let permuted = tensor.permute(&[2, 0, 1])?; // Shape becomes [4, 2, 3]Sourcepub fn narrow(
&self,
dim: isize,
start: usize,
length: usize,
) -> Result<Tensor<R>, Error>
pub fn narrow( &self, dim: isize, start: usize, length: usize, ) -> Result<Tensor<R>, Error>
Narrow a dimension (zero-copy slice)
Returns a view of the tensor narrowed to a contiguous subset of elements along a single dimension. This is a view operation - no data is copied.
§Arguments
dim- Dimension to narrow (supports negative indexing)start- Starting index in that dimensionlength- Number of elements to keep
§Example
let tensor = Tensor::<CpuRuntime>::from_slice(&data, &[4, 5, 6], &device);
let narrowed = tensor.narrow(1, 1, 3)?; // Shape becomes [4, 3, 6]Sourcepub fn broadcast_to(&self, shape: &[usize]) -> Result<Tensor<R>, Error>
pub fn broadcast_to(&self, shape: &[usize]) -> Result<Tensor<R>, Error>
Broadcast to a target shape (zero-copy)
Sourcepub fn flip(&self, dim: isize) -> Result<Tensor<R>, Error>
pub fn flip(&self, dim: isize) -> Result<Tensor<R>, Error>
Flip (reverse) tensor along a dimension (zero-copy)
Reverses the order of elements along the specified dimension. This is a view operation - no data is copied.
§Arguments
dim- Dimension to flip (supports negative indexing)
§Example
let tensor = Tensor::<CpuRuntime>::from_slice(&[1.0, 2.0, 3.0, 4.0], &[2, 2], &device);
let flipped = tensor.flip(0)?; // Reverse rows: [[3, 4], [1, 2]]
let flipped = tensor.flip(-1)?; // Reverse columns: [[2, 1], [4, 3]]Sourcepub fn contiguous(&self) -> Tensor<R>
pub fn contiguous(&self) -> Tensor<R>
Make tensor contiguous (copy if needed)
If the tensor is already contiguous, returns a view (zero-copy). Otherwise, allocates new storage and copies the data to a contiguous layout.
§Backend Support
This method uses Runtime::copy_strided which handles strided copies
correctly for each backend:
- CPU/CUDA: Uses pointer arithmetic (handles can be offset directly)
- WGPU: Uses compute shader (buffer IDs don’t support arithmetic)
Sourcepub fn to_vec<T>(&self) -> Vec<T>where
T: Pod,
pub fn to_vec<T>(&self) -> Vec<T>where
T: Pod,
Copy tensor data to a Vec on the host
For contiguous tensors, this copies only the viewed portion of the storage, respecting the tensor’s shape and offset.
Sourcepub fn record_event(&self) -> Result<u64, Error>
pub fn record_event(&self) -> Result<u64, Error>
Record an event on the compute stream for this tensor’s device.
Call this BEFORE launching additional compute work, then pass the event
to to_vec_pipelined AFTER launching the compute work. This allows the
copy to proceed as soon as the event fires, while compute continues.
Sourcepub fn to_vec_pipelined<T>(&self, event: u64) -> Result<Vec<T>, Error>where
T: Pod,
pub fn to_vec_pipelined<T>(&self, event: u64) -> Result<Vec<T>, Error>where
T: Pod,
Copy tensor data to a Vec using the pipelined copy stream, synchronized via a previously recorded event.
On CUDA, syncs only the copy stream — compute stream keeps running.
Sourcepub fn item<T>(&self) -> Result<T, Error>
pub fn item<T>(&self) -> Result<T, Error>
Extract the scalar value from a single-element tensor
This is the idiomatic way to get a scalar value from a tensor for use in Rust control flow (convergence checks, comparisons, etc.).
§Returns
The single element as type T, or an error if the tensor doesn’t
contain exactly one element.
§Example
let loss_val: f32 = loss.item()?;
if loss_val < 1.0 {
// training converged
}Source§impl<R> Tensor<R>where
R: Runtime,
impl<R> Tensor<R>where
R: Runtime,
Sourcepub fn try_zeros_generic(
shape: &[usize],
dtype: <R as Runtime>::DType,
device: &<R as Runtime>::Device,
) -> Result<Tensor<R>, Error>
pub fn try_zeros_generic( shape: &[usize], dtype: <R as Runtime>::DType, device: &<R as Runtime>::Device, ) -> Result<Tensor<R>, Error>
Create a tensor filled with zeros (generic, works with any DType)
Sourcepub fn try_ones_generic(
shape: &[usize],
dtype: <R as Runtime>::DType,
device: &<R as Runtime>::Device,
) -> Result<Tensor<R>, Error>
pub fn try_ones_generic( shape: &[usize], dtype: <R as Runtime>::DType, device: &<R as Runtime>::Device, ) -> Result<Tensor<R>, Error>
Create a tensor filled with ones (generic, works with any DType)
Sourcepub fn try_full_scalar_generic(
shape: &[usize],
dtype: <R as Runtime>::DType,
value: f64,
device: &<R as Runtime>::Device,
) -> Result<Tensor<R>, Error>
pub fn try_full_scalar_generic( shape: &[usize], dtype: <R as Runtime>::DType, value: f64, device: &<R as Runtime>::Device, ) -> Result<Tensor<R>, Error>
Create a tensor filled with a scalar value (generic, works with any DType)
Uses DataType::fill_bytes to generate the fill pattern, so it works
with any DType that implements the trait (including boostr’s quantized types).
Source§impl<R> Tensor<R>
impl<R> Tensor<R>
Sourcepub fn from_slice<T>(
data: &[T],
shape: &[usize],
device: &<R as Runtime>::Device,
) -> Tensor<R>where
T: Element,
pub fn from_slice<T>(
data: &[T],
shape: &[usize],
device: &<R as Runtime>::Device,
) -> Tensor<R>where
T: Element,
Create a tensor from a slice of data
§Panics
Panics if data.len() does not equal the product of the shape dimensions.
For a fallible alternative, use Self::try_from_slice.
§Example
let tensor = Tensor::<CpuRuntime>::from_slice(&[1.0f32, 2.0, 3.0, 4.0], &[2, 2], &device);Sourcepub fn try_from_slice<T>(
data: &[T],
shape: &[usize],
device: &<R as Runtime>::Device,
) -> Result<Tensor<R>, Error>where
T: Element,
pub fn try_from_slice<T>(
data: &[T],
shape: &[usize],
device: &<R as Runtime>::Device,
) -> Result<Tensor<R>, Error>where
T: Element,
Create a tensor from a slice of data (fallible version)
Returns an error if data.len() does not equal the product of the shape dimensions,
or if memory allocation fails.
§Example
let tensor = Tensor::<CpuRuntime>::try_from_slice(&[1.0f32, 2.0, 3.0, 4.0], &[2, 2], &device)?;Sourcepub fn zeros(
shape: &[usize],
dtype: DType,
device: &<R as Runtime>::Device,
) -> Tensor<R>
pub fn zeros( shape: &[usize], dtype: DType, device: &<R as Runtime>::Device, ) -> Tensor<R>
Create a tensor filled with zeros
This properly initializes memory to zero on all backends (CPU and GPU).
Sourcepub fn try_zeros(
shape: &[usize],
dtype: DType,
device: &<R as Runtime>::Device,
) -> Result<Tensor<R>, Error>
pub fn try_zeros( shape: &[usize], dtype: DType, device: &<R as Runtime>::Device, ) -> Result<Tensor<R>, Error>
Create a tensor filled with zeros (fallible version)
Sourcepub fn ones(
shape: &[usize],
dtype: DType,
device: &<R as Runtime>::Device,
) -> Tensor<R>
pub fn ones( shape: &[usize], dtype: DType, device: &<R as Runtime>::Device, ) -> Tensor<R>
Create a tensor filled with ones
Sourcepub fn try_ones(
shape: &[usize],
dtype: DType,
device: &<R as Runtime>::Device,
) -> Result<Tensor<R>, Error>
pub fn try_ones( shape: &[usize], dtype: DType, device: &<R as Runtime>::Device, ) -> Result<Tensor<R>, Error>
Create a tensor filled with ones (fallible version)
Source§impl<R> Tensor<R>
impl<R> Tensor<R>
Sourcepub fn add(&self, other: &Tensor<R>) -> Result<Tensor<R>, Error>
pub fn add(&self, other: &Tensor<R>) -> Result<Tensor<R>, Error>
Element-wise addition: self + other
Sourcepub fn sub(&self, other: &Tensor<R>) -> Result<Tensor<R>, Error>
pub fn sub(&self, other: &Tensor<R>) -> Result<Tensor<R>, Error>
Element-wise subtraction: self - other
Sourcepub fn mul(&self, other: &Tensor<R>) -> Result<Tensor<R>, Error>
pub fn mul(&self, other: &Tensor<R>) -> Result<Tensor<R>, Error>
Element-wise multiplication: self * other
Sourcepub fn div(&self, other: &Tensor<R>) -> Result<Tensor<R>, Error>
pub fn div(&self, other: &Tensor<R>) -> Result<Tensor<R>, Error>
Element-wise division: self / other
Sourcepub fn pow(&self, other: &Tensor<R>) -> Result<Tensor<R>, Error>
pub fn pow(&self, other: &Tensor<R>) -> Result<Tensor<R>, Error>
Element-wise power: self ^ other
Source§impl<R> Tensor<R>
impl<R> Tensor<R>
Source§impl<R> Tensor<R>
impl<R> Tensor<R>
Sourcepub fn sum(&self, dims: &[usize], keepdim: bool) -> Result<Tensor<R>, Error>
pub fn sum(&self, dims: &[usize], keepdim: bool) -> Result<Tensor<R>, Error>
Sum along dimensions
Sourcepub fn mean(&self, dims: &[usize], keepdim: bool) -> Result<Tensor<R>, Error>
pub fn mean(&self, dims: &[usize], keepdim: bool) -> Result<Tensor<R>, Error>
Mean along dimensions
Source§impl<R> Tensor<R>
impl<R> Tensor<R>
Sourcepub fn index_select(
&self,
dim: usize,
indices: &Tensor<R>,
) -> Result<Tensor<R>, Error>
pub fn index_select( &self, dim: usize, indices: &Tensor<R>, ) -> Result<Tensor<R>, Error>
Select elements along a dimension using indices
Sourcepub fn argmax(&self, dim: usize, keepdim: bool) -> Result<Tensor<R>, Error>
pub fn argmax(&self, dim: usize, keepdim: bool) -> Result<Tensor<R>, Error>
Argmax along a dimension
Sourcepub fn argmin(&self, dim: usize, keepdim: bool) -> Result<Tensor<R>, Error>
pub fn argmin(&self, dim: usize, keepdim: bool) -> Result<Tensor<R>, Error>
Argmin along a dimension
Source§impl<R> Tensor<R>
impl<R> Tensor<R>
Trait Implementations§
Auto Trait Implementations§
impl<R> Freeze for Tensor<R>
impl<R> RefUnwindSafe for Tensor<R>
impl<R> Send for Tensor<R>
impl<R> Sync for Tensor<R>
impl<R> Unpin for Tensor<R>
impl<R> UnsafeUnpin for Tensor<R>
impl<R> UnwindSafe for Tensor<R>
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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 moreSource§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.