Skip to main content

Crate candle_einops

Crate candle_einops 

Source
Expand description

Compile-time einops-style tensor transformations for Candle.

The einops! macro combines rearrange, reduce, repeat, composition, and decomposition operations. einsum! provides explicit-output, arbitrary-arity Einstein summation. Backend failures are returned as Candle errors.

Einsum equations require exactly one ->, use whitespace-delimited named axes, and have one comma-separated input list per operand. Axes omitted from the output are summed, .. captures right-aligned runtime axes, and repeated labels select diagonals. See the repository’s docs/einsum-contract.md for the complete supported contract.

use candle_core::{Device, Result, Tensor};
use candle_einops::einops;

let input = Tensor::arange(0f32, 6f32, &Device::Cpu)?.reshape((2, 3))?;
let output = einops!("rows columns -> columns rows", &input)?;
assert_eq!(output.dims(), &[3, 2]);

A .. captures zero or more axes. Captures from multiple operands align from the right and broadcast, while omitting .. from the output reduces those axes:

use candle_core::{Device, Result, Tensor};
use candle_einops::einsum;

let input = Tensor::arange(0f32, 12f32, &Device::Cpu)?.reshape((2, 2, 3))?;
let reduced = einsum!(".. feature -> feature", &input)?;
assert_eq!(reduced.to_vec1::<f32>()?, [18., 22., 26.]);

Contractions lower through Candle matrix multiplication, including batch broadcasting. Equations with more than two operands use deterministic, shape-aware greedy pair selection:

use candle_core::{Device, Result, Tensor};
use candle_einops::einsum;

let left = Tensor::new(&[[1f32, 2., 3.], [4., 5., 6.]], &Device::Cpu)?;
let right = Tensor::new(&[[1f32, 2.], [3., 4.], [5., 6.]], &Device::Cpu)?;
let output = einsum!("row inner, inner column -> row column", &left, &right)?;
assert_eq!(output.to_vec2::<f32>()?, [[22., 28.], [49., 64.]]);
let weights = Tensor::new(&[1f32, 1.], &Device::Cpu)?;
let projected = einsum!(
    "row inner, inner column, column -> row",
    &left,
    &right,
    &weights,
)?;
assert_eq!(projected.to_vec1::<f32>()?, [50., 113.]);

Repeating a label within one operand extracts its diagonal. Omitting that label from the output computes a trace:

use candle_core::{Device, Result, Tensor};
use candle_einops::einsum;

let matrix = Tensor::arange(0f32, 9f32, &Device::Cpu)?.reshape((3, 3))?;
let diagonal = einsum!("index index -> index", &matrix)?;
assert_eq!(diagonal.to_vec1::<f32>()?, [0., 4., 8.]);
let trace = einsum!("index index ->", &matrix)?;
assert_eq!(trace.to_scalar::<f32>()?, 12.);

§Dtypes, devices, and gradients

einsum! never casts operands or transfers them between devices. Every operand in a multi-operand equation must have the same dtype and reside on the same device; mismatches return a contextual candle_core::Error. Unary permutations preserve every dtype supported by the corresponding Candle operation. Binary equations without contracted labels use Candle multiplication, including its integer and BF16 support. True contractions lower through Candle matrix multiplication and therefore inherit its dtype and device support: unsupported combinations return an error rather than being silently converted.

Einsum execution is assembled from tracked public Candle operations, so floating-point inputs participate in Candle autograd. Accelerator execution likewise follows the features and devices made available by Candle; results remain on the operands’ original device.

Unary einsum equations use whitespace-delimited named axes. Axes omitted from the explicit output are summed:

use candle_core::{Device, Result, Tensor};
use candle_einops::einsum;

let input = Tensor::arange(0f32, 6f32, &Device::Cpu)?.reshape((2, 3))?;
let columns = einsum!("rows columns -> columns", &input)?;
assert_eq!(columns.to_vec1::<f32>()?, [3., 5., 7.]);

Macros§

einops
Macro to perform tensor transformations using simple expressions
einsum
Evaluates an explicit-output Einstein summation equation.

Structs§

PreparedDiagonalPlan
Caller-owned, device-bound indices for repeated-axis diagonal extraction.

Enums§

Operation
Specifies the operation used to reduce an axis

Traits§

Backend
Tensor operations used by crate::einops!.

Type Aliases§

Result
The result type returned by einops! and Backend transformations.