Skip to main content

tenferro_runtime/
lib.rs

1//! Traced graph runtime and extension dispatch infrastructure for tenferro.
2//!
3//! This crate owns graph construction, lowering to execution IR, graph
4//! execution, and backend-parametric extension runtime dispatch. Standard
5//! operations are lowered through the runtime's internal operation vocabulary;
6//! tensor storage and backend kernels live in `tenferro-tensor`.
7//!
8//! Use this crate directly when you want concrete tensor helpers or reusable
9//! traced graph execution without depending on `tenferro-ad`. Start with
10//! [`TypedTensor`] when the scalar type is fixed in Rust, [`Tensor`] when dtype
11//! is selected at runtime, and [`TracedTensor`] plus [`GraphCompiler`] and
12//! [`Runtime`] when the same expression should be compiled once and run
13//! repeatedly. Operation-family crates such as `tenferro-einsum`,
14//! `tenferro-linalg`, and `tenferro-fft` register extension runtimes through
15//! runtime engine registrations when compiled execution reaches those
16//! operations.
17//!
18//! User-facing guides live at
19//! <https://tensor4all.org/tenferro-rs/guides/choosing-an-api.html> and
20//! <https://tensor4all.org/tenferro-rs/guides/execution-models.html>.
21//!
22//! # Examples
23//!
24//! ```rust
25//! use tenferro_runtime::{GraphCompiler, Runtime, TracedTensor};
26//! use tenferro_cpu::CpuBackend;
27//!
28//! let x = TracedTensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap();
29//! let y = (&x + &x).unwrap();
30//! let mut compiler = GraphCompiler::new();
31//! let program = compiler.compile(&y).unwrap();
32//! let backend = CpuBackend::default();
33//! let mut builder = Runtime::builder();
34//! builder.register_engine(tenferro_cpu::runtime_engine_registration(&backend).unwrap()).unwrap();
35//! let runtime = builder.build().unwrap();
36//! let out = runtime.run_compiled(&program, &[]).unwrap().pop().unwrap();
37//! assert_eq!(out.as_slice::<f64>().unwrap(), &[2.0, 4.0]);
38//! ```
39
40#[doc(hidden)]
41pub mod ad_support;
42mod checkpoint;
43mod compiler;
44pub mod error;
45mod exec;
46pub mod extension;
47pub mod extension_cache;
48mod extension_execution_context;
49pub mod graph;
50mod metadata;
51pub mod prelude;
52pub mod program;
53pub mod runtime;
54#[doc(hidden)]
55pub mod scalar_semantics;
56mod segment;
57mod shape_constraint;
58mod shape_infer;
59mod shape_packing;
60pub mod sym_dim;
61mod tensor;
62mod trace;
63pub mod traced;
64mod typed_tensor;
65
66pub use compiler::{CompilerOptions, OptimizerConfig};
67pub use error::{ContextId, Error, ErrorPhase, Result, ShapeConstraintEvalError};
68pub use extension_cache::{
69    ExtensionCacheKey, ExtensionCacheLimits, ExtensionCacheSelector, ExtensionCacheStore,
70};
71pub use extension_execution_context::ExtensionExecutionContext;
72pub use graph::{CompiledGraph, GraphCompiler};
73pub use runtime::{
74    assemble_executable_engine_registration, assemble_preparation_only_engine_registration,
75    CacheInFlightBehavior, CacheOwnerError, CacheOwnerFailure, CacheOwnerId, CoreCapabilityBundle,
76    CoreCapabilityBundleBuilder, CoreCapabilityKind, CorePrepareContext, Determinism,
77    DotGeneralPreparation, DotGeneralPrepareRequest, ElementwisePrepareRequest, ElementwiseRuntime,
78    EngineExecutionContractError, EngineId, EngineRegistration, EngineRegistrationMetadata,
79    EngineSnapshotView, ErasedExecutionContext, EventDomainDriver, EventDomainError, EventDomainId,
80    EventDomainOperation, EventDomainRun, EventToken, ExecutableEngineRegistrationConfig,
81    ExecutionBundle, ExecutionContextIdentity, ExecutionContextMismatch, ExecutionHandle,
82    ExecutionInputs, ExecutionOutcome, ExecutionPolicy, ExecutionPolicyError, ExtensionEngine,
83    ExtensionModule, ExtensionModuleError, ExtensionModuleId, ExtensionModuleRegistrar,
84    ExtensionPlanningConfig, ExtensionPrepareRequest, HardwareClassId, IdentityError, IdentityKind,
85    ImmediateEventDomainDriver, IndexingPrepareRequest, IndexingRuntime, InputIngressContract,
86    InputIngressContractError, InputPlacementContract, InputSignature, InputSignatureContract,
87    InputSignatureEntry, InputSignatureError, InputSpecializationProjection,
88    InputSpecializationRequirements, InputSpecializationRequirementsBuilder,
89    InputSpecializationRequirementsError, LayoutClass, LayoutPrepareRequest, LayoutProjection,
90    LayoutRuntime, LayoutSpecialization, OutputAccessError, OutputExtractError, OutputMetadata,
91    OutputRef, PlacementConstraintError, PlacementProjection, PlacementSpecialization,
92    PreparationKeySummary, PreparationOnlyEngineRegistrationConfig, PrepareCapability,
93    PrepareError, PrepareOptions, PrepareOptionsKey, PreparedCompiledGraph, PreparedOperation,
94    PreparedOperationBinding, PreparedOperationExecutor, PreparedOperationExecutorHandle,
95    PreparedOperationHandle, PreparedOperationPlan, PreparedPlanCacheLimits,
96    PreparedPlanCacheStats, ProgramPlacementConstraint, ProviderContractError,
97    ProviderDeviceIdentity, ProviderId, RankRequirement, ReductionPrepareRequest, ReductionRuntime,
98    RegistrationIdentity, RegistrationKey, ResidentOutputContract, ResolvedPlanningConfig,
99    ResolvedPlanningKey, ResolvedProgramPlacement, Runtime, RuntimeCacheError, RuntimeCacheOwner,
100    RuntimeCacheStats, RuntimeConfigBuilder, RuntimeConfigError, RuntimeConfigSnapshot,
101    RuntimeEpoch, RuntimeId, RuntimeInputContract, RuntimeReconfiguration, RuntimeReconfigureError,
102    RuntimeStateError, ScopedExecutionBundle, ScopedExecutionOutcome, ScopedOutput,
103    ScopedOutputExtractError, ScopedReadBinding, ScopedReadInputs, ScopedSubmitRejected,
104    SpecializationError, SpecializationProjection, SpecializationRequirements, StorageClass,
105    SubmissionError, SubmitError, TransferEndpoint, TransferError, TransferProvider,
106    TransferProviderContractError, TransferRequest, UnsupportedReason,
107};
108#[doc(hidden)]
109pub use shape_constraint::ShapeGuard;
110pub use shape_packing::TracedSliceBuilder;
111pub use sym_dim::SymDim;
112pub use tenferro_ops::ShapeRelation;
113pub use tenferro_tensor::{
114    BackendSessionHost, CacheStats, CompareDir, DType, DotGeneralConfig, GatherConfig, MemoryKind,
115    PadConfig, ScatterConfig, SliceConfig, Tensor, TensorBackend, TensorRead, TensorScalar,
116    TensorValue, TensorView, TypedTensor, TypedTensorView,
117};
118pub use trace::{TraceContext, TraceValue, TracedGraph};
119
120/// Backend-explicit concrete tensor operations.
121///
122/// `Tensor` is owned by `tenferro-tensor`, so `tenferro-runtime` exposes these
123/// operations as a crate-root extension trait rather than as inherent methods.
124///
125/// # Public API rationale
126///
127/// This trait is intentionally public: it is the supported non-AD concrete
128/// tensor operation surface for downstream users who want to run operations on
129/// an explicit backend. The old public module/free-function surface was
130/// removed; the private `tensor` module now contains implementation helpers
131/// only and must not be treated as a compatibility API.
132///
133/// # Examples
134///
135/// ```rust
136/// use tenferro_cpu::CpuBackend;
137/// use tenferro_runtime::{Tensor, TensorOpsExt};
138///
139/// let mut backend = CpuBackend::new();
140/// let a = Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64; 4]).unwrap();
141/// let b = Tensor::from_vec_col_major(vec![2, 2], vec![2.0_f64; 4]).unwrap();
142/// let c = a.matmul(&b, &mut backend).unwrap();
143/// assert_eq!(c.shape(), &[2, 2]);
144/// ```
145pub trait TensorOpsExt {
146    /// Convert to a different dtype using the checked conversion lattice.
147    ///
148    /// # Errors
149    ///
150    /// Returns [`tenferro_tensor::Error::UnsupportedDTypeConversion`] when the
151    /// conversion is outside the checked lattice,
152    /// [`tenferro_tensor::Error::Validation`] with `DTypeMismatch` or
153    /// `InvalidArgument` for invalid tensor metadata, or
154    /// [`tenferro_tensor::Error::BackendSource`] when the backend reports a
155    /// typed failure.
156    fn convert<B: TensorBackend>(
157        &self,
158        to: DType,
159        backend: &mut B,
160    ) -> tenferro_tensor::Result<Tensor>;
161    /// Cast to a different dtype using explicit lossy projection.
162    ///
163    /// # Errors
164    ///
165    /// Returns [`tenferro_tensor::Error::UnsupportedDTypeConversion`] when the
166    /// requested cast is unsupported, [`tenferro_tensor::Error::Validation`]
167    /// with `DTypeMismatch` or `InvalidArgument` for invalid tensor metadata,
168    /// or [`tenferro_tensor::Error::BackendSource`] for a typed backend
169    /// failure.
170    fn cast<B: TensorBackend>(&self, to: DType, backend: &mut B)
171        -> tenferro_tensor::Result<Tensor>;
172    /// Elementwise addition with NumPy-style broadcasting.
173    ///
174    /// # Errors
175    ///
176    /// Returns [`tenferro_tensor::Error::Validation`] with a
177    /// [`ShapeMismatch`](tenferro_tensor::ValidationError::ShapeMismatch) or
178    /// `DTypeMismatch` payload when operands are incompatible, or
179    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
180    fn add<B: TensorBackend>(
181        &self,
182        rhs: &Tensor,
183        backend: &mut B,
184    ) -> tenferro_tensor::Result<Tensor>;
185    /// Elementwise subtraction with NumPy-style broadcasting.
186    ///
187    /// # Errors
188    ///
189    /// Returns [`tenferro_tensor::Error::Validation`] with
190    /// `ShapeMismatch` or `DTypeMismatch` for incompatible operands, or
191    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
192    fn sub<B: TensorBackend>(
193        &self,
194        rhs: &Tensor,
195        backend: &mut B,
196    ) -> tenferro_tensor::Result<Tensor>;
197    /// Elementwise multiplication with NumPy-style broadcasting.
198    ///
199    /// # Errors
200    ///
201    /// Returns [`tenferro_tensor::Error::Validation`] with
202    /// `ShapeMismatch` or `DTypeMismatch` for incompatible operands, or
203    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
204    fn mul<B: TensorBackend>(
205        &self,
206        rhs: &Tensor,
207        backend: &mut B,
208    ) -> tenferro_tensor::Result<Tensor>;
209    /// Elementwise division with NumPy-style broadcasting.
210    ///
211    /// # Errors
212    ///
213    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` or
214    /// `DTypeMismatch` for shape/dtype incompatibility,
215    /// [`tenferro_tensor::Error::Extension`] with a numerical classification
216    /// for a detected zero divisor, or
217    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
218    fn div<B: TensorBackend>(
219        &self,
220        rhs: &Tensor,
221        backend: &mut B,
222    ) -> tenferro_tensor::Result<Tensor>;
223    /// Elementwise remainder with NumPy-style broadcasting.
224    ///
225    /// # Errors
226    ///
227    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` or
228    /// `DTypeMismatch` for shape/dtype incompatibility, a numerical
229    /// [`tenferro_tensor::Error::Extension`] for a detected zero divisor, or
230    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
231    fn rem<B: TensorBackend>(
232        &self,
233        rhs: &Tensor,
234        backend: &mut B,
235    ) -> tenferro_tensor::Result<Tensor>;
236    /// Elementwise power with NumPy-style broadcasting.
237    ///
238    /// # Errors
239    ///
240    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` or
241    /// `DTypeMismatch` for incompatible metadata, a numerical
242    /// [`tenferro_tensor::Error::Extension`] for a detected negative integer
243    /// exponent, or [`tenferro_tensor::Error::BackendSource`] for a typed
244    /// backend failure.
245    fn pow<B: TensorBackend>(
246        &self,
247        rhs: &Tensor,
248        backend: &mut B,
249    ) -> tenferro_tensor::Result<Tensor>;
250    /// Elementwise maximum with NumPy-style broadcasting.
251    ///
252    /// # Errors
253    ///
254    /// Returns [`tenferro_tensor::Error::Validation`] with
255    /// `ShapeMismatch` or `DTypeMismatch` for incompatible operands, or
256    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
257    fn maximum<B: TensorBackend>(
258        &self,
259        rhs: &Tensor,
260        backend: &mut B,
261    ) -> tenferro_tensor::Result<Tensor>;
262    /// Elementwise minimum with NumPy-style broadcasting.
263    ///
264    /// # Errors
265    ///
266    /// Returns [`tenferro_tensor::Error::Validation`] with
267    /// `ShapeMismatch` or `DTypeMismatch` for incompatible operands, or
268    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
269    fn minimum<B: TensorBackend>(
270        &self,
271        rhs: &Tensor,
272        backend: &mut B,
273    ) -> tenferro_tensor::Result<Tensor>;
274    /// Elementwise negation.
275    ///
276    /// # Errors
277    ///
278    /// Returns [`tenferro_tensor::Error::Unsupported`] when the dtype is not
279    /// supported by the operation, or [`tenferro_tensor::Error::BackendSource`]
280    /// for a typed backend failure.
281    fn neg<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
282    /// Elementwise absolute value.
283    ///
284    /// # Errors
285    ///
286    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
287    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
288    /// failure.
289    fn abs<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
290    /// Elementwise sign.
291    ///
292    /// # Errors
293    ///
294    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
295    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
296    /// failure.
297    fn sign<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
298    /// Elementwise complex conjugate.
299    ///
300    /// # Errors
301    ///
302    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
303    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
304    /// failure.
305    fn conj<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
306    /// Elementwise exponential.
307    ///
308    /// # Errors
309    ///
310    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
311    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
312    /// failure.
313    fn exp<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
314    /// Elementwise natural logarithm.
315    ///
316    /// # Errors
317    ///
318    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
319    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
320    /// failure.
321    fn log<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
322    /// Elementwise sine.
323    ///
324    /// # Errors
325    ///
326    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
327    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
328    /// failure.
329    fn sin<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
330    /// Elementwise cosine.
331    ///
332    /// # Errors
333    ///
334    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
335    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
336    /// failure.
337    fn cos<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
338    /// Elementwise hyperbolic tangent.
339    ///
340    /// # Errors
341    ///
342    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
343    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
344    /// failure.
345    fn tanh<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
346    /// Elementwise square root.
347    ///
348    /// # Errors
349    ///
350    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
351    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
352    /// failure.
353    fn sqrt<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
354    /// Elementwise reciprocal square root.
355    ///
356    /// # Errors
357    ///
358    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
359    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
360    /// failure.
361    fn rsqrt<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
362    /// Elementwise `exp(x) - 1`.
363    ///
364    /// # Errors
365    ///
366    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
367    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
368    /// failure.
369    fn expm1<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
370    /// Elementwise `log(1 + x)`.
371    ///
372    /// # Errors
373    ///
374    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
375    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
376    /// failure.
377    fn log1p<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<Tensor>;
378    /// Elementwise comparison with NumPy-style broadcasting.
379    ///
380    /// # Errors
381    ///
382    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` or
383    /// `DTypeMismatch` for incompatible shape/dtype metadata, or
384    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
385    fn compare<B: TensorBackend>(
386        &self,
387        rhs: &Tensor,
388        dir: CompareDir,
389        backend: &mut B,
390    ) -> tenferro_tensor::Result<Tensor>;
391    /// Select values from `on_true` or `on_false` using this tensor as condition.
392    ///
393    /// # Errors
394    ///
395    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` or
396    /// `DTypeMismatch` when the condition and branches are incompatible, or
397    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
398    fn where_select<B: TensorBackend>(
399        &self,
400        on_true: &Tensor,
401        on_false: &Tensor,
402        backend: &mut B,
403    ) -> tenferro_tensor::Result<Tensor>;
404    /// Clamp values elementwise between lower and upper bounds.
405    ///
406    /// # Errors
407    ///
408    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` or
409    /// `DTypeMismatch` when bounds are incompatible with the input, or
410    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
411    fn clamp<B: TensorBackend>(
412        &self,
413        lower: &Tensor,
414        upper: &Tensor,
415        backend: &mut B,
416    ) -> tenferro_tensor::Result<Tensor>;
417    /// Rank-2 matrix multiplication.
418    ///
419    /// # Errors
420    ///
421    /// Returns [`tenferro_tensor::Error::Validation`] with `RankMismatch`,
422    /// `ShapeMismatch`, or `DTypeMismatch` for incompatible matrices, or
423    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
424    fn matmul<B: TensorBackend>(
425        &self,
426        rhs: &Tensor,
427        backend: &mut B,
428    ) -> tenferro_tensor::Result<Tensor>;
429    /// Reshape without changing element order.
430    ///
431    /// # Errors
432    ///
433    /// Returns [`tenferro_tensor::Error::Validation`] with
434    /// `ShapeMismatch`, `RankMismatch`, or `InvalidArgument` when element
435    /// counts or ranks are invalid, or
436    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
437    fn reshape<B: TensorBackend>(
438        &self,
439        shape: &[usize],
440        backend: &mut B,
441    ) -> tenferro_tensor::Result<Tensor>;
442    /// Permute axes.
443    ///
444    /// # Errors
445    ///
446    /// Returns [`tenferro_tensor::Error::Validation`] with
447    /// `InvalidPermutationLength`, `AxisOutOfBounds`, or `DuplicateAxis` for
448    /// an invalid permutation, or
449    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
450    fn transpose<B: TensorBackend>(
451        &self,
452        perm: &[usize],
453        backend: &mut B,
454    ) -> tenferro_tensor::Result<Tensor>;
455    /// Sum over one or more axes.
456    ///
457    /// # Errors
458    ///
459    /// Returns [`tenferro_tensor::Error::Validation`] with `AxisOutOfBounds`
460    /// or `DuplicateAxis` for invalid reductions, or
461    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
462    fn reduce_sum<B: TensorBackend>(
463        &self,
464        axes: &[usize],
465        backend: &mut B,
466    ) -> tenferro_tensor::Result<Tensor>;
467}
468
469/// Backend-explicit operations for dynamic-rank typed tensors.
470///
471/// `TypedTensor` is owned by `tenferro-tensor`, so `tenferro-runtime` exposes
472/// these operations as a crate-root extension trait rather than as inherent
473/// methods.
474///
475/// # Public API rationale
476///
477/// This trait is intentionally public for the same reason as [`TensorOpsExt`]:
478/// downstream users need a supported backend-explicit typed tensor surface, and
479/// `tenferro-runtime` cannot add inherent methods to a type owned by
480/// `tenferro-tensor`. The private `typed_tensor` module is implementation
481/// detail, not a retained module/free-function API.
482///
483/// # Examples
484///
485/// ```rust
486/// use tenferro_cpu::CpuBackend;
487/// use tenferro_runtime::{TypedTensor, TypedTensorOpsExt};
488///
489/// let mut backend = CpuBackend::new();
490/// let x = TypedTensor::<f64>::from_vec_col_major(vec![2], vec![1.0, 2.0]).unwrap();
491/// let y = TypedTensor::<f64>::from_vec_col_major(vec![2], vec![3.0, 4.0]).unwrap();
492/// let sum = x.add(&y, &mut backend).unwrap();
493/// assert_eq!(sum.host_data().unwrap(), &[4.0, 6.0]);
494/// ```
495pub trait TypedTensorOpsExt<T: TensorScalar> {
496    /// Elementwise addition with NumPy-style broadcasting.
497    ///
498    /// # Errors
499    ///
500    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` for
501    /// incompatible operands, or [`tenferro_tensor::Error::BackendSource`] for
502    /// a typed backend failure.
503    fn add<B: TensorBackend>(
504        &self,
505        rhs: &TypedTensor<T>,
506        backend: &mut B,
507    ) -> tenferro_tensor::Result<TypedTensor<T>>;
508    /// Elementwise subtraction with NumPy-style broadcasting.
509    ///
510    /// # Errors
511    ///
512    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` for
513    /// incompatible operands, or [`tenferro_tensor::Error::BackendSource`] for
514    /// a typed backend failure.
515    fn sub<B: TensorBackend>(
516        &self,
517        rhs: &TypedTensor<T>,
518        backend: &mut B,
519    ) -> tenferro_tensor::Result<TypedTensor<T>>;
520    /// Elementwise multiplication with NumPy-style broadcasting.
521    ///
522    /// # Errors
523    ///
524    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` for
525    /// incompatible operands, or [`tenferro_tensor::Error::BackendSource`] for
526    /// a typed backend failure.
527    fn mul<B: TensorBackend>(
528        &self,
529        rhs: &TypedTensor<T>,
530        backend: &mut B,
531    ) -> tenferro_tensor::Result<TypedTensor<T>>;
532    /// Elementwise division with NumPy-style broadcasting.
533    ///
534    /// # Errors
535    ///
536    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` for
537    /// incompatible shapes, a numerical [`tenferro_tensor::Error::Extension`]
538    /// for a detected zero divisor, or [`tenferro_tensor::Error::BackendSource`]
539    /// for a typed backend failure.
540    fn div<B: TensorBackend>(
541        &self,
542        rhs: &TypedTensor<T>,
543        backend: &mut B,
544    ) -> tenferro_tensor::Result<TypedTensor<T>>;
545    /// Elementwise remainder with NumPy-style broadcasting.
546    ///
547    /// # Errors
548    ///
549    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` for
550    /// incompatible shapes, a numerical [`tenferro_tensor::Error::Extension`]
551    /// for a detected zero divisor, or [`tenferro_tensor::Error::BackendSource`]
552    /// for a typed backend failure.
553    fn rem<B: TensorBackend>(
554        &self,
555        rhs: &TypedTensor<T>,
556        backend: &mut B,
557    ) -> tenferro_tensor::Result<TypedTensor<T>>;
558    /// Elementwise power with NumPy-style broadcasting.
559    ///
560    /// # Errors
561    ///
562    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` for
563    /// incompatible shapes, a numerical [`tenferro_tensor::Error::Extension`]
564    /// for a detected negative integer exponent, or
565    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
566    fn pow<B: TensorBackend>(
567        &self,
568        rhs: &TypedTensor<T>,
569        backend: &mut B,
570    ) -> tenferro_tensor::Result<TypedTensor<T>>;
571    /// Elementwise maximum with NumPy-style broadcasting.
572    ///
573    /// # Errors
574    ///
575    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` for
576    /// incompatible operands, or [`tenferro_tensor::Error::BackendSource`] for
577    /// a typed backend failure.
578    fn maximum<B: TensorBackend>(
579        &self,
580        rhs: &TypedTensor<T>,
581        backend: &mut B,
582    ) -> tenferro_tensor::Result<TypedTensor<T>>;
583    /// Elementwise minimum with NumPy-style broadcasting.
584    ///
585    /// # Errors
586    ///
587    /// Returns [`tenferro_tensor::Error::Validation`] with `ShapeMismatch` for
588    /// incompatible operands, or [`tenferro_tensor::Error::BackendSource`] for
589    /// a typed backend failure.
590    fn minimum<B: TensorBackend>(
591        &self,
592        rhs: &TypedTensor<T>,
593        backend: &mut B,
594    ) -> tenferro_tensor::Result<TypedTensor<T>>;
595    /// Elementwise negation.
596    ///
597    /// # Errors
598    ///
599    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
600    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
601    /// failure.
602    fn neg<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
603    /// Elementwise absolute value.
604    ///
605    /// # Errors
606    ///
607    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
608    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
609    /// failure.
610    fn abs<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
611    /// Elementwise sign.
612    ///
613    /// # Errors
614    ///
615    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
616    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
617    /// failure.
618    fn sign<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
619    /// Elementwise complex conjugate.
620    ///
621    /// # Errors
622    ///
623    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
624    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
625    /// failure.
626    fn conj<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
627    /// Elementwise exponential.
628    ///
629    /// # Errors
630    ///
631    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
632    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
633    /// failure.
634    fn exp<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
635    /// Elementwise natural logarithm.
636    ///
637    /// # Errors
638    ///
639    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
640    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
641    /// failure.
642    fn log<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
643    /// Elementwise sine.
644    ///
645    /// # Errors
646    ///
647    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
648    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
649    /// failure.
650    fn sin<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
651    /// Elementwise cosine.
652    ///
653    /// # Errors
654    ///
655    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
656    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
657    /// failure.
658    fn cos<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
659    /// Elementwise hyperbolic tangent.
660    ///
661    /// # Errors
662    ///
663    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
664    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
665    /// failure.
666    fn tanh<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
667    /// Elementwise square root.
668    ///
669    /// # Errors
670    ///
671    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
672    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
673    /// failure.
674    fn sqrt<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
675    /// Elementwise reciprocal square root.
676    ///
677    /// # Errors
678    ///
679    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
680    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
681    /// failure.
682    fn rsqrt<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
683    /// Elementwise `exp(x) - 1`.
684    ///
685    /// # Errors
686    ///
687    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
688    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
689    /// failure.
690    fn expm1<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
691    /// Elementwise `log(1 + x)`.
692    ///
693    /// # Errors
694    ///
695    /// Returns [`tenferro_tensor::Error::Unsupported`] for an unsupported
696    /// dtype or [`tenferro_tensor::Error::BackendSource`] for a typed backend
697    /// failure.
698    fn log1p<B: TensorBackend>(&self, backend: &mut B) -> tenferro_tensor::Result<TypedTensor<T>>;
699    /// Elementwise comparison with NumPy-style broadcasting.
700    ///
701    /// # Errors
702    ///
703    /// Returns [`tenferro_tensor::Error::Validation`] with
704    /// `ShapeMismatch::IncompatibleShapes` when broadcasting the operands is
705    /// impossible, or [`tenferro_tensor::Error::BackendSource`] for a typed
706    /// backend failure.
707    fn compare<B: TensorBackend>(
708        &self,
709        rhs: &TypedTensor<T>,
710        dir: CompareDir,
711        backend: &mut B,
712    ) -> tenferro_tensor::Result<TypedTensor<bool>>;
713    /// Clamp values elementwise between lower and upper bounds.
714    ///
715    /// # Errors
716    ///
717    /// Returns [`tenferro_tensor::Error::Validation`] with
718    /// `ShapeMismatch::IncompatibleShapes` when a bound cannot broadcast to
719    /// the input, or [`tenferro_tensor::Error::BackendSource`] for a typed
720    /// backend failure.
721    fn clamp<B: TensorBackend>(
722        &self,
723        lower: &TypedTensor<T>,
724        upper: &TypedTensor<T>,
725        backend: &mut B,
726    ) -> tenferro_tensor::Result<TypedTensor<T>>;
727    /// Rank-2 matrix multiplication.
728    ///
729    /// # Errors
730    ///
731    /// Returns [`tenferro_tensor::Error::Validation`] with `RankMismatch` when
732    /// either operand is not rank two or `ShapeMismatch::ContractedDimensions`
733    /// when the inner dimensions differ, or
734    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
735    fn matmul<B: TensorBackend>(
736        &self,
737        rhs: &TypedTensor<T>,
738        backend: &mut B,
739    ) -> tenferro_tensor::Result<TypedTensor<T>>;
740    /// Sum over one or more axes.
741    ///
742    /// # Errors
743    ///
744    /// Returns [`tenferro_tensor::Error::Validation`] with `AxisOutOfBounds`
745    /// for an axis outside the input rank or `DuplicateAxis` when `axes`
746    /// repeats an axis, or [`tenferro_tensor::Error::BackendSource`] for a
747    /// typed backend failure.
748    fn reduce_sum<B: TensorBackend>(
749        &self,
750        axes: &[usize],
751        backend: &mut B,
752    ) -> tenferro_tensor::Result<TypedTensor<T>>;
753    /// Reshape through the backend structural operation.
754    ///
755    /// # Errors
756    ///
757    /// Returns [`tenferro_tensor::Error::Validation`] with
758    /// `ShapeMismatch::ReshapeElementCount` when the element counts differ,
759    /// `IntegerOverflow` when shape arithmetic overflows, or
760    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
761    fn reshape<B: TensorBackend>(
762        &self,
763        shape: &[usize],
764        backend: &mut B,
765    ) -> tenferro_tensor::Result<TypedTensor<T>>;
766    /// Permute axes through the backend structural operation.
767    ///
768    /// # Errors
769    ///
770    /// Returns [`tenferro_tensor::Error::Validation`] with
771    /// `InvalidPermutationLength` when `perm` has the wrong length,
772    /// `AxisOutOfBounds` for an invalid axis, or `DuplicateAxis` for a
773    /// repeated axis, or [`tenferro_tensor::Error::BackendSource`] for a typed
774    /// backend failure.
775    fn transpose<B: TensorBackend>(
776        &self,
777        perm: &[usize],
778        backend: &mut B,
779    ) -> tenferro_tensor::Result<TypedTensor<T>>;
780    /// Broadcast into a larger shape.
781    ///
782    /// # Errors
783    ///
784    /// Returns [`tenferro_tensor::Error::Validation`] with `RankMismatch` when
785    /// `dims` does not match the input rank, `AxisOutOfBounds` or
786    /// `DuplicateAxis` for an invalid mapping, or
787    /// `ShapeMismatch::IncompatibleShapes` when known dimensions cannot
788    /// broadcast. [`tenferro_tensor::Error::BackendSource`] reports a typed
789    /// backend failure.
790    fn broadcast_in_dim<B: TensorBackend>(
791        &self,
792        shape: &[usize],
793        dims: &[usize],
794        backend: &mut B,
795    ) -> tenferro_tensor::Result<TypedTensor<T>>;
796}
797
798/// Backend-explicit bool-mask operations for typed tensors.
799///
800/// # Public API rationale
801///
802/// This trait keeps `where_select` available as a method on bool
803/// `TypedTensor`s while preserving the crate-root extension-trait surface. It
804/// is public because downstream users call it directly; the implementation
805/// helper in the private `typed_tensor` module is not a compatibility API.
806pub trait TypedTensorMaskOpsExt {
807    /// Select typed values using this bool tensor as condition.
808    ///
809    /// # Errors
810    ///
811    /// Returns [`tenferro_tensor::Error::Validation`] with
812    /// `ShapeMismatch::IncompatibleShapes` when the condition or either branch
813    /// cannot broadcast to the other operands, or
814    /// [`tenferro_tensor::Error::BackendSource`] for a typed backend failure.
815    fn where_select<T: TensorScalar, B: TensorBackend>(
816        &self,
817        on_true: &TypedTensor<T>,
818        on_false: &TypedTensor<T>,
819        backend: &mut B,
820    ) -> tenferro_tensor::Result<TypedTensor<T>>;
821}
822
823pub use traced::TracedTensor;