Skip to main content

CpuExecutionContext

Struct CpuExecutionContext 

Source
pub struct CpuExecutionContext<'a> { /* private fields */ }
Expand description

Borrowed execution policy for an already-entered CPU operation.

The context exposes immutable domain facts while keeping the resource lease, executor object, and the checked executor-entry boundary private. Providers cannot install or submit work through this value.

§Examples

Providers inspect this value inside a trait method:

use tenferro_cpu::provider::CpuExecutionContext;
assert!(context.thread_budget().get() >= 1);

Implementations§

Source§

impl<'a> CpuExecutionContext<'a>

Source

pub fn batch_policy(&self) -> CpuBatchPolicy

The effective batch policy for batched work in this context.

It is the backend default unless a session scope overrides it; see crate::with_batch_policy.

§Examples
use tenferro_cpu::{with_cpu_exec_session, CpuBackend, CpuBatchStrategy};
use tenferro_tensor::BackendSessionHost;

let mut backend = CpuBackend::with_threads(1)?;
let strategy = backend.with_backend_session(|session| {
    with_cpu_exec_session(session, |cpu| {
        cpu.with_linalg_pool(|context, _| Ok(context.batch_policy().strategy()))
    })
    .expect("a CPU backend session")
})??;
assert_eq!(strategy, CpuBatchStrategy::Auto);
Source

pub fn can_fan_out_lanes(&self) -> bool

Whether Self::with_outer_lanes can fan out from this context.

§Examples
use tenferro_cpu::{with_cpu_exec_session, CpuBackend};
use tenferro_tensor::BackendSessionHost;

let mut backend = CpuBackend::with_threads(1)?;
let fans_out = backend.with_backend_session(|session| {
    with_cpu_exec_session(session, |cpu| {
        cpu.with_linalg_pool(|context, _| Ok(context.can_fan_out_lanes()))
    })
    .expect("a CPU backend session")
})??;
assert!(!fans_out);
Source

pub fn is_outer_fan_out_lane(&self) -> bool

Whether this context is one lane of tenferro’s own outer fan-out.

Such a lane runs concurrently with its siblings. Its mode is ParallelMode::Sequential, so it may not start inner parallel work, and a provider whose declared parallelism is an independent runtime (the default for external BLAS/LAPACK) is rejected before dispatch. Running on a Rayon worker is not by itself outer fan-out.

§Examples
use tenferro_cpu::{with_cpu_exec_session, CpuBackend};
use tenferro_tensor::BackendSessionHost;

let mut backend = CpuBackend::with_threads(1)?;
let lane = backend.with_backend_session(|session| {
    with_cpu_exec_session(session, |cpu| {
        cpu.with_linalg_pool(|context, _| Ok(context.is_outer_fan_out_lane()))
    })
    .expect("a CPU backend session")
})??;
assert!(!lane);
Source

pub fn with_outer_lanes<I>( &self, jobs: I, job: impl Fn(I::Item, &CpuExecutionContext<'a>) + Sync, )
where I: IntoIterator, I::IntoIter: Send, I::Item: Send,

Run independent lane jobs as tenferro-owned outer fan-out inside this already-entered context’s own Rayon region.

Each item of jobs (typically one disjoint chunk of a batch) runs once and receives a lane context: Self::is_outer_fan_out_lane is true and the mode is ParallelMode::Sequential, so the lane neither starts inner parallel work nor reaches an independent-runtime provider. Fan-out needs an ParallelMode::Inner context of a Rayon executor with more than one thread; otherwise the jobs run in order on the calling thread, still with a lane context. No second pool is created: jobs run on the Rayon pool this context was entered in.

§Examples
use tenferro_cpu::{with_cpu_exec_session, CpuBackend};
use tenferro_tensor::BackendSessionHost;

let mut backend = CpuBackend::with_threads(2)?;
let mut data = vec![1.0_f64; 8];
backend.with_backend_session(|session| {
    with_cpu_exec_session(session, |cpu| {
        cpu.with_linalg_pool(|context, _| {
            context.with_outer_lanes(data.chunks_mut(3), |chunk, lane| {
                assert!(lane.is_outer_fan_out_lane());
                chunk.iter_mut().for_each(|value| *value *= 2.0);
            });
            Ok(())
        })
    })
    .expect("a CPU backend session")
})??;
assert_eq!(data, [2.0; 8]);
Source

pub fn domain_id(&self) -> CpuDomainId

Return the stable identity of the selected CPU resource domain.

§Examples
use tenferro_cpu::CpuExecutionContext;
let _domain_id = context.domain_id();
Source

pub fn cpus(&self) -> Option<&CpuSet>

Return the selected domain’s declared logical CPU set, when present.

§Examples
use tenferro_cpu::CpuExecutionContext;
if let Some(cpus) = context.cpus() {
    assert!(!cpus.is_empty());
}
Source

pub fn admission_mode(&self) -> CpuAdmissionMode

Return the selected domain’s admission contract.

§Examples
use tenferro_cpu::{CpuAdmissionMode, CpuExecutionContext};
let _mode: CpuAdmissionMode = context.admission_mode();
Source

pub fn thread_budget(&self) -> NonZeroUsize

Return the non-zero maximum participating-thread budget.

§Examples
use tenferro_cpu::CpuExecutionContext;
assert!(context.thread_budget().get() >= 1);
Source

pub fn parallel_mode(&self) -> ParallelMode

Return the engine-selected scheduling mode for this entered provider call.

Provider calls observe Sequential or Inner. Outer scheduling creates a separate Sequential context inside every submitted child.

§Examples
use tenferro_cpu::{CpuExecutionContext, ParallelMode};
assert!(matches!(
    context.parallel_mode(),
    ParallelMode::Sequential | ParallelMode::Inner
));
Source

pub fn rayon_pool(&self) -> Option<&'a ThreadPool>

The Rayon pool this context’s inner parallel region runs on.

Some exactly when the context owns an inner region: parallel mode ParallelMode::Inner, a Rayon-backed executor, and a thread budget above one (the same gate as the faer policy). The caller is already on a worker of this pool, so work installed or scoped on it runs in place. A provider running its own kernels on the pool must use at most CpuExecutionContext::thread_budget threads, which can be smaller than the pool, and declares crate::CpuThreadCountControl::PerCallUpperBound with crate::CpuPlacementControl::EngineWorkers.

§Examples
use tenferro_cpu::{with_cpu_exec_session, CpuBackend};
use tenferro_tensor::BackendSessionHost;
let mut backend = CpuBackend::with_threads(2)?;
let workers = backend.with_backend_session(|session| {
    with_cpu_exec_session(session, |cpu| {
        cpu.with_linalg_pool(|context, _| {
            Ok(context.rayon_pool().map(|pool| pool.current_num_threads()))
        })
    })
    .expect("a CPU backend session")
})??;
assert_eq!(workers, Some(2));

Trait Implementations§

Source§

impl<'a> Clone for CpuExecutionContext<'a>

Source§

fn clone(&self) -> CpuExecutionContext<'a>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Copy for CpuExecutionContext<'a>

Source§

impl Debug for CpuExecutionContext<'_>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
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> MaybeSend for T
where T: Send,

§

impl<T> MaybeSendSync for T
where T: Send + Sync,

§

impl<T> MaybeSync for T
where T: Sync,

§

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
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.