pub struct Tensor { /* private fields */ }Expand description
A symbolic tensor in a traced graph.
Lazy by construction. Despite the eager-looking operator syntax, a
Tensor is a deferred handle: &a + &b, .relu(), .matmul(..) etc.
only append IR nodes — no host or device buffers are allocated and nothing
executes. The graph is compiled (fused + memory-planned) and run only
when you force it with to_vec / realize
(both require the eval feature). This is what lets the whole expression
fuse instead of materializing every intermediate.
Zero-copy clone & slice. clone() just bumps a refcount on the shared
graph handle — no data is duplicated. slice/narrow/reshape/select
add a view node into the same graph (referencing the parent by id), so
they move zero payload bytes either. Use shares_graph
to observe storage sharing and storage_bytes to
confirm no data was copied. (Combining two independently-constructed
tensors is the one case that copies — the right operand’s nodes are merged
in once; see [crate::handle].)
Implementations§
Source§impl Tensor
impl Tensor
Sourcepub fn from_vec(data: impl Into<Vec<f32>>, shape: impl AsRef<[usize]>) -> Self
pub fn from_vec(data: impl Into<Vec<f32>>, shape: impl AsRef<[usize]>) -> Self
Constant tensor from row-major host data (F32). The product of shape
must equal data.len().
Sourcepub fn full(shape: impl AsRef<[usize]>, value: f32) -> Self
pub fn full(shape: impl AsRef<[usize]>, value: f32) -> Self
Constant of the given shape filled with value (F32).
Sourcepub fn arange_step(start: i64, end: i64, step: i64) -> Self
pub fn arange_step(start: i64, end: i64, step: i64) -> Self
1-D constant [start, start+step, …) up to (excluding) end (F32).
Sourcepub fn from_f64(data: impl AsRef<[f64]>, shape: impl AsRef<[usize]>) -> Self
pub fn from_f64(data: impl AsRef<[f64]>, shape: impl AsRef<[usize]>) -> Self
F64 (double-precision) constant from host data.
Sourcepub fn from_i64(data: impl AsRef<[i64]>, shape: impl AsRef<[usize]>) -> Self
pub fn from_i64(data: impl AsRef<[i64]>, shape: impl AsRef<[usize]>) -> Self
I64 constant from host data (general N-D).
Sourcepub fn index_vec(data: impl AsRef<[i64]>) -> Self
pub fn index_vec(data: impl AsRef<[i64]>) -> Self
1-D I64 index vector for gather /
index_select.
Sourcepub fn rand(shape: impl AsRef<[usize]>, seed: u64) -> Self
pub fn rand(shape: impl AsRef<[usize]>, seed: u64) -> Self
Uniform random in [0, 1) (F32), reproducible from seed.
Sourcepub fn rand_range(
shape: impl AsRef<[usize]>,
seed: u64,
lo: f32,
hi: f32,
) -> Self
pub fn rand_range( shape: impl AsRef<[usize]>, seed: u64, lo: f32, hi: f32, ) -> Self
Uniform random in [lo, hi) (F32), reproducible from seed.
Source§impl Tensor
impl Tensor
Sourcepub fn id(&self) -> NodeId
pub fn id(&self) -> NodeId
IR node id (mix with raw rlx_ir::Graph builders via NodeId).
pub fn shape(&self) -> Shape
pub fn dtype(&self) -> DType
pub fn rank(&self) -> usize
Sourcepub fn is_static_shape(&self) -> bool
pub fn is_static_shape(&self) -> bool
True when every dimension is statically known.
True if self and other are backed by the same graph — i.e. one
is a clone or a view (slice/reshape/narrow/…) of the
other, sharing storage with zero copy. Tensors from independent
constructors return false until they’re combined in an op.
Sourcepub fn storage_bytes(&self) -> usize
pub fn storage_bytes(&self) -> usize
Total bytes of constant (payload) data physically held in the backing graph. Cloning and slicing do not increase this — they share storage and only add zero-payload view nodes. Combining tensors from different graphs copies the right-hand operand’s data in (once).
Sourcepub fn slice(&self, spec: SliceSpec) -> Self
pub fn slice(&self, spec: SliceSpec) -> Self
View slice — lowers to narrow (no copy at IR level).
pub fn matmul(&self, rhs: &Tensor) -> Self
Sourcepub fn scaled_matmul(
&self,
rhs: &Tensor,
fmt: ScaledFormat,
layout: ScaleLayout,
) -> Self
pub fn scaled_matmul( &self, rhs: &Tensor, fmt: ScaledFormat, layout: ScaleLayout, ) -> Self
Native low-precision GEMM (TN: self [m,k] · rhs [n,k]ᵀ → [m,n]).
Both operands are dynamically quantized to the minifloat fmt +
layout; rhs must be K-last ([n, k]). fmt may be any
ScaledFormat, including a parameterized Custom — e.g.
t.scaled_matmul(&w, ScaledFormat::custom(3, 0), ScaleLayout::mx()) runs
the matmul in f4e3m0.
pub fn softmax(&self, axis: i32) -> Self
pub fn reshape(&self, new_shape: impl Into<Vec<i64>>) -> Self
pub fn transpose(&self, perm: impl Into<Vec<usize>>) -> Self
pub fn t(&self) -> Self
pub fn cast(&self, to: DType) -> Self
pub fn narrow(&self, axis: usize, start: usize, len: usize) -> Self
Sourcepub fn broadcast_to(&self, shape: impl Into<Vec<i64>>) -> Self
pub fn broadcast_to(&self, shape: impl Into<Vec<i64>>) -> Self
Broadcast (expand) to an explicit target shape — NumPy broadcast_to.
A 1 axis stretches; sizes must otherwise match. Use -1-free static
targets.
Sourcepub fn unsqueeze(&self, axis: usize) -> Self
pub fn unsqueeze(&self, axis: usize) -> Self
Insert a size-1 axis at axis (NumPy expand_dims / PyTorch
unsqueeze).
Sourcepub fn squeeze(&self, axis: usize) -> Self
pub fn squeeze(&self, axis: usize) -> Self
Remove the size-1 axis at axis (panics if it is not size 1).
Sourcepub fn squeeze_all(&self) -> Self
pub fn squeeze_all(&self) -> Self
Remove every size-1 axis.
Sourcepub fn split(&self, axis: usize, sizes: &[usize]) -> Vec<Tensor>
pub fn split(&self, axis: usize, sizes: &[usize]) -> Vec<Tensor>
Split axis into contiguous pieces of the given sizes (must sum to
the axis length). NumPy split / PyTorch split_with_sizes.
Sourcepub fn chunk(&self, axis: usize, n: usize) -> Vec<Tensor>
pub fn chunk(&self, axis: usize, n: usize) -> Vec<Tensor>
Split axis into n near-equal chunks (first len % n get one extra).
Sourcepub fn tile(&self, axis: usize, reps: usize) -> Tensor
pub fn tile(&self, axis: usize, reps: usize) -> Tensor
Repeat the whole tensor reps times along axis (NumPy tile on one
axis): output axis length becomes len * reps.
Sourcepub fn flip(&self, axis: usize) -> Tensor
pub fn flip(&self, axis: usize) -> Tensor
Reverse the order of elements along axis (NumPy flip).
Sourcepub fn roll(&self, axis: usize, shift: usize) -> Tensor
pub fn roll(&self, axis: usize, shift: usize) -> Tensor
Cyclically shift elements along axis by shift (NumPy roll).
Sourcepub fn pad(
&self,
axis: usize,
before: usize,
after: usize,
value: f32,
) -> Tensor
pub fn pad( &self, axis: usize, before: usize, after: usize, value: f32, ) -> Tensor
Pad axis with before/after entries of value (constant pad).
pub fn gather(&self, indices: &Tensor, axis: usize) -> Self
Sourcepub fn index_select(&self, axis: usize, indices: &Tensor) -> Self
pub fn index_select(&self, axis: usize, indices: &Tensor) -> Self
Gather along axis by an index tensor — NumPy take / PyTorch
index_select. Alias for gather.
Sourcepub fn select(&self, axis: usize, index: i64) -> Self
pub fn select(&self, axis: usize, index: i64) -> Self
Pick a single position along axis, dropping that axis (NumPy
a[…, i, …]). Negative index counts from the end.
pub fn stop_gradient(&self) -> Self
Sourcepub fn argmax(&self, axis: usize, keep_dim: bool) -> Self
pub fn argmax(&self, axis: usize, keep_dim: bool) -> Self
Index of the maximum along axis (f32-encoded indices). Drops the axis
unless keep_dim.
Sourcepub fn argmin(&self, axis: usize, keep_dim: bool) -> Self
pub fn argmin(&self, axis: usize, keep_dim: bool) -> Self
Index of the minimum along axis (f32-encoded indices).
Sourcepub fn inv(&self) -> Self
pub fn inv(&self) -> Self
Matrix inverse of a square 2-D tensor. Composite over DenseSolve
(inv(A) = solve(A, I)), so it needs a BLAS-backed eval build (LAPACK)
to run, not the default splat backend.
Sourcepub fn solve(&self, b: &Tensor) -> Self
pub fn solve(&self, b: &Tensor) -> Self
Solve the linear system self @ x = b for x (LAPACK via DenseSolve;
needs a BLAS eval build). x takes b’s shape.
Sourcepub fn cumsum(&self, axis: i32, exclusive: bool) -> Self
pub fn cumsum(&self, axis: i32, exclusive: bool) -> Self
Cumulative sum along axis. exclusive shifts so output[0] = 0.
Sourcepub fn var(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
pub fn var(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
Population variance over axes: mean((x - mean(x))²).
Sourcepub fn std(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
pub fn std(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
Population standard deviation over axes.
Sourcepub fn norm(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
pub fn norm(&self, axes: impl Into<Vec<usize>>, keep_dim: bool) -> Self
L2 (Frobenius) norm over axes: sqrt(sum(x²)).
Sourcepub fn logsumexp(&self, axis: usize, keep_dim: bool) -> Self
pub fn logsumexp(&self, axis: usize, keep_dim: bool) -> Self
Numerically-stable log(sum(exp(x))) along axis
(max + log(sum(exp(x - max)))).
Sourcepub fn fft(&self) -> Self
pub fn fft(&self) -> Self
1-D FFT along the last axis (unnormalized; ifft(fft(x)) = N·x).
Complex data uses the [..., 2N] block layout (real plane then imag
plane) for F32/F64, or a C64 last axis. Output matches input shape.
Sourcepub fn ifft(&self) -> Self
pub fn ifft(&self) -> Self
Inverse 1-D FFT along the last axis (unnormalized — pairs with [fft]
up to the N factor).
Sourcepub fn fft_axis(&self, axis: usize, inverse: bool) -> Self
pub fn fft_axis(&self, axis: usize, inverse: bool) -> Self
1-D FFT along an arbitrary axis (transpose → fft → transpose).
pub fn layer_norm(&self, gamma: &Tensor, beta: &Tensor, eps: f32) -> Self
pub fn rms_norm(&self, gamma: &Tensor, beta: &Tensor, eps: f32) -> Self
pub fn conv2d( &self, weight: &Tensor, kernel_size: [usize; 2], stride: [usize; 2], padding: [usize; 2], dilation: [usize; 2], groups: usize, ) -> Self
pub fn attention( &self, k: &Tensor, v: &Tensor, num_heads: usize, head_dim: usize, mask_kind: MaskKind, ) -> Self
pub fn rope(&self, cos: &Tensor, sin: &Tensor, head_dim: usize) -> Self
pub fn where_(&self, on_true: &Tensor, on_false: &Tensor) -> Self
Sourcepub fn masked_fill(&self, mask: &Tensor, value: f64) -> Self
pub fn masked_fill(&self, mask: &Tensor, value: f64) -> Self
Replace entries of self where mask is true with value (NumPy
masked_fill / the attention-mask primitive: scores.masked_fill(causal, f32::NEG_INFINITY) then softmax). Requires a static shape.
pub fn pow(&self, rhs: &Tensor) -> Self
pub fn pow_scalar(&self, exp: f64) -> Self
Source§impl Tensor
impl Tensor
Sourcepub fn gelu_approx(&self) -> Self
pub fn gelu_approx(&self) -> Self
GELU, tanh approximation.