How subgroupPartitionedAddNV Works in GLSL
The subgroupPartitionedAddNV intrinsic in GLSL enables
invocations within a subgroup to perform parallel addition reductions
across dynamically formed subsets of execution lanes without writing to
shared or global memory. Provided by the
GL_NV_shader_subgroup_partitioned extension, this function
solves the performance bottleneck of aggregating data across arbitrary
runtime categories by using fast, register-level intra-warp
communication instead of serialized atomic operations.
In standard GLSL subgroup operations like subgroupAdd,
reduction operations automatically span either the entire active
subgroup or a contiguous range of lanes. In real-time rendering and
compute tasks—such as binning particles, clustering light sources, or
aggregating material attributes—lanes in a subgroup rarely belong to the
same category. Without partitioned operations, threads sharing an
identical property (such as a spatial cell index or material ID) must
serialize their accumulations using atomic adds in shared memory or
global memory, leading to severe hardware contention.
To aggregate values over dynamically clustered lanes, the algorithm
first identifies which invocations belong to the same cluster. This
clustering is represented as a partition mask, typically generated using
the subgroupPartitionNV(key) function. In this step, each
thread passes a runtime value—such as an integer hash or identifier—into
subgroupPartitionNV. The hardware evaluates the inputs
across all active lanes and returns a 4-component 32-bit unsigned
integer vector (uvec4) acting as a bitmask (ballot). In
this ballot, bits are set for all lanes within the subgroup that
provided the exact same key.
Once the partition ballot is established, each thread calls
subgroupPartitionedAddNV(value, ballot). The function takes
the local numerical value to be aggregated and the uvec4
ballot representing that thread's dynamic cluster.
The hardware uses the provided ballot to logically segment the subgroup into isolated execution partitions. Inside each partition:
- The hardware filters out lanes whose corresponding bits in the caller's ballot are zero, ignoring their values completely.
- An intra-warp reduction network executes a sum across only the lanes marked active within that ballot.
- Depending on whether an inclusive scan or an aggregate sum is specified, each participating lane receives the computed sum of all values submitted by the threads belonging to its dynamic partition.
Because subgroupPartitionedAddNV executes directly
across the GPU's register file and warp shuffle data paths, it
completely bypasses the L1/L2 caches and threadgroup shared memory
(TGSM). Multiple distinct partitions execute their additions
simultaneously in parallel without stalling or serializing one another,
yielding high throughput even when keys are randomly distributed across
subgroup lanes.