CUDA Two-Stage Reduction with Atomics
Problem Statement
Reduce a 1D array to a single sum by combining a shared-memory tree reduction within each block with a single cuda.atomic.add per block into the global result. Verify out[0] equals x.sum().
Background
Per-block: load into shared memory, tree-reduce to s[0]. Then only thread 0 of each block does cuda.atomic.add(out, 0, s[0]) — so there are just gridDim.x atomics total instead of n, which is far less contention than one atomic per element.
Your Task
Implement reduce_sum_kernel and run(n=8192) returning whether the global sum matches x.sum().
How it is tested
Your solution must define a top-level function run(...) that allocates the inputs, copies them to the GPU, launches your @cuda.jit kernel, and returns a Python bool from np.allclose(gpu_result, reference). The grader prints run(...); the expected output is True.
Example
n = 8192
True
- The input
n = 8192represents the size of the 1D array to be reduced to a single sum. - The
reduce_sum_kernelfunction is launched with this input, where each block performs a shared-memory tree reduction to calculate the sum of its assigned elements, resulting in a partial sum stored ins[0]. - Only thread 0 of each block then performs a
cuda.atomic.addoperation to add its block's partial sum to the global resultout[0], minimizing contention with only atomic operations. - The final output
Trueindicates that the global sumout[0]matches the reference sum calculated usingx.sum(), verifying the correctness of the CUDA two-stage reduction implementation.
Constraints
- Shared-memory tree reduction within the block (cuda.syncthreads() between steps)
- Only thread 0 calls cuda.atomic.add(out, 0, s[0])
- Initialize the device accumulator to 0