#[non_exhaustive]pub enum ScratchRequirement {
None,
Fixed {
bytes: usize,
},
PerElement {
bytes_per_element: usize,
},
Unbounded,
Affine {
base_bytes: usize,
bytes_per_element: usize,
bytes_per_worker: usize,
},
}Expand description
Scratch memory an operation needs beyond its inputs and outputs.
Declared up front so a caller can budget, pre-reserve, or refuse before any
work starts. Unbounded is deliberately representable and deliberately
unpleasant: an operation that cannot bound its scratch must say so rather
than allocating silently in a hot loop.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
None
Operates in place; no scratch beyond inputs and outputs.
Fixed
At most bytes of scratch, independent of input size.
PerElement
At most bytes_per_element * elements of scratch.
Unbounded
Scratch cannot be bounded ahead of time.
Callers must treat this as “may allocate arbitrarily”; a memory budget cannot be enforced against it.
Affine
At most base_bytes + bytes_per_element * elements + bytes_per_worker * workers of scratch, where workers is the number
of threads the operation may run on.
For an operation whose scratch is not purely per element: a fixed
setup cost dominates small inputs, and a threaded operation pays per
worker (pool bookkeeping, work stolen onto another thread being live
at the same time as the rest) no matter how small the input is
(#226). A Self::PerElement bound tight enough for large inputs is
then below the real peak for small ones.
Implementations§
Source§impl ScratchRequirement
impl ScratchRequirement
Sourcepub const fn upper_bound_bytes(self, elements: usize) -> Option<usize>
pub const fn upper_bound_bytes(self, elements: usize) -> Option<usize>
Upper bound for elements inputs, or None when unbounded.
An Self::Affine requirement with a per-worker term has no bound
without a worker count, so it reports None here; use
Self::upper_bound_bytes_on.
Sourcepub const fn upper_bound_bytes_on(
self,
elements: usize,
workers: usize,
) -> Option<usize>
pub const fn upper_bound_bytes_on( self, elements: usize, workers: usize, ) -> Option<usize>
Upper bound for elements inputs run on workers threads, or None
when unbounded or when the bound overflows usize.
Only Self::Affine depends on workers.
Sourcepub fn fits_budget(self, options: &ExecutionOptions, elements: usize) -> bool
pub fn fits_budget(self, options: &ExecutionOptions, elements: usize) -> bool
Whether this requirement fits options’ memory budget for elements.
An unbounded requirement never fits a declared budget: allowing it would
make the budget advisory, which is the failure this type exists to stop.
A per-worker term is charged for Parallelism::worker_bound of
options’ parallelism; a caller that knows the operation runs on a
different number of threads uses Self::fits_budget_on.
No longer const: it reads an ExecutionOptions that now owns a
shared cancellation handle, so it cannot be destructured at compile
time. Budget checks happen once per dispatch, not on a hot path.
Sourcepub fn fits_budget_on(
self,
options: &ExecutionOptions,
elements: usize,
workers: usize,
) -> bool
pub fn fits_budget_on( self, options: &ExecutionOptions, elements: usize, workers: usize, ) -> bool
Whether this requirement fits options’ memory budget for elements
run on workers threads.
For a caller that knows the width the operation actually runs on: a dispatcher scoping the call to its own pool, or a provider checking the pool it finds itself in.
Trait Implementations§
Source§impl Clone for ScratchRequirement
impl Clone for ScratchRequirement
Source§fn clone(&self) -> ScratchRequirement
fn clone(&self) -> ScratchRequirement
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more