Task 5 of 6

Min and Max: Change the Operator

Here's the secret hiding inside the ladder: nothing about it is really about addition. Any operation that combines two values and doesn't care about order or grouping — associative and commutative — can ride the same ladder. Swap + for Math.min and the scalar at the bottom is the smallest value in the array. Math.max gives the largest.

Two kernels, one driver. The structure doesn't change at all — only the fold rule.

Goal: find both the minimum and the maximum of data with two halving-ladder kernels, and log both.

Requirements

Hint 1 — Math inside kernels

Math.min(a, b) and Math.max(a, b) both work inside kernel functions. The fold becomes

Math.min(data[this.thread.x], data[this.thread.x + this.output.x])
Hint 2 — one driver, two ladders

Wrap last task's while-loop in a plain JS function that takes the kernel as a parameter — await reduce(minStep, data), await reduce(maxStep, data) — instead of writing it twice.

Same idea elsewhere

Pluggable operators are why every library ships reduce as a higher-order function: thrust::reduce and ROCm's rocPRIM accept any binary op plus an identity value, Metal Performance Shaders sells min/max reductions pre-built, and WGSL's subgroupMin/subgroupMax are this exact ladder burned into silicon.

All tasks in Reductions

  1. The One-Thread Trap
  2. Partial Sums: Divide the Work
  3. One Rung of the Ladder
  4. Ride the Ladder Down
  5. Min and Max: Change the Operator
  6. Payoff: Mean and RMS, Fused

This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.