Expand description
Dense tensor type with CPU/GPU support.
This crate provides Tensor<T>, a multi-dimensional array type composed of
shape, strides, and a device-aware DataBuffer. It supports:
- Zero-copy view operations:
Tensor::permute,Tensor::broadcast,Tensor::diagonal,Tensor::select,Tensor::narrowmodify only metadata (dims/strides) - Data operations:
Tensor::contiguous/Tensor::into_contiguouscopy data into a contiguous layout (the consuming variant avoids allocation when the tensor is already contiguous);Tensor::tril/Tensor::triuextract triangular parts - Factory functions:
Tensor::zeros,Tensor::ones,Tensor::eye - DLPack interop:
DataBuffersupports both Rust-owned (Vec<T>) and externally-owned memory (e.g., imported via DLPack) with automatic cleanup.
§Memory layout
Tensor stores explicit strides and is not tied to any particular memory
order. MemoryOrder is only used as a parameter when allocating new memory
(e.g., Tensor::zeros, Tensor::contiguous).
§No strided-rs dependency
This crate does not depend on strided-rs. The strided-rs types
(StridedView, StridedViewMut) are backend implementation details
used only in tenferro-prims. To pass tensor data to prims backends,
use DataBuffer::as_slice combined with Tensor::dims,
Tensor::strides, and Tensor::offset.
§Examples
§Creating tensors
use tenferro_tensor::{Tensor, MemoryOrder};
use tenferro_device::LogicalMemorySpace;
// Zeros / ones
let a = Tensor::<f64>::zeros(&[3, 4], LogicalMemorySpace::MainMemory, MemoryOrder::ColumnMajor);
let b = Tensor::<f64>::ones(&[3, 4], LogicalMemorySpace::MainMemory, MemoryOrder::RowMajor);
// From existing data (column-major: Julia convention)
let data = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
let m = Tensor::<f64>::from_slice(&data, &[2, 3], MemoryOrder::ColumnMajor).unwrap();
// Logical layout:
// [[1, 3, 5],
// [2, 4, 6]]§Transpose and reshape
// Transpose a matrix (zero-copy, only strides change)
let mt = m.permute(&[1, 0]).unwrap();
assert_eq!(mt.dims(), &[3, 2]);
// Reshape (requires contiguous data)
let flat = m.reshape(&[6]).unwrap();
assert_eq!(flat.dims(), &[6]);§Broadcasting
// Column vector [3,1] broadcast to [3,4] for element-wise ops
let col = Tensor::<f64>::ones(&[3, 1], LogicalMemorySpace::MainMemory, MemoryOrder::ColumnMajor);
let expanded = col.broadcast(&[3, 4]).unwrap();
assert_eq!(expanded.dims(), &[3, 4]);
// No data is copied; stride along axis 1 is set to 0§TensorView — borrowed, zero-copy views
TensorView is the borrowed counterpart to Tensor, following the
String / &str pattern. View operations modify only metadata
(dims, strides, offset) and never copy data.
// tensor_view() borrows the tensor — no data copy
let tv = m.tensor_view();
assert_eq!(tv.dims(), m.dims());
// permute: reorder dimensions (zero-copy, strides reordered)
let tv_t = tv.permute(&[1, 0]).unwrap();
assert_eq!(tv_t.dims(), &[3, 2]);
// broadcast: expand size-1 dims (zero-copy, stride set to 0)
let col = Tensor::<f64>::from_slice(&[1.0, 2.0, 3.0], &[3, 1],
MemoryOrder::ColumnMajor).unwrap();
let col_tv = col.tensor_view();
let expanded = col_tv.broadcast(&[3, 4]).unwrap();
assert_eq!(expanded.dims(), &[3, 4]);
// diagonal: extract diagonal view (zero-copy, strides merged)
let sq = Tensor::<f64>::zeros(&[4, 4],
LogicalMemorySpace::MainMemory, MemoryOrder::ColumnMajor);
let sq_tv = sq.tensor_view();
let diag = sq_tv.diagonal(&[(0, 1)]).unwrap();
assert_eq!(diag.dims(), &[4]);
// to_tensor() / contiguous(): materialize a view into owned Tensor
let owned = tv_t.to_tensor(MemoryOrder::ColumnMajor);Structs§
- Completion
Event - Placeholder for an accelerator synchronization event.
- Data
Buffer - Data storage for tensor elements.
- Tensor
- Multi-dimensional dense tensor.
- Tensor
View - Borrowed tensor view, lifetime-tied to the source
Tensor.
Enums§
- Memory
Order - Memory ordering for new allocations.