tenferro-tensor 0.2.0

Dense runtime tensors, views, backend traits, and backend-independent contracts for tenferro.
Documentation

tenferro-rs

tenferro-rs is a modular Rust tensor stack for scientific computing and general-purpose tensor workflows.

tenferro-rs architecture overview

Why tenferro-rs Exists

tenferro means tensor computation with an iron/Rust flavor: tensor + ferro.

The project aims to provide a Rust-native tensor stack for typed tensor computation, immediate execution with optional backward(), traced graph execution, automatic differentiation, linear algebra, einsum, FFT, and explicit CPU, CUDA, and experimental WebGPU backend control.

tenferro-rs is influenced by JAX and PyTorch in its split between immediate execution, traced graphs, and AD. It is also influenced by the Julia numerical computing ecosystem, where operation semantics and AD rules can live outside a single all-in-one tensor type.

tenferro-rs is Rust-native, but it should fit established numerical computing conventions rather than replacing them with project-specific rules. It uses Rust's type system, ownership model, and crate boundaries where those choices help.

We also see Rust's package system — fine-grained crates, feature flags, and semver-aware dependency composition — as a strong place for cross-ecosystem collaboration. tenferro-rs prefers to build on and contribute back to existing crates (GPU kernels, linear algebra, autodiff, contraction ordering) rather than reinvent them, and to bridge cleanly to the Fortran/LAPACK, Julia, and JAX/PyTorch worlds. The modular crate layout is meant to make tenferro components reusable as shared infrastructure, not just as an internal stack.

Design Principles

  • Keep tensor types and operation crates modular, rather than building one all-in-one tensor type.
  • Let users choose the lowest API that solves their problem. Autodiff, traced graphs, CUDA, experimental WebGPU, linalg, einsum, and FFT are opt-in capabilities.
  • Stay aligned with established numerical computing conventions where they fit: Rust's crate ecosystem, column-major conventions from Fortran, Julia, MATLAB, and LAPACK-oriented workflows, and Rust numerics crates such as faer, num-traits, and num-complex.
  • Make dependencies, feature flags, backends, and devices explicit. tenferro does not silently move tensor data between CPU and GPU.
  • Support both Rust-typed tensors and tensors whose dtype is selected at runtime.
  • Treat extension operations and AD rules as part of the design, so external crates can add operations without growing the core tensor crates.
  • Manage engineering quality through three pillars — reference oracles (finite-difference and Torch reference data), a comprehensive unit-test suite with enforced per-file coverage thresholds, and a reproducible benchmark suite — backed by invariants, residual checks, and provenance checks. This engineering discipline is what lets the project iterate quickly (see Stability Policy) without sacrificing correctness.

When tenferro Is a Good Fit

tenferro-rs is designed for workloads where tensor shapes are not always fixed before execution. If your computation involves runtime-dependent ranks, threshold-based filtering, data-dependent iteration counts, or shape-parametric models, tenferro's traced execution can reuse a compiled program while resolving the concrete sizes at runtime.

It also fits small-to-medium batched linear algebra with autodiff, grad/vjp/jvp/HVP workflows in Rust, Rust-native tensor applications, and extension points for custom algebra or operation families.

The experimental tenferro-xla crate lowers static-shaped traced graph programs to StableHLO and can load PJRT plugins at runtime through environment variables. Dynamic-shape graphs remain the native runtime's core use case. See the XLA and PJRT guide.

Why Build On tenferro-rs

tenferro-rs aims to be a pure-Rust tensor stack for scientific and numerical computing — one you can build on, extend, and ship as a single binary, rather than a wrapper around a C++ or Python engine. What that gives you:

  • A complete stack, natively in Rust. Typed tensors, eager execution with backward(), traced graphs with reuse, grad/vjp/jvp/HVP autodiff, linear algebra, einsum, and FFT — all carried by Rust's type system, ownership model, and tooling, with no Python runtime.
  • Extensible operations and AD rules. Operations and their AD rules live outside the core tensor crates. An external crate can introduce a new operation family — even a different algebra — register its linearize/transpose_rule, and have it flow through the same eager and traced autodiff as the built-in ops. The ext/tropical semiring extension is a worked example; see docs/guides/custom-operations.md.
  • Fits the numerical-computing world. Column-major storage lines up with Fortran, Julia, MATLAB, Eigen3, and LAPACK/BLAS, and strided views bridge to row-major data without eager copies (see docs/guides/memory-order.md). tenferro-rs builds on faer for dense linear algebra and on CubeCL for GPU kernels, contributing to the Rust ecosystem rather than reinventing it.
  • Built for shapes you only know at runtime. A traced program is compiled once and reused while concrete sizes — ranks, truncation thresholds, data-dependent iteration counts — resolve at execution time.

If your host language is Python, JAX and PyTorch are the natural choice. tenferro-rs is for the projects that want this kind of stack natively in Rust.

Which API Should I Use?

If your workflow needs Start with
Fixed scalar type, ordinary tensor computation, no autodiff TypedTensor<T, R>
Runtime dtype selection or direct backend dispatch Tensor with an explicit backend
Immediate execution in one runtime, optionally with backward() on scalar losses EagerTensor and EagerRuntime
grad, vjp, and jvp on traced graphs, graph reuse, or repeated compile/run execution TracedTensor, GraphCompiler, and GraphExecutor<B>
CUDA or experimental WebGPU execution The same tensor API plus explicit GPU upload/download and supported provider backend features
Static-shaped StableHLO and PJRT plugin experiments GraphCompiler plus tenferro-xla

Crates

tenferro-rs is a multi-crate workspace. There is intentionally no tenferro facade crate; users depend on the crates they need directly.

Core User Crates

Crate Use when you need
tenferro-tensor Tensor values, typed tensors, views, dtype/runtime tensor contracts, and backend traits
tenferro-cpu CPU backend execution
tenferro-gpu CUDA backend support, experimental WebGPU support, future ROCm substrate, and explicit device transfers
tenferro-runtime Eager/traced execution, graph compilation, and extension runtime support
tenferro-ad Automatic differentiation
tenferro-xla Experimental StableHLO lowering and runtime-loaded PJRT plugin support for static-shaped traced graphs

Standard Operation Extensions

Crate Use when you need
tenferro-linalg Linear algebra operations
tenferro-einsum Einsum and contraction planning
tenferro-fft FFT operations

Implementation Crates

Crate Use when you need
tenferro-tensor-core Host tensor storage, dtype tags, and metadata-only layouts
tenferro-core-ops Core primitive operation metadata shared by runtimes and backends
tenferro-internal-ops Published implementation crate for internal graph op vocabulary and AD rule implementations used by tenferro crates
tenferro-internal-extension-macros Procedural macros for registering internal extension operation descriptors

Minimal CPU Example

Create a binary crate that depends on tenferro-runtime and tenferro-cpu. The same runnable example lives at crates/tenferro-runtime/examples/cpu_quickstart.rs. For a local checkout, the full setup notes are in docs/getting-started/index.md, including the empty [workspace] table needed by scratch crates created inside this repository.

use tenferro_cpu::CpuBackend;
use tenferro_runtime::{Tensor, TensorOpsExt};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut backend = CpuBackend::new();

    let a = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 3.0, 2.0, 4.0])?;
    let b = Tensor::from_vec_col_major(vec![2, 2], vec![5.0_f64, 7.0, 6.0, 8.0])?;

    let c = a.matmul(&b, &mut backend)?;

    assert_eq!(c.shape(), &[2, 2]);
    assert_eq!(c.as_slice::<f64>().unwrap(), &[19.0, 43.0, 22.0, 50.0]);

    Ok(())
}

Documentation

The full guides, tutorials, API reference, architecture notes, and specifications live at https://tensor4all.org/tenferro-rs/. Start with Getting Started if you are using tenferro-rs for the first time.

Benchmarks And Numerical Validation

Official benchmark suites and result tooling live in tensor4all/tenferro-benchmark. Run them there for reproducible cross-backend performance numbers rather than relying on ad hoc local timings.

Numerical correctness — especially automatic differentiation — is validated against reference oracles (finite-difference checks and Torch reference data) rather than line coverage alone. See the oracle support table for the per-operation AD coverage status and the tensor4all/tensor-ad-oracles dataset repository.

Get In Touch

Questions, design discussions, and contributor coordination for tenferro happen in the tenferro Matrix room:

Matrix is an open, federated chat protocol. You can join from a Matrix client such as Element, or through the browser flow opened by the link above.

Use GitHub issues for bug reports, feature requests, and decisions that need tracking; use Matrix for lightweight discussion before filing or implementing changes. The broader tensor4all community also uses the tensor4all mailing list for announcements, and the community entry point is https://tensor4all.org/.

Acknowledgments

tenferro-rs stands on excellent work across several ecosystems, and aims to integrate with and contribute back to them rather than wall itself off — even as it iterates quickly.

  • GPU. The GPU backend is built on CubeCL by the tracel-ai team (also the foundation of the Burn deep learning framework). The temporary t4a-* CubeCL/CubeK crates stage tensor4all fork patches until those changes are upstream, with the intent to converge back rather than fork the ecosystem.
  • CPU / numerics. Dense CPU linear algebra builds on faer, with numeric foundations from num-traits and num-complex.
  • Contraction ordering. Einsum contraction-order optimization uses omeco, carrying over ideas from the Julia tensor-network ecosystem (OMEinsum/contraction-order tooling).
  • Design heritage. The modular structure — operation semantics and AD rules living outside an all-in-one tensor type — is influenced by the Julia numerical-computing community (e.g. the ChainRules and OMEinsum/tensor-network ecosystems), and by JAX/PyTorch for the eager/traced/AD split.
  • Generic autodiff. Autodiff is built on tidu, a tensor4all crate providing Primitive-generic graph transforms (linearize / linear_transpose) that are not tied to tensors and can drive autodiff for other domains.

Thanks to these projects, communities, and their maintainers.

Stability Policy

tenferro-rs is a pre-1.0 experimental research platform. Before v1.0, public APIs may change substantially, including across 0.1.x releases: at this stage we prioritize rapid iteration, backend exploration, and AI-assisted development over API stability.

This does not mean correctness or engineering discipline is relaxed. We keep tests, runnable examples, documentation, and migration notes for major changes up to date, and changes are accepted only after the checks described in Development And Trust Model — repository rules, CI, oracle-based validation, reproducible benchmarks, provenance checks, and maintainer review. The detailed, current API documentation is the primary reference for following the library as it evolves; we write migration notes for major breaking changes rather than maintaining exhaustive compatibility tables.

For downstream projects, pin exact versions or commits, and when upgrading use AI-assisted refactoring against the current docs to follow breaking changes. The stack is dogfooded in tensor4all-rs and related tensor4all projects.

AI-Assisted Development

tenferro-rs assumes AI-assisted and agentic coding for development, migration, and review. AI output is not accepted as authority by itself: changes are validated against repository rules, source-of-truth code and doc comments, CI, oracle-based numerical checks, reproducible benchmarks when relevant, provenance checks, and maintainer review.

Correctness and consistency are also kept by a retained knowledge base that the project builds on rather than rediscovers each time: durable repository and engineering rules (REPOSITORY_RULES.md and the shared tensor4all-agent-rules), design documents (docs/design/, docs/spec/), and the history of past development decisions (work logs in docs/worklogs/ and review-decision records). This institutional memory is what keeps a fast, AI-assisted workflow coherent: rules and recorded decisions constrain new changes — including AI-generated ones — toward the established design.

Documentation–implementation consistency is itself audited regularly by agents, on top of the automated doc-snippet and docs-site checks in CI (every doc example must compile and run). Because the current API documentation is the primary reference for following the library as it evolves, keeping the docs aligned with the code is treated as a correctness concern, not an afterthought.

Contributing

Bug reports, minimal reproducers, proposed regression tests, feature requests, design discussions, documentation improvements, benchmark reports, and prototype branches are welcome in issues. Pull request creation is currently restricted to collaborators.

Collaborator implementation PRs for new features must start from accepted feature request issues so API, backend, AD, dependency, and testing implications can be reviewed first.

See CONTRIBUTING.md for the external contribution policy and the supported AI-assisted issue-intake and collaborator bug-fix PR workflows across Codex CLI, Claude Code, OpenCode, and Kimi CLI.

See GOVERNANCE.md for maintainer roles, merge authority, and the project-direction decision model. Maintainers are listed in CONTRIBUTORS.md.