Task 2 of 6

Partial Sums: Divide the Work

The fix: give every thread a slice. 64 threads, each summing 64 of the 4,096 values, produce 64 partial sums — and 64 leftover numbers are cheap to finish off in plain JavaScript.

Watch the reading pattern, though. Thread x does not take a contiguous block; it reads data[x], data[x + 64], data[x + 128], … — a strided walk. At every step of the loop, neighbouring threads touch neighbouring elements, which is exactly the access pattern GPU memory hardware is built to serve in one go.

thread x takes every 64th element — neighbours read neighbours at every step
Goal: compute 64 strided partial sums on the GPU, then total the 64 partials in JavaScript and log the grand total.

Requirements

Hint 1 — which elements are mine?

Thread x owns elements x, x + 64, x + 128, … so its i-th element sits at index i * 64 + x.

Hint 2 — the loop body
sum += data[i * this.constants.threads + this.thread.x];
Hint 3 — finishing in JS

After const partial = await partials(data); a plain loop does it:

let total = 0;
for (let i = 0; i < partial.length; i++) {
  total += partial[i];
}

Same idea elsewhere

This is CUDA's grid-stride loop, almost line for line — every serious reduction in CUB and Thrust starts with per-thread partials accumulated in registers, and coalesced (strided-by-thread-count) reads are the whole reason for the pattern. WebGPU and Metal compute kernels stage the same partials into workgroup/threadgroup memory.

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.