Skip to main content

Session

Struct Session 

Source
pub struct Session<'session> { /* private fields */ }
Expand description

One explicit concrete session over a caller-held CPU engine.

The session borrows an engine for the whole of its life. Inside CpuExecutionContext::with_concrete_session that is the context’s engine, borrowed for the closure; a caller that owns an engine (crate::CpuBackend) builds the same session with Session::new and keeps it across as many operations as it wants. Every route on it runs through that one engine, so a stage does not pay an entry per operation.

§Examples

use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?;
let b = Tensor::from_vec_col_major(vec![2, 2], vec![0.0_f64, 1.0, 1.0, 0.0])?;
let (ab, a_again) = context.with_concrete_session(
    |session| -> Result<_, Box<dyn std::error::Error + Send + Sync>> {
        let ab = session.contraction(&a, &[1], &b, &[0])?;
        // One session, two operations.
        let a_again = session.permute(&a, &[1, 0])?;
        Ok((ab, a_again))
    },
)??;
// `a` is `[[1, 3], [2, 4]]` column-major and `b` swaps the axes, so `a * b`
// is `[[3, 1], [4, 2]]`.
assert_eq!(ab.as_slice::<f64>()?, &[3.0, 4.0, 1.0, 2.0]);
assert_eq!(a_again.as_slice::<f64>()?, &[1.0, 3.0, 2.0, 4.0]);

Implementations§

Source§

impl<'session> Session<'session>

Source

pub fn new(engine: &'session mut dyn Engine) -> Self

Wrap a borrowed engine as this frontend’s session.

A caller that owns an engine - a crate::CpuBackend, an engine it built itself, or one borrowed for a stage - builds the same Session the callback-scoped CpuExecutionContext::with_concrete_session hands out, so a long stage can keep one session across many operations without entering a context. The engine stays borrowed for the whole life of the returned session: this constructor never enters, replaces or reroutes an engine.

§Examples
use tensor4all_tensorbackend::{explicit::Session, CpuBackend};
use tenferro::Tensor;

let mut backend = CpuBackend::with_threads(1)?;
let a = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?;

let mut session = Session::new(backend.engine_mut());
// One session, two operations.
let transposed = session.permute(&a, &[1, 0])?;
let total = session.sum(&transposed)?;
assert_eq!(total.as_slice::<f64>()?, &[10.0]);
Source

pub fn engine(&mut self) -> &mut dyn Engine

The engine behind this explicit session.

Exposed so a prepared plan can evaluate itself on the caller’s engine; it is not a second entry point, and it never consults another backend.

Source

pub fn reshape( &mut self, tensor: &NativeTensor, shape: &[usize], ) -> Result<NativeTensor>

Reshape a concrete tensor without changing its column-major linearization.

§Errors

Returns [tenferro_tensor::Error::Validation] when the element counts differ or the requested layout is invalid, [tenferro_tensor::Error::UnsupportedDType] for a dtype the backend cannot reshape, and [tenferro_tensor::Error::BackendSource] when the operation itself fails. It never retries on another route.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let x = Tensor::from_vec_col_major(vec![4], vec![1.0_f64, 2.0, 3.0, 4.0])?;
let reshaped = context.with_concrete_session(|session| session.reshape(&x, &[2, 2]))??;
assert_eq!(reshaped.as_slice::<f64>()?, &[1.0, 2.0, 3.0, 4.0]);
Source

pub fn permute( &mut self, tensor: &NativeTensor, perm: &[usize], ) -> Result<NativeTensor>

Permute the axes of a concrete tensor.

§Errors

Returns [tenferro_tensor::Error::Validation] when perm is not a permutation of the tensor’s axes, and [tenferro_tensor::Error::BackendSource] when the operation itself fails.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let x = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?;
let transposed = context.with_concrete_session(|session| session.permute(&x, &[1, 0]))??;
assert_eq!(transposed.as_slice::<f64>()?, &[1.0, 3.0, 2.0, 4.0]);
Source

pub fn contraction( &mut self, lhs: &NativeTensor, lhs_axes: &[usize], rhs: &NativeTensor, rhs_axes: &[usize], ) -> Result<NativeTensor>

Binary contraction along the given axes, preserving the remaining axes in order.

The operand identity and axis building is the same code path the compatibility frontend uses, so both frontends contract identically; only the session differs.

§Errors

Returns [tenferro_einsum::Error::InvalidSubscripts] when the axis lists are malformed or of different length, and [tenferro_einsum::Error::Tensor] when the backend rejects the operands, when an operand cannot be promoted, or when the contraction itself fails.

Operands are promoted to a common dtype exactly as the compatibility frontend promotes them: a heterogeneous set contracts in the promoted dtype, and a set that already shares one dtype is used as is.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?;
let b = Tensor::from_vec_col_major(vec![2, 1], vec![5.0_f64, 6.0])?;
let product =
    context.with_concrete_session(|session| session.contraction(&a, &[1], &b, &[0]))??;
assert_eq!(product.as_slice::<f64>()?, &[23.0, 34.0]);
Source

pub fn einsum( &mut self, operands: &[&NativeTensor], input_ids: &[&[usize]], output_ids: &[usize], ) -> Result<NativeTensor>

N-ary einsum from integer labels, evaluated on this session.

The labels are validated by the same helper the compatibility frontend uses; the evaluation is tenferro-einsum’s session-direct einsum, so it does not compile a semantic graph or start a runtime worker.

§Errors

Returns [tenferro_einsum::Error::InvalidSubscripts] for malformed labels, a label list whose length does not match the operand’s rank, or a label-list count that does not match the operand count, and [tenferro_einsum::Error::Tensor] when the backend rejects the operands, when an operand cannot be promoted, or when the contraction itself fails.

Operands are promoted to a common dtype exactly as the compatibility frontend promotes them: a heterogeneous set contracts in the promoted dtype, and a set that already shares one dtype is used as is.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?;
let b = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 0.0, 0.0, 1.0])?;
let product = context.with_concrete_session(|session| {
    session.einsum(&[&a, &b], &[&[0, 1], &[1, 2]], &[0, 2])
})??;
assert_eq!(product.as_slice::<f64>()?, &[1.0, 2.0, 3.0, 4.0]);
Source

pub fn sum(&mut self, tensor: &NativeTensor) -> Result<NativeTensor>

Sum every element of a concrete tensor, returning the rank-0 result.

The compatibility frontend wraps the same rank-0 tensor in a BackendScalar; this route stays on the concrete value so it works without the compatibility feature.

§Errors

Returns [tenferro_tensor::Error::Validation] for an unsupported reduction shape and [tenferro_tensor::Error::BackendSource] when the reduction itself fails.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let x = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?;
let total = context.with_concrete_session(|session| session.sum(&x))??;
assert_eq!(total.shape(), &[] as &[usize]);
assert_eq!(total.as_slice::<f64>()?, &[10.0]);
Source

pub fn conj(&mut self, tensor: &NativeTensor) -> Result<NativeTensor>

Conjugate a concrete tensor.

A real tensor is returned unchanged; a complex tensor is conjugated elementwise.

§Errors

Returns [tenferro_tensor::Error::Unsupported] for a dtype the backend cannot conjugate and [tenferro_tensor::Error::BackendSource] when the operation itself fails.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;
use num_complex::Complex64;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let x = Tensor::from_vec_col_major(
    vec![2],
    vec![Complex64::new(1.0, 2.0), Complex64::new(3.0, -4.0)],
)?;
let conjugated = context.with_concrete_session(|session| session.conj(&x))??;
assert_eq!(
    conjugated.as_slice::<Complex64>()?,
    &[Complex64::new(1.0, -2.0), Complex64::new(3.0, 4.0)]
);
Source

pub fn einsum_reads( &mut self, operands: &[TensorRead<'_>], input_ids: &[&[usize]], output_ids: &[usize], ) -> Result<NativeTensor>

N-ary einsum over borrowed read inputs, without materializing them.

Same contract as Session::einsum, except that the operands are TensorRead views: a non-contiguous or lazily represented operand stays borrowed until the contract evaluates it.

§Errors

Returns [tenferro_einsum::Error::InvalidSubscripts] for malformed labels or a label list whose length does not match the operand’s rank, and [tenferro_einsum::Error::Tensor] when the backend rejects the operands or the contraction itself fails.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;
use tenferro_tensor::TensorRead;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?;
let b = Tensor::from_vec_col_major(vec![2, 1], vec![5.0_f64, 6.0])?;
let reads = [TensorRead::from_tensor(&a), TensorRead::from_tensor(&b)];
let product = context
    .with_concrete_session(|session| session.einsum_reads(&reads, &[&[0, 1], &[1, 2]], &[0, 2]))??;
assert_eq!(product.as_slice::<f64>()?, &[23.0, 34.0]);
Source

pub fn contraction_into( &mut self, lhs: &NativeTensor, lhs_axes: &[usize], rhs: &NativeTensor, rhs_axes: &[usize], out: TensorWrite<'_>, ) -> Result<()>

Binary contraction into a caller-provided destination.

The destination is fully written and is never zero-filled first. The operands and the destination must already share one dtype: this route does not convert into a caller-owned output, and a mismatch is rejected typed by the backend.

§Errors

Returns [tenferro_einsum::Error::InvalidSubscripts] when the axis lists are malformed or of different length, and [tenferro_einsum::Error::Tensor] when the backend rejects the operands, the destination or the contraction.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;
use tenferro_tensor::TensorWrite;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?;
let b = Tensor::from_vec_col_major(vec![2, 1], vec![5.0_f64, 6.0])?;
let mut out = Tensor::from_vec_col_major(vec![2, 1], vec![0.0_f64, 0.0])?;
context.with_concrete_session(|session| {
    session.contraction_into(&a, &[1], &b, &[0], TensorWrite::Tensor(&mut out))
})??;
assert_eq!(out.as_slice::<f64>()?, &[23.0, 34.0]);
Source

pub fn solve_matrix<T>( &mut self, a: &Matrix<T>, b: &Matrix<T>, ) -> Result<Matrix<T>, BackendLinalgError>
where T: BackendLinalgScalar + Copy, NativeTensor: From<TypedTensor<T>>,

Solve A X = B for column-major matrices on this session.

Same kernel, conversion and validation as solve_matrix, entered through this session instead of the process-global one.

§Errors

Returns BackendLinalgError under the same conditions as solve_matrix.

§Examples
use tensor4all_tensorbackend::{CpuExecutionContext, Matrix};
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Matrix::from_col_major_vec(2, 2, vec![2.0_f64, 0.0, 0.0, 4.0]);
let b = Matrix::from_col_major_vec(2, 1, vec![6.0_f64, 8.0]);
let x = context.with_concrete_session(|session| session.solve_matrix(&a, &b))??;
assert_eq!(x.as_col_major_slice(), &[3.0, 2.0]);
Source

pub fn triangular_solve_matrix<T>( &mut self, a: &Matrix<T>, b: &Matrix<T>, left_side: bool, lower: bool, transpose_a: bool, unit_diagonal: bool, ) -> Result<Matrix<T>, BackendLinalgError>
where T: BackendLinalgScalar + Copy, NativeTensor: From<TypedTensor<T>>,

Solve a triangular system for column-major matrices on this session.

Same kernel, conversion and validation as triangular_solve_matrix, entered through this session instead of the process-global one. left_side, lower, transpose_a and unit_diagonal have the same meaning as on that entry.

§Errors

Returns BackendLinalgError under the same conditions as triangular_solve_matrix.

§Examples
use tensor4all_tensorbackend::{CpuExecutionContext, Matrix};
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Matrix::from_col_major_vec(2, 2, vec![2.0_f64, 1.0, 0.0, 4.0]);
let b = Matrix::from_col_major_vec(2, 1, vec![4.0_f64, 4.0]);
let x = context.with_concrete_session(|session| {
    session.triangular_solve_matrix(&a, &b, true, true, false, false)
})??;
assert_eq!(x.as_col_major_slice(), &[2.0, 0.5]);
Source

pub fn full_piv_lu_matrix<T>( &mut self, a: &Matrix<T>, ) -> Result<FullPivLuMatrixResult<T>, BackendLinalgError>

Complete-pivoting LU decomposition of a column-major matrix on this session.

Same kernel and conversion as full_piv_lu_matrix, entered through this session instead of the process-global one.

§Errors

Returns BackendLinalgError under the same conditions as full_piv_lu_matrix.

§Examples
use tensor4all_tensorbackend::{CpuExecutionContext, Matrix};
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Matrix::from_col_major_vec(2, 2, vec![0.0_f64, 1.0, 2.0, 3.0]);
let factors = context.with_concrete_session(|session| session.full_piv_lu_matrix(&a))??;
assert_eq!(factors.p.nrows(), 2);
assert_eq!(factors.q.ncols(), 2);
Source

pub fn qr_backend<T>( &mut self, a: TypedTensor<T>, ) -> Result<(TypedTensor<T>, TypedTensor<T>), BackendLinalgError>

Thin/economy QR of a typed tensor on this session.

Same kernel and conversion as qr_backend, entered through this session instead of the process-global one.

§Errors

Returns BackendLinalgError under the same conditions as qr_backend.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::TypedTensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = TypedTensor::<f64>::from_vec_col_major(vec![2, 2], vec![1.0, 2.0, 3.0, 4.0])?;
let (q, r) = context.with_concrete_session(|session| session.qr_backend(a))??;
assert_eq!(q.shape(), &[2, 2]);
assert_eq!(r.shape(), &[2, 2]);
Source

pub fn svd_backend<T>( &mut self, a: &TypedTensor<T>, ) -> Result<SvdResult<T>, BackendLinalgError>

Thin/economy SVD of a typed tensor on this session.

Same kernel and conversion as svd_backend, entered through this session instead of the process-global one.

§Errors

Returns BackendLinalgError under the same conditions as svd_backend.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::TypedTensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = TypedTensor::<f64>::from_vec_col_major(vec![2, 2], vec![3.0, 0.0, 0.0, 2.0])?;
let factors = context.with_concrete_session(|session| session.svd_backend(&a))??;
assert_eq!(factors.s().as_slice()?, &[3.0, 2.0]);
Source

pub fn mat_mul<T: BlasMul>( &mut self, a: &Matrix<T>, b: &Matrix<T>, ) -> Result<Matrix<T>, MatrixMulError>

Matrix multiplication A * B on this session.

The same kernel and shape validation as mat_mul, entered through this session instead of the process-global one, and returning the shared Matrix container.

§Errors

Returns MatrixMulError when the shapes disagree or the session operation fails.

§Examples
use tensor4all_tensorbackend::{CpuExecutionContext, Matrix};
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Matrix::from_col_major_vec(2, 2, vec![1.0_f64, 2.0, 3.0, 4.0]);
let b = Matrix::from_col_major_vec(2, 2, vec![1.0_f64, 0.0, 0.0, 1.0]);
let c = context.with_concrete_session(|session| session.mat_mul(&a, &b))??;
assert_eq!(c.as_col_major_slice(), &[1.0, 2.0, 3.0, 4.0]);
Source

pub fn qr( &mut self, tensor: &NativeTensor, ) -> Result<(NativeTensor, NativeTensor)>

Thin/economy QR decomposition.

§Errors

Returns [tenferro_tensor::Error::Validation] for an unsupported dtype or rank, and [tenferro_tensor::Error::BackendSource] when the factorization itself fails.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?;
let (q, r) = context.with_concrete_session(|session| session.qr(&a))??;
// `A = Q R` is reproduced to rounding, which is the correctness property
// of a factorization.
let reconstructed =
    context.with_concrete_session(|session| session.contraction(&q, &[1], &r, &[0]))??;
for (got, want) in reconstructed.as_slice::<f64>()?.iter().zip([1.0, 2.0, 3.0, 4.0]) {
    assert!((got - want).abs() < 1e-12, "got {got}, want {want}");
}
Source

pub fn svd( &mut self, tensor: &NativeTensor, ) -> Result<(NativeTensor, NativeTensor, NativeTensor)>

Thin/economy SVD.

§Errors

Returns [tenferro_tensor::Error::Validation] for an unsupported dtype or rank, and [tenferro_tensor::Error::BackendSource] when the factorization itself fails.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Tensor::from_vec_col_major(vec![2, 2], vec![3.0_f64, 0.0, 0.0, 2.0])?;
let (u, s, vt) = context.with_concrete_session(|session| session.svd(&a))??;
// The singular values of diag(3, 2) are 3 and 2.
assert_eq!(s.as_slice::<f64>()?, &[3.0, 2.0]);
assert_eq!(u.shape(), &[2, 2]);
assert_eq!(vt.shape(), &[2, 2]);
Source

pub fn solve( &mut self, lhs: &NativeTensor, rhs: &NativeTensor, ) -> Result<NativeTensor>

Solve A X = B for a square A.

§Errors

Returns [tenferro_tensor::Error::Validation] when lhs is not square, when the operands have mismatched shapes, or for an unsupported dtype, and [tenferro_tensor::Error::BackendSource] when the solve itself fails.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
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![6.0_f64, 8.0])?;
let x = context.with_concrete_session(|session| session.solve(&a, &b))??;
assert_eq!(x.as_slice::<f64>()?, &[3.0, 2.0]);
Source

pub fn triangular_solve( &mut self, lhs: &NativeTensor, rhs: &NativeTensor, left_side: bool, lower: bool, transpose_a: bool, unit_diagonal: bool, ) -> Result<NativeTensor>

Solve A X = B where A is triangular.

  • left_side: solve A X = B when true, X A = B when false;
  • lower: A is lower triangular;
  • transpose_a: solve with A transposed;
  • unit_diagonal: treat the diagonal of A as one, ignoring the stored values.
§Errors

Returns [tenferro_tensor::Error::Validation] for a shape mismatch or an unsupported dtype, and [tenferro_tensor::Error::BackendSource] when the solve itself fails.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
// Lower triangular, column-major.
let a = Tensor::from_vec_col_major(vec![2, 2], vec![2.0_f64, 1.0, 0.0, 4.0])?;
let b = Tensor::from_vec_col_major(vec![2, 1], vec![4.0_f64, 4.0])?;
let x = context.with_concrete_session(|session| {
    session.triangular_solve(&a, &b, true, true, false, false)
})??;
assert_eq!(x.as_slice::<f64>()?, &[2.0, 0.5]);
Source

pub fn full_piv_lu( &mut self, tensor: &NativeTensor, ) -> Result<(NativeTensor, NativeTensor, NativeTensor, NativeTensor, NativeTensor)>

Full-pivoting LU decomposition P A Q = L U, returning (P, L, U, Q, parity).

§Errors

Returns [tenferro_tensor::Error::Validation] for a non-square A or an unsupported dtype, and [tenferro_tensor::Error::BackendSource] when the factorization itself fails.

§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::Tensor;
use tensor4all_tensorbackend::CpuBackend;

let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let a = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?;
let (p, l, u, q, _parity) = context
    .with_concrete_session(|session| session.full_piv_lu(&a))?
    .expect("full-pivoting LU");
for factor in [&p, &l, &u, &q] {
    assert_eq!(factor.shape(), &[2, 2]);
}
// Column-major, so index 0 is (0, 0), index 1 is (1, 0) and index 2 is (0, 1).
let l = l.as_slice::<f64>()?;
let u = u.as_slice::<f64>()?;
assert_eq!(l[2], 0.0, "L is lower triangular");
assert_eq!(u[1], 0.0, "U is upper triangular");

Trait Implementations§

Source§

impl Debug for Session<'_>

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'session> !RefUnwindSafe for Session<'session>

§

impl<'session> !Send for Session<'session>

§

impl<'session> !Sync for Session<'session>

§

impl<'session> !UnwindSafe for Session<'session>

§

impl<'session> Freeze for Session<'session>

§

impl<'session> Unpin for Session<'session>

§

impl<'session> UnsafeUnpin for Session<'session>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> ByRef<T> for T

§

fn by_ref(&self) -> &T

§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

§

fn simd_from(_simd: S, value: T) -> T

§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

§

fn simd_into(self, simd: S) -> T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V