Skip to main content

reduce

Function reduce 

Source
pub fn reduce<T: Copy + MaybeSendSync, Op: ElementOp<T>, M, R, U>(
    src: &StridedView<'_, T, Op>,
    map_fn: M,
    reduce_fn: R,
    init: U,
) -> Result<U>
where M: Fn(T) -> U + MaybeSync, R: Fn(U, U) -> U + MaybeSync, U: Clone + MaybeSendSync,
Expand description

Full reduction with map function: reduce(init, op, map.(src)).

§Evaluation order

The result is independent of the ambient pool width when the call runs under the sequential policy — ExecContext::serial or with_execution_policy with ExecutionPolicy::Sequential: only serial branches run, and their fold order is fixed by the source layout. Under a parallel policy the fold is split over the effective thread count, so the result is repeatable for a fixed shape, layout and thread count but can differ between thread counts.

In neither case is this a strict left to right fold: a contiguous source is folded with sixteen independent lanes (see the crate source for the exact lane assignment), non-contiguous sources are traversed in a cache-friendly loop order, and parallel execution folds per-worker chunks independently and combines them in a tree. Floating point results can therefore differ from a sequential left to right sum in the last bits, and no bitwise equality across machines or target features is guaranteed.

Because of that, reduce_fn must be associative and commutative, and init must be an identity of reduce_fn whenever the reduction can run on several threads.

§Allocation

At rank ≤ INLINE_RANK the view metadata and the traversal plan are stored inline, so a call performs no heap allocation. Above that bound the planner may spill to the heap.

Because map_fn and reduce_fn are opaque closures this entry cannot select the dtype-specific SIMD kernels of crate::ErasedReducePlan; callers that reduce with a known operation (sum, product, max, min) on a supported dtype can use that plan for the fastest path.