Skip to main content

LinalgBackend

Trait LinalgBackend 

Source
pub trait LinalgBackend: Engine {
Show 28 methods // Required methods fn cholesky(&mut self, input: &Tensor) -> Result<Tensor>; fn triangular_solve( &mut self, a: &Tensor, b: &Tensor, left_side: bool, lower: bool, transpose_a: bool, unit_diagonal: bool, ) -> Result<Tensor>; fn lu(&mut self, input: &Tensor) -> Result<Vec<Tensor>>; fn full_piv_lu(&mut self, input: &Tensor) -> Result<Vec<Tensor>>; fn full_piv_lu_solve( &mut self, a: &Tensor, b: &Tensor, transpose_a: bool, ) -> Result<Tensor>; fn svd(&mut self, input: &Tensor) -> Result<Vec<Tensor>>; fn qr(&mut self, input: &Tensor) -> Result<Vec<Tensor>>; fn eigh(&mut self, input: &Tensor) -> Result<Vec<Tensor>>; fn eig(&mut self, input: &Tensor) -> Result<Vec<Tensor>>; fn solve(&mut self, a: &Tensor, b: &Tensor) -> Result<Tensor>; // Provided methods fn triangular_solve_read( &mut self, _a: TensorRead<'_>, _b: TensorRead<'_>, _left_side: bool, _lower: bool, _transpose_a: bool, _unit_diagonal: bool, ) -> Result<Tensor> { ... } fn svd_with_options( &mut self, input: &Tensor, options: SvdOptions, ) -> Result<Vec<Tensor>> { ... } fn svd_full(&mut self, _input: &Tensor) -> Result<Vec<Tensor>> { ... } fn svd_full_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>> { ... } fn svd_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>> { ... } fn svd_with_options_read( &mut self, input: TensorRead<'_>, options: SvdOptions, ) -> Result<Vec<Tensor>> { ... } fn qr_with_options( &mut self, input: &Tensor, options: QrOptions, ) -> Result<Vec<Tensor>> { ... } fn qr_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>> { ... } fn qr_with_options_read( &mut self, input: TensorRead<'_>, options: QrOptions, ) -> Result<Vec<Tensor>> { ... } fn eigh_with_options( &mut self, input: &Tensor, options: EighOptions, ) -> Result<Vec<Tensor>> { ... } fn eigh_with_options_read( &mut self, input: TensorRead<'_>, options: EighOptions, ) -> Result<Vec<Tensor>> { ... } fn eigh_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>> { ... } fn cholesky_read(&mut self, _input: TensorRead<'_>) -> Result<Tensor> { ... } fn lu_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>> { ... } fn full_piv_lu_read( &mut self, _input: TensorRead<'_>, ) -> Result<Vec<Tensor>> { ... } fn eig_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>> { ... } fn solve_read( &mut self, _a: TensorRead<'_>, _b: TensorRead<'_>, ) -> Result<Tensor> { ... } fn solve_read_into( &mut self, a: TensorRead<'_>, b: TensorRead<'_>, out: TensorWrite<'_>, ) -> Result<()> { ... }
}
Expand description

Backend surface required by the linalg extension runtime.

§Examples

use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::backend::LinalgBackend;

fn assert_linalg_backend<B: LinalgBackend>() {}

assert_linalg_backend::<CpuEngine>();
let mut host = tenferro_cpu::CpuEngine::serial();
{
    with_cpu_engine(&mut host, |_backend| ())
        .expect("CpuEngine must expose a CpuEngine");
};

Required Methods§

Source

fn cholesky(&mut self, input: &Tensor) -> Result<Tensor>

Compute a Cholesky factorization.

§Errors

Returns Error::Validation for non-matrix, non-square, or unsupported input dtypes; Error::Extension with ErrorKind::NumericalFailure when the matrix is not positive definite; or a typed backend source when the provider cannot execute the factorization.

Source

fn triangular_solve( &mut self, a: &Tensor, b: &Tensor, left_side: bool, lower: bool, transpose_a: bool, unit_diagonal: bool, ) -> Result<Tensor>

Solve a triangular linear system with explicit side, triangle, transpose, and unit-diagonal flags.

§Errors

Returns Error::Validation for incompatible matrix/rhs shapes, rank, or dtype; Error::Extension with ErrorKind::NumericalFailure for a singular or zero-diagonal system; or a typed backend source for a provider failure.

Source

fn lu(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Compute public LU outputs (P, L, U, parity).

§Errors

Returns Error::Validation when the input is not a supported matrix or dtype, and Error::Extension or a typed backend source when LU execution or pivot storage fails.

Source

fn full_piv_lu(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Compute complete-pivot LU outputs (P, L, U, Q, parity).

The reconstruction convention is A = P^T * L * U * Q, equivalently P * A * Q^T = L * U. parity is a scalar real tensor containing +1 or -1: F32 for F32/C32 inputs and F64 for F64/C64 inputs.

§Errors

Returns Error::Validation for an invalid rank, square-shape requirement, or dtype, and Error::Extension or a typed backend source when complete-pivot factorization cannot be executed.

Source

fn full_piv_lu_solve( &mut self, a: &Tensor, b: &Tensor, transpose_a: bool, ) -> Result<Tensor>

Solve a linear system through the complete-pivot LU path.

With transpose_a = false, this solves A * x = b. With transpose_a = true, this solves A^T * x = b.

§Errors

Returns Error::Validation for incompatible coefficient/rhs shapes or dtypes, Error::Extension with ErrorKind::NumericalFailure for a singular system, or a typed backend source for provider failure.

Source

fn svd(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Compute public SVD outputs (U, S, Vt).

§Errors

Returns Error::Validation for an unsupported rank or dtype and a typed Error::Extension or backend source when the solver fails.

Source

fn qr(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Compute public QR outputs (Q, R).

QR is thin: for an m x n input, Q has shape m x min(m, n) and R has shape min(m, n) x n.

This is LinalgBackend::qr_with_options with default options. The CUDA provider does not inspect the cuSOLVER device status flags for ordinary QR; synchronous provider errors still propagate. It does not report rank deficiency: shapes and dtypes are validated up front, and a rank-deficient input still yields its valid (Q, R) factors.

§Errors

Returns Error::Validation for an unsupported rank, shape, or dtype, and a typed Error::Extension or backend source when QR execution fails.

Source

fn eigh(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Compute public Hermitian eigendecomposition outputs (values, vectors).

The returned vector order is [values, vectors], where values has shape [n] and vectors has shape [n, n].

§Errors

Returns Error::Validation for a non-square or unsupported-dtype input and a typed Error::Extension or backend source when eigendecomposition fails.

Source

fn eig(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Compute public general eigendecomposition outputs (values, vectors). Eigenvectors come back with unit 2-norm columns, whichever provider computed them; a column the provider left non-finite is reported as a numerical failure instead of being returned as NaN (#2148).

§Errors

Returns Error::Validation for a non-square, rank, or dtype mismatch, and a typed Error::Extension or backend source when the eigensolver fails.

Source

fn solve(&mut self, a: &Tensor, b: &Tensor) -> Result<Tensor>

Solve a dense linear system.

The CUDA provider does not inspect the cuSOLVER getrf status flag on the forward solve path, so it performs no per-call non-singularity check and issues no host round trip. An exactly singular input is left to the caller’s verification, as in torch.linalg.solve. CPU providers may still report their own exactly singular factor as Error::Singular.

§Errors

Returns Error::Validation for incompatible matrix/rhs shapes, rank, or dtype; Error::Extension with ErrorKind::NumericalFailure for a singular system; or a typed backend source for provider failure.

Provided Methods§

Source

fn triangular_solve_read( &mut self, _a: TensorRead<'_>, _b: TensorRead<'_>, _left_side: bool, _lower: bool, _transpose_a: bool, _unit_diagonal: bool, ) -> Result<Tensor>

Solve a triangular linear system from tensor read targets.

Backends may canonicalize the inputs inside the same placement family, but must not silently transfer between CPU and GPU memory.

§Examples
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::LinalgBackend;
use tenferro_tensor::{Tensor, TensorRead};

let a = Tensor::from_vec_col_major(vec![2, 2], vec![2.0_f64, 0.0, 1.0, 3.0])?;
let b = Tensor::from_vec_col_major(vec![2, 1], vec![4.0_f64, 9.0])?;
let mut host = tenferro_cpu::CpuEngine::serial();
let x = {
    with_cpu_engine(&mut host, |backend| {
        backend.triangular_solve_read(
            TensorRead::from_tensor(&a),
            TensorRead::from_tensor(&b),
            true,
            false,
            false,
            false,
        )
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
let x = x.into_typed::<f64>().expect("F64 inputs return F64 output");
assert_eq!(x.host_data()?, &[0.5, 3.0]);
§Errors

The default implementation returns Error::Unsupported because the backend does not accept tensor read targets. Implementations may return Error::Validation for incompatible shapes or dtypes, Error::RuntimeState for invalid placement, Error::Extension for a singular system, or a typed backend-source error.

Source

fn svd_with_options( &mut self, input: &Tensor, options: SvdOptions, ) -> Result<Vec<Tensor>>

Compute public SVD outputs (U, S, Vt) with explicit options.

derivative_eps is validated for API consistency, but concrete backend execution does not perform AD. gauge controls optional singular-vector post-processing. driver selects the cuSOLVER routine on the CUDA backend; the default implementation ignores it because CPU providers have a single SVD kernel.

§Examples
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::{LinalgBackend, SvdGauge, SvdOptions};
use tenferro_tensor::Tensor;

let input = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 0.0, 0.0, 2.0])?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.svd_with_options(
            &input,
            SvdOptions::default().gauge(SvdGauge::CanonicalPivot),
        )
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs[1].shape(), &[2]);
§Errors

Returns tenferro_tensor::Error::Validation containing tenferro_tensor::ValidationError::InvalidArgument when derivative_eps is non-finite or non-positive, or when canonical gauge output metadata is malformed. It can return tenferro_tensor::Error::Validation with tenferro_tensor::ValidationError::RankMismatch, tenferro_tensor::ValidationError::ShapeMismatch, or tenferro_tensor::ValidationError::DTypeMismatch for the input or generated outputs, tenferro_tensor::Error::Extension with the typed tenferro_linalg::Error::UnsupportedDType or NonConvergence source, tenferro_tensor::Error::BackendSource for provider calls, and tenferro_tensor::Error::RuntimeState for placement failures. A CPU provider that was not compiled is reported as tenferro_tensor::ValidationError::InvalidArgument on the provider configuration.

Source

fn svd_full(&mut self, _input: &Tensor) -> Result<Vec<Tensor>>

Compute public full-matrices SVD outputs (U, S, Vt) with U shaped m x m and Vt shaped n x n, so the trailing Vt rows span the input’s right nullspace.

§Errors

The default implementation returns Error::Unsupported: a backend that does not implement the full variant reports it explicitly rather than silently falling back to the thin decomposition. Implementing backends may additionally return Error::Validation for an unsupported rank or dtype and a typed backend source when the solver fails.

Source

fn svd_full_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>>

Compute full-matrices SVD outputs (U, S, Vt) from a tensor read target.

This is the borrowed-input counterpart of LinalgBackend::svd_full and keeps the same output contract: U is m x m, S has min(m, n) entries, and Vt is n x n. Backends may canonicalize the input inside the same placement family, but must not silently transfer between CPU and GPU memory, and must not substitute the thin decomposition.

§Examples
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::LinalgBackend;
use tenferro_tensor::{TensorRead, TensorView, TypedTensor};

let input = TypedTensor::<f64>::from_vec_col_major(vec![1, 2], vec![1.0, 1.0])?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.svd_full_read(TensorRead::from_view(TensorView::F64(input.as_view())))
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs[0].shape(), &[1, 1]);
assert_eq!(outputs[1].shape(), &[1]);
assert_eq!(outputs[2].shape(), &[2, 2]);
§Errors

The default implementation returns Error::Unsupported because the backend does not accept tensor read targets for the full variant; an implementation may instead return Error::Validation for an unsupported rank or dtype, Error::Unsupported when the selected provider has no full-matrices kernel, and a typed backend source when the solver fails.

Source

fn svd_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>>

Compute a singular value decomposition from a tensor read target.

Backends may canonicalize the input inside the same placement family, but must not silently transfer between CPU and GPU memory.

§Examples
use tenferro_linalg::LinalgBackend;
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_tensor::{TensorRead, TensorView, TypedTensor};

let input = TypedTensor::<f64>::from_vec_col_major(
    vec![2, 2],
    vec![1.0, 0.0, 0.0, 2.0],
)?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.svd_read(TensorRead::from_view(TensorView::F64(input.as_view())))
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs[1].shape(), &[2]);
§Errors

The default implementation returns Error::Unsupported because the backend does not accept tensor read targets; an implementation may instead return validation or typed backend-source errors after canonicalizing the view.

Source

fn svd_with_options_read( &mut self, input: TensorRead<'_>, options: SvdOptions, ) -> Result<Vec<Tensor>>

Compute public SVD outputs (U, S, Vt) from a tensor read target with explicit options.

This is the borrowed-input counterpart of LinalgBackend::svd_with_options. The default implementation runs LinalgBackend::svd_read and applies the gauge on the host; it ignores driver because CPU providers have a single SVD kernel. The CUDA backend overrides it so the driver reaches cuSOLVER.

§Examples
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::{LinalgBackend, SvdDriver, SvdOptions};
use tenferro_tensor::{TensorRead, TensorView, TypedTensor};

let input = TypedTensor::<f64>::from_vec_col_major(
    vec![2, 2],
    vec![1.0, 0.0, 0.0, 2.0],
)?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.svd_with_options_read(
            TensorRead::from_view(TensorView::F64(input.as_view())),
            SvdOptions::default().driver(SvdDriver::Gesvd),
        )
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs[1].shape(), &[2]);
§Errors

Returns tenferro_tensor::Error::Validation containing tenferro_tensor::ValidationError::InvalidArgument when derivative_eps is non-finite or non-positive, plus the validation, unsupported-dtype, numerical, placement, or typed backend/provider errors from LinalgBackend::svd_read and the gauge metadata and host-access errors from the default host gauge path.

Source

fn qr_with_options( &mut self, input: &Tensor, options: QrOptions, ) -> Result<Vec<Tensor>>

Compute public QR outputs (Q, R) with explicit options.

gauge controls optional sign or phase post-processing. The CUDA provider does not inspect the cuSOLVER device status flags for ordinary QR; synchronous provider errors still propagate. It does not report rank deficiency: shapes and dtypes are validated up front, and a rank-deficient input still yields its valid factors. The caller’s own verification decides whether those factors are acceptable.

§Examples
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::{LinalgBackend, QrGauge, QrOptions};
use tenferro_tensor::Tensor;

let input = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 0.0, 0.0, 2.0])?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.qr_with_options(
            &input,
            QrOptions::default().gauge(QrGauge::PositiveDiagonal),
        )
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs[0].shape(), &[2, 2]);
§Errors

Returns tenferro_tensor::Error::Validation containing tenferro_tensor::ValidationError::RankMismatch or tenferro_tensor::ValidationError::ShapeMismatch for an invalid matrix input, or tenferro_tensor::ValidationError::InvalidArgument for malformed gauge output metadata, checked size arithmetic, or an unavailable compiled provider. A mismatched generated Q/R dtype is reported as tenferro_tensor::ValidationError::DTypeMismatch. Provider unsupported dtype or numerical rejection is tenferro_tensor::Error::Extension with a typed linalg source, while provider failures use tenferro_tensor::Error::BackendSource and a backend-resident input uses tenferro_tensor::Error::RuntimeState.

Source

fn qr_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>>

Compute public QR outputs (Q, R) from a tensor read target.

Backends may canonicalize the input inside the same placement family, but must not silently transfer between CPU and GPU memory.

§Examples
use tenferro_linalg::LinalgBackend;
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_tensor::{TensorRead, TensorView, TypedTensor};

let input = TypedTensor::<f64>::from_vec_col_major(
    vec![2, 2],
    vec![1.0, 0.0, 0.0, 2.0],
)?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.qr_read(TensorRead::from_view(TensorView::F64(input.as_view())))
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs[0].shape(), &[2, 2]);
assert_eq!(outputs[1].shape(), &[2, 2]);
§Errors

The default implementation returns Error::Unsupported because the backend does not accept tensor read targets; implementations may return validation or typed backend-source errors.

Source

fn qr_with_options_read( &mut self, input: TensorRead<'_>, options: QrOptions, ) -> Result<Vec<Tensor>>

Compute public QR outputs (Q, R) from a tensor read target with options.

Device backends override this hook to keep gauge processing in the input placement. The default is appropriate for host backends.

§Examples
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::{LinalgBackend, QrGauge, QrOptions};
use tenferro_tensor::{Tensor, TensorRead};

let input = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 0.0, 0.0, 2.0])?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.qr_with_options_read(
            TensorRead::from_tensor(&input),
            QrOptions::default().gauge(QrGauge::PositiveDiagonal),
        )
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs[0].shape(), &[2, 2]);
§Errors

Returns the validation, unsupported-dtype, numerical, placement, or typed backend/provider errors from LinalgBackend::qr_read, plus gauge metadata and host-access errors from the default host gauge path.

Source

fn eigh_with_options( &mut self, input: &Tensor, options: EighOptions, ) -> Result<Vec<Tensor>>

Compute public Hermitian eigendecomposition outputs with explicit options.

derivative_eps is validated for API consistency, but concrete backend execution does not perform AD. gauge controls optional eigenvector post-processing.

§Examples
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::{EighGauge, EighOptions, LinalgBackend};
use tenferro_tensor::Tensor;

let input = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 0.0, 0.0, 2.0])?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.eigh_with_options(
            &input,
            EighOptions::default()
                .gauge(EighGauge::CanonicalPivot)
                .derivative_eps(1.0e-10),
        )
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs[0].shape(), &[2]);
§Errors

Returns tenferro_tensor::Error::Validation containing tenferro_tensor::ValidationError::InvalidArgument when derivative_eps is non-finite or non-positive, when canonical gauge output metadata is malformed, or when checked output-size arithmetic overflows. It can return tenferro_tensor::Error::Validation with tenferro_tensor::ValidationError::RankMismatch or tenferro_tensor::ValidationError::ShapeMismatch for the matrix input, or tenferro_tensor::ValidationError::DTypeMismatch for generated outputs. It can also return tenferro_tensor::Error::Extension with typed tenferro_linalg::Error::UnsupportedDType or NonConvergence, and tenferro_tensor::Error::BackendSource or tenferro_tensor::Error::RuntimeState for provider and placement failures.

Source

fn eigh_with_options_read( &mut self, input: TensorRead<'_>, options: EighOptions, ) -> Result<Vec<Tensor>>

Compute public eigh outputs (values, vectors) from a tensor read target with explicit options.

This is the borrowed-input counterpart of LinalgBackend::eigh_with_options. The default implementation runs LinalgBackend::eigh_read and applies the gauge on the host; it ignores driver because CPU providers have a single eigh kernel. The CUDA backend overrides it so the driver reaches cuSOLVER.

§Examples
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::{EighDriver, EighOptions, LinalgBackend};
use tenferro_tensor::{TensorRead, TensorView, TypedTensor};

let input = TypedTensor::<f64>::from_vec_col_major(
    vec![2, 2],
    vec![2.0, 0.0, 0.0, 3.0],
)?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.eigh_with_options_read(
            TensorRead::from_view(TensorView::F64(input.as_view())),
            EighOptions::default().driver(EighDriver::Syevj),
        )
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs[0].shape(), &[2]);
§Errors

Returns tenferro_tensor::Error::Validation containing tenferro_tensor::ValidationError::InvalidArgument when derivative_eps is non-finite or non-positive, plus the validation, unsupported-dtype, numerical, placement, or typed backend/provider errors from LinalgBackend::eigh_read and the gauge metadata and host-access errors from the default host gauge path.

Source

fn eigh_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>>

Compute public Hermitian eigendecomposition outputs from a tensor read target.

Backends may canonicalize the input inside the same placement family, but must not silently transfer between CPU and GPU memory.

§Examples
use tenferro_linalg::LinalgBackend;
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_tensor::{TensorRead, TensorView, TypedTensor};

let input = TypedTensor::<f64>::from_vec_col_major(
    vec![2, 2],
    vec![1.0, 0.0, 0.0, 2.0],
)?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.eigh_read(TensorRead::from_view(TensorView::F64(input.as_view())))
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs[0].shape(), &[2]);
assert_eq!(outputs[1].shape(), &[2, 2]);
§Errors

The default implementation returns Error::Unsupported because the backend does not accept tensor read targets; implementations may return validation or typed backend-source errors.

Source

fn cholesky_read(&mut self, _input: TensorRead<'_>) -> Result<Tensor>

Compute Cholesky factorization from a tensor read target.

Backends may canonicalize the input inside the same placement family, but must not silently transfer between CPU and GPU memory.

§Examples
use tenferro_linalg::LinalgBackend;
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_tensor::{TensorRead, TensorView, TypedTensor};

let input = TypedTensor::<f64>::from_vec_col_major(
    vec![2, 2],
    vec![4.0, 2.0, 2.0, 3.0],
)?;
let mut host = tenferro_cpu::CpuEngine::serial();
let output = {
    with_cpu_engine(&mut host, |backend| {
        backend.cholesky_read(TensorRead::from_view(TensorView::F64(input.as_view())))
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(output.shape(), &[2, 2]);
§Errors

The default implementation returns Error::Unsupported because the backend does not accept tensor read targets; implementations may return validation or typed backend-source errors.

Source

fn lu_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>>

Compute public LU outputs from a tensor read target.

Backends may canonicalize the input inside the same placement family, but must not silently transfer between CPU and GPU memory.

§Examples
use tenferro_linalg::LinalgBackend;
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_tensor::{TensorRead, TensorView, TypedTensor};

let input = TypedTensor::<f64>::from_vec_col_major(
    vec![2, 2],
    vec![1.0, 3.0, 2.0, 4.0],
)?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.lu_read(TensorRead::from_view(TensorView::F64(input.as_view())))
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs.len(), 4);
§Errors

The default implementation returns Error::Unsupported because the backend does not accept tensor read targets; implementations may return validation or typed backend-source errors.

Source

fn full_piv_lu_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>>

Compute public full-pivoting LU outputs from a tensor read target.

Backends may canonicalize the input inside the same placement family, but must not silently transfer between CPU and GPU memory.

§Examples
use tenferro_linalg::LinalgBackend;
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_tensor::{TensorRead, TensorView, TypedTensor};

let input = TypedTensor::<f64>::from_vec_col_major(
    vec![2, 2],
    vec![1.0, 3.0, 2.0, 4.0],
)?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.full_piv_lu_read(TensorRead::from_view(TensorView::F64(input.as_view())))
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs.len(), 5);
§Errors

The default implementation returns Error::Unsupported because the backend does not accept tensor read targets; implementations may return validation or typed backend-source errors.

Source

fn eig_read(&mut self, _input: TensorRead<'_>) -> Result<Vec<Tensor>>

Compute general eigendecomposition outputs from a tensor read target.

Backends may canonicalize the input inside the same placement family, but must not silently transfer between CPU and GPU memory.

§Examples
use tenferro_linalg::LinalgBackend;
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_tensor::{TensorRead, TensorView, TypedTensor};

let input = TypedTensor::<f64>::from_vec_col_major(
    vec![2, 2],
    vec![2.0, 0.0, 0.0, 3.0],
)?;
let mut host = tenferro_cpu::CpuEngine::serial();
let outputs = {
    with_cpu_engine(&mut host, |backend| {
        backend.eig_read(TensorRead::from_view(TensorView::F64(input.as_view())))
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(outputs.len(), 2);
§Errors

The default implementation returns Error::Unsupported because the backend does not accept tensor read targets; implementations may return validation or typed backend-source errors.

Source

fn solve_read( &mut self, _a: TensorRead<'_>, _b: TensorRead<'_>, ) -> Result<Tensor>

Solve a linear system from tensor read targets.

Backends may canonicalize the inputs inside the same placement family, but must not silently transfer between CPU and GPU memory.

§Examples
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::LinalgBackend;
use tenferro_tensor::{Tensor, TensorRead};

let a = Tensor::from_vec_col_major(vec![2, 2], vec![2.0_f64, 0.0, 0.0, 3.0])?;
let b = Tensor::from_vec_col_major(vec![2, 1], vec![4.0_f64, 9.0])?;
let mut host = tenferro_cpu::CpuEngine::serial();
let x = {
    with_cpu_engine(&mut host, |backend| {
        backend.solve_read(
            TensorRead::from_tensor(&a),
            TensorRead::from_tensor(&b),
        )
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
let x = x.into_typed::<f64>().expect("F64 inputs return F64 output");
assert_eq!(x.host_data()?, &[2.0, 3.0]);

The CUDA provider does not inspect the cuSOLVER getrf status flag on the forward solve path, so it performs no per-call non-singularity check and issues no host round trip. An exactly singular input is left to the caller’s verification, as in torch.linalg.solve. CPU providers may still report their own exactly singular factor as Error::Singular.

§Errors

The default implementation returns Error::Unsupported because the backend does not accept tensor read targets. Implementations may return Error::Validation for incompatible shapes or dtypes, Error::RuntimeState for invalid placement, Error::Extension for a singular system, or a typed backend-source error.

Source

fn solve_read_into( &mut self, a: TensorRead<'_>, b: TensorRead<'_>, out: TensorWrite<'_>, ) -> Result<()>

Solve into a caller-owned destination.

The default preserves the ordinary read path and copies its result into out. Backends with a native destination path may override this method, but must validate the destination before the first write and preserve the same shape, dtype, placement, aliasing, and error contracts.

The CUDA provider does not inspect the cuSOLVER getrf status flag on the forward solve path, so it performs no per-call non-singularity check and issues no host round trip. An exactly singular input is left to the caller’s verification, as in torch.linalg.solve. CPU providers may still report their own exactly singular factor as Error::Singular.

§Errors

Returns tenferro_tensor_core::ShapeMismatch or tenferro_tensor_core::ValidationError::DTypeMismatch for incompatible destination metadata, tenferro_tensor_core::ValidationError::InvalidArgument for aliasing or placement violations, Error::Unsupported when the provider is unavailable, and Error::Singular for a singular system.

§Examples
use tenferro_cpu::{with_cpu_engine, CpuEngine};
use tenferro_linalg::LinalgBackend;
use tenferro_tensor::{Tensor, TensorRead, TensorWrite};

let a = Tensor::from_vec_col_major(vec![2, 2], vec![2.0_f64, 0.0, 0.0, 4.0])?;
let b = Tensor::from_vec_col_major(vec![2, 1], vec![4.0_f64, 8.0])?;
let mut out = Tensor::from_vec_col_major(vec![2, 1], vec![0.0_f64; 2])?;
let mut host = tenferro_cpu::CpuEngine::serial();
{
    with_cpu_engine(&mut host, |backend| {
        backend.solve_read_into(
            TensorRead::from_tensor(&a),
            TensorRead::from_tensor(&b),
            TensorWrite::from_tensor(&mut out),
        )
    })
    .expect("CpuEngine must expose a CpuEngine")
}?;
assert_eq!(out.as_slice::<f64>()?, &[2.0, 2.0]);

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl LinalgBackend for CpuEngine

Source§

fn cholesky(&mut self, input: &Tensor) -> Result<Tensor>

Source§

fn triangular_solve( &mut self, a: &Tensor, b: &Tensor, left_side: bool, lower: bool, transpose_a: bool, unit_diagonal: bool, ) -> Result<Tensor>

Source§

fn triangular_solve_read( &mut self, a: TensorRead<'_>, b: TensorRead<'_>, left_side: bool, lower: bool, transpose_a: bool, unit_diagonal: bool, ) -> Result<Tensor>

Source§

fn lu(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Source§

fn full_piv_lu(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Source§

fn full_piv_lu_solve( &mut self, a: &Tensor, b: &Tensor, transpose_a: bool, ) -> Result<Tensor>

Source§

fn svd(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Source§

fn svd_full(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Source§

fn svd_full_read(&mut self, input: TensorRead<'_>) -> Result<Vec<Tensor>>

Source§

fn svd_read(&mut self, input: TensorRead<'_>) -> Result<Vec<Tensor>>

Source§

fn qr(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Source§

fn qr_read(&mut self, input: TensorRead<'_>) -> Result<Vec<Tensor>>

Source§

fn eigh(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Source§

fn eigh_read(&mut self, input: TensorRead<'_>) -> Result<Vec<Tensor>>

Source§

fn cholesky_read(&mut self, input: TensorRead<'_>) -> Result<Tensor>

Source§

fn lu_read(&mut self, input: TensorRead<'_>) -> Result<Vec<Tensor>>

Source§

fn full_piv_lu_read(&mut self, input: TensorRead<'_>) -> Result<Vec<Tensor>>

Source§

fn eig_read(&mut self, input: TensorRead<'_>) -> Result<Vec<Tensor>>

Source§

fn eig(&mut self, input: &Tensor) -> Result<Vec<Tensor>>

Source§

fn solve(&mut self, a: &Tensor, b: &Tensor) -> Result<Tensor>

Source§

fn solve_read(&mut self, a: TensorRead<'_>, b: TensorRead<'_>) -> Result<Tensor>

Source§

fn solve_read_into( &mut self, a: TensorRead<'_>, b: TensorRead<'_>, out: TensorWrite<'_>, ) -> Result<()>

Implementors§