lampshade 0.13.0

Fast, composable GPU primitives for Rust applications using wgpu and WGSL.
Documentation
@group(0) @binding(0)
var<storage, read> input: array<u32>;

@group(0) @binding(1)
var<storage, read_write> output: array<u32>;

const VT: u32 = {{VT}}u;
const BLOCK_SIZE: u32 = {{BLOCK_SIZE}}u;
const ITEMS_PER_BLOCK: u32 = VT * BLOCK_SIZE;
const IDENTITY: u32 = {{IDENTITY}};

var<workgroup> partials: array<u32, {{BLOCK_SIZE}}>;

fn combine(lhs: u32, rhs: u32) -> u32 {
    return {{COMBINE}};
}

@compute @workgroup_size(BLOCK_SIZE)
fn main(
    @builtin(local_invocation_id) local_id: vec3<u32>,
    @builtin(workgroup_id) group_id: vec3<u32>
) {
    let thread = local_id.x;
    let flat_group = group_id.y * {{MAX_WORKGROUPS_X}}u + group_id.x;
    if (flat_group >= arrayLength(&output)) {
        return;
    }
    let group_base = flat_group * ITEMS_PER_BLOCK;

    var value = IDENTITY;
    for (var item = 0u; item < VT; item++) {
        let index = group_base + thread + item * BLOCK_SIZE;
        if (index < arrayLength(&input)) {
            value = combine(value, input[index]);
        }
    }

    partials[thread] = value;
    workgroupBarrier();

    for (var stride = BLOCK_SIZE / 2u; stride > 0u; stride >>= 1u) {
        if (thread < stride) {
            partials[thread] = combine(partials[thread], partials[thread + stride]);
        }
        workgroupBarrier();
    }

    if (thread == 0u) {
        output[flat_group] = partials[0];
    }
}