API migration guide
This page is the first stop when an older tenferro-rs example fails with cannot find module, cannot find function, or a changed-signature error. The current public API favors explicit extension traits, fallible constructors, and session-owned execution. Historical worklogs are not API documentation.
Removed modules and free functions
| Older spelling | Current spelling |
|---|---|
tenferro_einsum::eager_tensor |
Import tenferro_einsum::EagerSessionEinsumExt and call the trait method on a borrowed session: ctx.with_eager_session(\|s\| s.einsum(&[&a, &b], "ij,jk->ik"))?. |
tenferro_einsum::EagerEinsumExt ([&a, &b].einsum(...) on eager values), EagerTensorEinsumExt (a.tensordot(&b, axes)) |
EagerSessionEinsumExt on a borrowed session: s.einsum(&[&a, &b], "ij,jk->ik"), s.einsum_notation(...), s.einsum_subscripts(...), s.tensordot(&a, &b, axes). |
tenferro_linalg::eager_tensor |
Import tenferro_linalg::EagerTensorLinalgExt and call the trait method on the eager value. |
tenferro_runtime::traced_tensor |
Use the current traced tensor types and their extension traits, such as tenferro_linalg::TracedTensorLinalgExt. |
tenferro_einsum::einsum |
Use the current trait method, for example TraceContextEinsumExt::einsum or TracedTensorEinsumExt::einsum, for the receiver you have. |
tenferro_einsum::einsum_subscripts_with |
Import the owning einsum extension trait and call its session/context method. |
tenferro_linalg::svd, qr, eigh, solve |
Import TensorLinalgExt, TypedTensorLinalgExt, or TensorReadLinalgExt and call .svd(...), .qr(...), .eigh(...), or .solve(...) on the input. |
tenferro_tensor::HostTensor<T> / HostTensorView<'a, T> |
TypedTensor<T, DynRank, Host> (from_host_vec_col_major, as_slice, host_data_mut) and TypedTensorView<'a, T, DynRank, Host> (from_host_slice, as_host_slice). Scalar-set members and ErasedHostTensor payloads use the same types. |
tenferro_tensor::core::{DefaultScalars, HostTensor, ...} |
tenferro_tensor::core re-exports metadata only; import tensor types, including DefaultScalars, from the tenferro_tensor root. |
TypedTensorView::try_slice, try_slice_axis, try_reshape (and the TypedTensorViewMut forms) |
slice_view, slice_axis_view, reshape_view. |
Owner-side execution on a backend: CpuBackend::to_contiguous / copy_into (TensorViewCanonicalization), TensorFusion, reclaim_buffer, with_linalg_pool, and the CUDA/WebGPU owner equivalents |
Enter once and call the method on the session: backend.with_backend_session(\|s\| s.to_contiguous_read(read))??. |
The owning crate’s prelude re-exports the public operation traits. For a first direct CPU program, the usual imports are:
use tenferro_cpu::CpuBackend;
use tenferro_linalg::prelude::*;
use tenferro_runtime::prelude::*;Then keep execution inside one session:
let mut backend = CpuBackend::new();
// The outer `?` reports session admission; the inner one the operation.
let values = backend.with_backend_session(|session| input.svdvals(session))??;Autodiff context changes
AdContextBuilder::with_core_rules() was removed. The core primitive rules are installed by the normal builder; start with:
let ad = tenferro_ad::AdContext::builder().build()?;When an operation family supplies semantic AD rules, install that family explicitly instead:
let ad = tenferro_ad::AdContext::builder()
.with_semantic_extension_rules(tenferro_linalg::semantic_ad_rules()?)?
.build()?;Fallible constructors and shape APIs
Constructors that validate storage, placement, or metadata return Result. Propagate the result instead of relying on an infallible constructor:
| Older assumption | Current spelling |
|---|---|
EagerTensor::from_tensor_in(tensor, ctx) returns a value |
EagerTensor::from_tensor_in(tensor, ctx)? |
EagerTensor::requires_grad_in(tensor, ctx) returns a value |
EagerTensor::requires_grad_in(tensor, ctx)? |
TracedTensor::input_concrete_shape(dtype, shape) is infallible |
TracedTensor::input_concrete_shape(dtype, shape)? |
TypedTensor::from_vec_col_major(shape, data) is infallible |
TypedTensor::from_vec_col_major(shape, data)? |
TypedTensor::zeros(shape) is infallible |
TypedTensor::zeros(shape)? |
reduce_sum uses an explicit optional axis list on eager values:
let total = value.reduce_sum(None)?; // all axes
let columns = value.reduce_sum(Some(&[0]))?; // selected axesAn empty slice remains distinct from None: use Some(&[]) when the API’s identity/no-axis behavior is what the program needs.
Changed signatures (2026-10)
| Older spelling | Current spelling |
|---|---|
ctx.with_eager_session(\|s\| s.neg(&x))?? (nested Result) |
ctx.with_eager_session(\|s\| s.neg(&x))?: the callback returns Result<T, E> with E: From<tenferro_ad::Error>, and session-entry failures arrive as E::from(..). Annotate Ok::<_, tenferro_ad::Error>(..) when the error type is not otherwise inferred; map tensor-level errors with .map_err(tenferro_ad::Error::from). Same for CpuPlacementBoundEager::with_eager_session. |
reduce_sum_squares(&x, &[0]) (eager), x.reduce_sum_squares(&[0]) (traced) |
Some(&[0]); None now reduces every axis, as for reduce_sum. |
x.reduce_sum(&[1], session) on Tensor / TypedTensor |
x.reduce_sum(Some(&[1]), session). |
session.gather(&x, &idx, &cfg) and other core ops only on the session |
Also x.gather(&idx, cfg, session) via TensorSessionOpsExt (see the session-surface notes in the guides). |
Tensor::from_vec_col_major with row-major data |
Tensor::from_vec_row_major(shape, data) reorders once into column-major storage. |
compile_with_input_specs with a placeholder the output does not use |
Rejected at compile time (InvalidArgument naming the binding); drop that binding. |
? on EagerFftInPlaceError in a tenferro_ad::Result function |
Works: From<EagerFftInPlaceError> for tenferro_ad::Error drops a rejected input. |
Finding the current method
- Choose the value tier: direct concrete tensor, eager tensor, or traced tensor.
- Import the
*Exttrait owned by the operation crate. - Check the method’s receiver and session arity in the API cheatsheet.
- Use the linear algebra guide, einsum guide, or custom operations guide for the relevant workflow.
Do not add a compatibility alias for a removed API. If a current example or error message contradicts this page, report the documentation gap through the issue-intake procedure after obtaining maintainer/user approval.