Skip to main content

tensor4all_tensorbackend/
lib.rs

1#![warn(missing_docs)]
2//! Tensor storage and linear algebra backend for tensor4all.
3//!
4//! [`CpuExecutionContext`] is the canonical CPU integration path. It requires a
5//! caller-supplied backend and owns plain, graph, and eager-AD runtime state.
6//!
7//! ## Feature flags
8//!
9//! - `explicit-context`: explicit CPU execution and logical tensor transfer.
10//! - `global-defaults`: legacy process-global tensor operations.
11//! - `backend-tenferro` (default): compatibility alias for `global-defaults`.
12
13#[cfg(feature = "global-defaults")]
14/// Dynamic scalar types supporting f32, f64, Complex32, and Complex64.
15mod any_scalar;
16#[cfg(feature = "global-defaults")]
17/// Backend dispatch for dense linear algebra operations.
18mod backend;
19#[cfg(feature = "explicit-context")]
20/// Explicit and optional process-global tenferro execution helpers.
21mod context;
22#[cfg(feature = "tenferro-cuda")]
23/// Explicit visible-ordinal-0 CUDA execution and transfer boundaries.
24mod cuda;
25#[cfg(feature = "global-defaults")]
26/// Incremental QR state for successive randomized compression.
27mod incremental_qr;
28#[cfg(feature = "explicit-context")]
29/// Backend-free tensor snapshots for execution-domain transfer.
30mod logical_tensor;
31#[cfg(feature = "global-defaults")]
32/// Dense column-major matrix type and backend-backed matrix utilities.
33mod matrix;
34#[cfg(feature = "global-defaults")]
35/// Process-level memory pressure helpers.
36mod memory;
37#[cfg(feature = "global-defaults")]
38/// Tensor snapshot storage types and low-level dense/diagonal kernels.
39mod storage;
40#[cfg(feature = "global-defaults")]
41pub(crate) mod tenferro_bridge;
42#[cfg(feature = "global-defaults")]
43/// Supported public tensor element types and native constructor hooks.
44mod tensor_element;
45
46#[cfg(feature = "global-defaults")]
47pub use any_scalar::BackendScalar;
48#[cfg(feature = "global-defaults")]
49pub use backend::{
50    full_piv_lu_backend, full_piv_lu_matrix, full_piv_lu_matrix_owned, qr_backend, solve_backend,
51    solve_matrix, solve_matrix_owned, src_error_estimate, src_error_estimate_general, svd_backend,
52    triangular_solve_backend, triangular_solve_matrix, triangular_solve_matrix_owned,
53    BackendLinalgError, BackendLinalgScalar, FullPivLuMatrixResult, FullPivLuResult,
54    FullPivLuScalar, MatrixSolveScalar, MatrixTriangularSolveScalar, SrcErrorEstimate, SvdResult,
55};
56#[cfg(feature = "global-defaults")]
57pub use context::{
58    default_cpu_execution_context, default_eager_ctx, with_default_backend, EagerContextError,
59};
60#[cfg(feature = "explicit-context")]
61pub use context::{CpuExecutionContext, CpuExecutionContextError, ExecutionContext};
62#[cfg(feature = "tenferro-cuda")]
63pub use cuda::{CudaExecutionContext, CudaExecutionContextError, CUDA_ORDINAL};
64#[cfg(feature = "global-defaults")]
65pub use incremental_qr::{IncrementalQr, IncrementalQrScalar};
66#[cfg(feature = "explicit-context")]
67pub use logical_tensor::{LogicalTensor, LogicalTensorData, LogicalTensorError};
68#[cfg(feature = "global-defaults")]
69pub use matrix::{
70    batched_mat_mul_same_shape, batched_mat_mul_same_shape_owned, from_vec2d,
71    grouped_mat_mul_shared, grouped_mat_mul_shared_owned, grouped_mat_mul_shared_with_backend,
72    hermitian_eigendecomposition, hermitian_exponential_first_column, lowest_hermitian_eigenpair,
73    mat_mul, mat_mul_owned, submatrix, submatrix_argmax, swap_cols, swap_rows, transpose,
74    try_from_vec2d, BlasMul, GroupedGemmError, GroupedGemmJob, GroupedGemmOptions,
75    HermitianEigenError, HermitianEigenScalar, HermitianEigendecomposition, HermitianEigenpair,
76    Matrix, MatrixScalar, MatrixShapeError, MatrixTensorConversionError,
77};
78#[cfg(feature = "global-defaults")]
79pub use memory::{release_process_allocator_cached_memory, AllocatorPressureRelief};
80#[cfg(feature = "global-defaults")]
81pub use storage::{
82    contract_storage, make_mut_storage, min_dim, Storage, StorageError, StorageKind, StorageResult,
83    StorageScalar, StructuredStorage, SumFromStorage,
84};
85#[cfg(feature = "global-defaults")]
86pub use tenferro_bridge::{
87    axpby_native_tensor, axpby_storage_native, conj_native_tensor, contract_native_tensor,
88    contract_storage_native, dense_native_tensor_from_col_major,
89    dense_native_tensor_from_col_major_owned, diag_native_tensor_from_col_major,
90    einsum_native_tensor_reads, einsum_native_tensors, einsum_native_tensors_owned,
91    native_tensor_primal_to_dense_col_major, native_tensor_primal_to_diag,
92    native_tensor_primal_to_storage, outer_product_native_tensor, outer_product_storage_native,
93    permute_native_tensor, permute_storage_native, print_and_reset_native_einsum_profile,
94    qr_native_tensor, reset_native_einsum_profile, reshape_col_major_native_tensor,
95    scale_native_tensor, scale_storage_native, storage_payload_native_read_input,
96    storage_to_native_tensor, sum_native_tensor, svd_native_tensor, tangent_native_tensor,
97    BridgeError, NativeTensorReadInput,
98};
99#[cfg(feature = "global-defaults")]
100pub use tensor_element::TensorElement;
101
102/// Extract a result whose error branch means validated internal state is inconsistent.
103#[cfg(feature = "global-defaults")]
104pub(crate) fn require_invariant<T, E: std::fmt::Display>(
105    result: std::result::Result<T, E>,
106    context: &str,
107) -> T {
108    let valid = result.is_ok();
109    if let Err(error) = &result {
110        assert!(valid, "{context}: {error}");
111    }
112    match result {
113        Ok(value) => value,
114        Err(_) => loop {
115            std::hint::spin_loop();
116        },
117    }
118}
119
120#[cfg(all(test, feature = "global-defaults"))]
121mod invariant_tests {
122    use super::require_invariant;
123
124    #[test]
125    fn require_invariant_returns_success_and_reports_failure_context() {
126        assert_eq!(require_invariant::<_, &str>(Ok(7), "valid state"), 7);
127
128        let failure = std::panic::catch_unwind(|| {
129            require_invariant::<(), _>(Err("broken state"), "tensor invariant")
130        });
131        let message = failure
132            .unwrap_err()
133            .downcast::<String>()
134            .map(|message| *message)
135            .unwrap_or_default();
136        assert!(message.contains("tensor invariant: broken state"));
137    }
138}