Task 5 of 6
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.
data
with two halving-ladder kernels, and log both.minStep folds with Math.min, maxStep with Math.maxdynamicOutput: true and dynamicArguments: trueconsole.log both resultsMath.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])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.
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.
This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.