Skip to main content

reduce

Function reduce 

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

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

§Evaluation order

The result is independent of the pool when the call runs with a serial token (Exec::serial) or a budget of one: only serial branches run, and their fold order is fixed by the source layout. With a larger budget the fold is split over the budget, so the result is repeatable for a fixed shape, layout and budget but can differ between budgets.

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-task 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.