pub struct CpuExecutionContext { /* private fields */ }Expand description
Caller-owned CPU execution domain for plain, graph, and eager-AD work.
The context owns one CpuBackend and lends its engine to one caller at a
time. A session entered from a Rayon worker runs inline on a fresh serial
engine that shares the context engine’s prepared-plan cache instead of
waiting for the context engine: a worker that waits for a pool install is
handed more of the enclosing pool’s work, and that work may enter a session
itself (tensor4all-rs#830). Graph preparation caches, the engine’s buffer
pool and the eager runtime are owned by this context and are released when
it is dropped.
§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tensor4all_tensorbackend::CpuBackend;
let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let threads = context.with_backend(|backend| backend.num_threads());
assert_eq!(threads, 1);Implementations§
Source§impl CpuExecutionContext
impl CpuExecutionContext
Sourcepub fn from_backend(backend: CpuBackend) -> Self
pub fn from_backend(backend: CpuBackend) -> Self
Create an execution context from a caller-selected CPU backend.
Runtime construction is lazy, so creating a context cannot fail and does not allocate another executor or consult environment configuration.
Sourcepub fn with_backend<R>(&self, f: impl FnOnce(&mut CpuBackend) -> R) -> R
pub fn with_backend<R>(&self, f: impl FnOnce(&mut CpuBackend) -> R) -> R
Run a plain tensor operation with this context’s engine.
The closure runs while the context-local engine lock is held. A lock
poisoned by a panic is recovered, and the engine is kept: it carries the
caller’s pool, allocation domain, batch policy and runtime engine id, so
a broken engine keeps refusing operations with tenferro’s typed
CpuEngineError::Broken instead of being silently replaced by a default
one. The caller builds a new context when it needs a new engine. The
session entries recover the same way.
This borrows the engine for the whole closure, so a session entry from
inside f on this thread is rejected with
CpuExecutionContextError::Reentered instead of waiting for the engine.
Calling with_backend from inside a session of this context is the
caller’s obligation not to do: this entry cannot report an error, so it
would wait for the engine the session already holds.
Sourcepub fn with_session<R>(
&self,
f: impl FnOnce(&mut CpuEngine) -> R,
) -> Result<R, CpuExecutionContextError>
pub fn with_session<R>( &self, f: impl FnOnce(&mut CpuEngine) -> R, ) -> Result<R, CpuExecutionContextError>
Run f in one session of this context’s engine.
This is the engine-borrow entry for callers that need the concrete
engine (for example to hand it to an eager AD session). The context lends
its engine to one caller at a time for the whole of f.
§Errors
Returns CpuExecutionContextError::Reentered when this thread is
already inside a session of this context.
§Examples
use tensor4all_tensorbackend::{CpuBackend, CpuExecutionContext};
let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let threads = context.with_session(|engine| engine.num_threads())?;
assert_eq!(threads, 1);Sourcepub fn compile_graph(
&self,
graph: &TracedGraph,
) -> Result<CompiledGraph, CpuExecutionContextError>
pub fn compile_graph( &self, graph: &TracedGraph, ) -> Result<CompiledGraph, CpuExecutionContextError>
Compile a backend-neutral traced graph using this context’s compiler cache.
§Errors
Returns CpuExecutionContextError::Graph when graph compilation fails.
Sourcepub fn run_graph(
&self,
graph: &CompiledGraph,
inputs: &[&Tensor],
) -> Result<Vec<Tensor>, CpuExecutionContextError>
pub fn run_graph( &self, graph: &CompiledGraph, inputs: &[&Tensor], ) -> Result<Vec<Tensor>, CpuExecutionContextError>
Execute a compiled graph in this context’s runtime and prepared-plan cache.
CompiledGraph is backend-neutral. Backend-prepared executables and
workspaces never leave this context-owned runtime.
§Errors
Returns CpuExecutionContextError::Reentered when this thread is
already inside a session of this context, and
CpuExecutionContextError::Initialization, CpuExecutionContextError::Graph
when runtime initialization, preparation, or execution fails.
Sourcepub fn eager_runtime(
&self,
) -> Result<Arc<EagerRuntime>, CpuExecutionContextError>
pub fn eager_runtime( &self, ) -> Result<Arc<EagerRuntime>, CpuExecutionContextError>
Return this context’s eager reverse-AD runtime.
The runtime is engine-independent: it is built once from an
[AdContext] with the linalg AD rules and the einsum/linalg extension
modules installed under this context engine’s runtime id, and every call
takes the caller’s engine ([EagerRuntime::with_eager_session]). Repeated
calls return the same runtime and therefore the same eager compilation
cache. The runtime registers itself with the eager-runtime owner table once,
when it is built.
§Errors
Returns CpuExecutionContextError when linalg AD-rule or eager-runtime
registration fails.
Sourcepub fn graph_cache_stats(
&self,
) -> Result<RuntimeCacheStats, CpuExecutionContextError>
pub fn graph_cache_stats( &self, ) -> Result<RuntimeCacheStats, CpuExecutionContextError>
Return statistics for this context’s runtime-owned graph caches.
§Errors
Returns CpuExecutionContextError::Reentered when this thread is
already inside a session of this context, and
CpuExecutionContextError when graph initialization or the cache
statistics query fails.
Sourcepub fn graph_buffer_pool_stats(
&self,
) -> Result<BufferPoolStats, CpuExecutionContextError>
pub fn graph_buffer_pool_stats( &self, ) -> Result<BufferPoolStats, CpuExecutionContextError>
Return retained-buffer statistics for this context’s engine.
buffers counts the retained allocations and capacity_bytes their
total element capacity. A context whose pool has just been released by
Self::reset_graph_buffer_pool reports zero.
§Errors
Returns CpuExecutionContextError::Reentered when this thread is
already inside a session of this context.
§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tenferro::program::{CoreSemanticOp, ProgramInputSpec};
use tenferro::{DType, Tensor, TraceContext};
use tensor4all_tensorbackend::CpuBackend;
let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
let mut trace = TraceContext::new();
let input = trace.input(ProgramInputSpec::new(DType::F64, [2_usize.into()]))?;
let output = trace.add_op(CoreSemanticOp::Neg, &[input])?[0];
let graph = trace.finish(&[output])?;
let compiled = context.compile_graph(&graph)?;
let values = Tensor::from_vec_col_major(vec![2], vec![1.0_f64, -2.0])?;
let output = context.run_graph(&compiled, &[&values])?;
assert_eq!(output[0].as_slice::<f64>()?, &[-1.0, 2.0]);
// Releasing the pool empties it.
context.reset_graph_buffer_pool()?;
let after = context.graph_buffer_pool_stats()?;
assert_eq!(after.buffers, 0);
assert_eq!(after.capacity_bytes, 0);Sourcepub fn reset_graph_buffer_pool(&self) -> Result<(), CpuExecutionContextError>
pub fn reset_graph_buffer_pool(&self) -> Result<(), CpuExecutionContextError>
Release retained buffers owned by this context’s engine.
The graph runtime, its compiled plans and its prepared-plan cache are kept, so callers can keep running previously compiled graphs afterwards.
§Errors
Returns CpuExecutionContextError::Reentered when this thread is
already inside a session of this context.
§Examples
use tensor4all_tensorbackend::CpuExecutionContext;
use tensor4all_tensorbackend::CpuBackend;
let context = CpuExecutionContext::from_backend(CpuBackend::with_threads(1)?);
context.reset_graph_buffer_pool()?;
// The pool retains nothing afterwards, and the runtime stays usable.
let stats = context.graph_buffer_pool_stats()?;
assert_eq!(stats.buffers, 0);
assert_eq!(stats.capacity_bytes, 0);Sourcepub fn reset_graph_runtime(&self) -> Result<(), CpuExecutionContextError>
pub fn reset_graph_runtime(&self) -> Result<(), CpuExecutionContextError>
Recreate this context’s graph runtime and release its prepared caches.
§Errors
Returns CpuExecutionContextError::Reentered when this thread is
already inside a session of this context.
Source§impl CpuExecutionContext
impl CpuExecutionContext
Sourcepub fn with_concrete_session<R>(
&self,
f: impl FnOnce(&mut Session<'_>) -> R,
) -> Result<R, CpuExecutionContextError>
pub fn with_concrete_session<R>( &self, f: impl FnOnce(&mut Session<'_>) -> R, ) -> Result<R, CpuExecutionContextError>
Run f inside one explicit concrete session of this context.
The context’s engine is borrowed once for the whole closure, so a stage
borrows it once and reuses its prepared plans and buffer pool. All routes on
the Session run on that engine only: nothing here consults the
process-global default context, and nothing falls back to it.
§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], vec![1.0_f64, 3.0])?;
let doubled = context.with_concrete_session(|session| session.reshape(&x, &[2]))??;
assert_eq!(doubled.as_slice::<f64>()?, &[1.0, 3.0]);§Errors
Returns CpuExecutionContextError::Reentered when the calling thread is
already inside a session of this context. A session entered from a Rayon
worker runs inline on a serial engine that shares the context engine’s
prepared-plan cache, so a worker entry completes instead of waiting for a
pool it belongs to (tensor4all-rs#830).
§Panics
Never. A panic in f propagates after the engine borrow is released.
Source§impl CpuExecutionContext
impl CpuExecutionContext
Sourcepub fn reconstruct(
&self,
tensor: &LogicalTensor,
) -> Result<Tensor, LogicalTensorError>
pub fn reconstruct( &self, tensor: &LogicalTensor, ) -> Result<Tensor, LogicalTensorError>
Reconstruct a logical host tensor in this receiving execution domain.
The returned value carries only host tensor data. Its first plain, graph, or eager operation must use this same explicit context.
§Errors
Returns LogicalTensorError if tenferro rejects the validated shape or
dtype payload.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for CpuExecutionContext
impl !RefUnwindSafe for CpuExecutionContext
impl !UnwindSafe for CpuExecutionContext
impl Send for CpuExecutionContext
impl Sync for CpuExecutionContext
impl Unpin for CpuExecutionContext
impl UnsafeUnpin for CpuExecutionContext
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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