wgpu-primitives 0.3.0

Composable GPU primitives for Rust applications using wgpu.
Documentation
@group(0) @binding(0)
var<storage, read_write> data: array<u32>;

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

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

const VT: u32 = {{VT}}u;
const BLOCK_SIZE: u32 = {{BLOCK_SIZE}}u;
const ITEMS_PER_BLOCK: u32 = VT * BLOCK_SIZE;
override EXCLUSIVE: bool = false;

@compute @workgroup_size(BLOCK_SIZE)
fn main(
    @builtin(local_invocation_id) local_id: vec3<u32>,
    @builtin(workgroup_id) group_id: vec3<u32>
) {
    let tid = local_id.x;
    let flat_group_id = group_id.y * 65535u + group_id.x;
    let group_base = flat_group_id * ITEMS_PER_BLOCK;
    let thread_base = group_base + (tid * VT);

    var my_vals: array<u32, {{VT}}>;
    var my_sum = 0u;

    for (var i = 0u; i < VT; i++) {
        let idx = thread_base + i;
        if (idx < arrayLength(&data)) {
            my_vals[i] = data[idx];
            my_sum += my_vals[i];
        } else {
            my_vals[i] = 0u;
        }
    }

    // Hillis-Steele Scan (Shared Mem)
    temp[tid] = my_sum;
    workgroupBarrier();

    for (var offset = 1u; offset < BLOCK_SIZE; offset <<= 1u) {
        var val = 0u;
        if (tid >= offset) { val = temp[tid - offset]; }
        workgroupBarrier();
        if (tid >= offset) { temp[tid] += val; }
        workgroupBarrier();
    }

    let group_prefix = temp[tid];
    let thread_start_prefix = group_prefix - my_sum;

    var running_prefix = thread_start_prefix;
    for (var i = 0u; i < VT; i++) {
        let idx = thread_base + i;
        if (idx < arrayLength(&data)) {
            if (EXCLUSIVE) {
                data[idx] = running_prefix;
                running_prefix += my_vals[i];
            } else {
                running_prefix += my_vals[i];
                data[idx] = running_prefix;
            }
        }
    }

    if (tid == (BLOCK_SIZE - 1u)) {
        if (flat_group_id < arrayLength(&aux)) {
            aux[flat_group_id] = temp[BLOCK_SIZE - 1u];
        }
    }
}