wai-quantum 0.4.2: tile runs certified on their own, and the WebGPU member in a browser #225
Loading…
Reference in a new issue
No description provided.
Delete branch "wai-quantum-webgpu-tile"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
0.4.1 put one WGSL gate kernel on Metal, Vulkan and DX12, certified bit-exact against the CPU reference on each adapter. This adds the two pieces that follow from it:
What
The member in a browser (wai-web feature
quantum_webgpu, a bundle of its own,--out-name wai_quantum_webgpu)quantum_webgpu_discoverandQuantumWebGpu(certify,statevector_hash_hex) for JS. The default wai-web build and its bundle are unchanged.demo/quantum_webgpu.htmlruns the member in a worker.quantum-conformance/browser_webgpu.mjsdrives the page headless and requires:quantum-conformance/fabric/expected.jsonlists the four certificates and both implementation ids. A crate test (tests/fabric_expected.rs, not in the package) holds the file to the crate exactly, so the page's pins cannot be weakened by editing it alone.browserCI job on macOS.Tile runs:
wgsl-lanes32-tile/54e443520c020013plan::Config(PER_GATE,TILED),Step::Tile,compile_with,schedule,execute_from;PLAN_REVISIONis 2.A tiled plan applies each maximal run of consecutive gates that act inside a tile to tiles of up to 1024 amplitudes, in op-log order. Those are diagonal gates on any target, and others with their target inside the tile.
Only exact identities are left out. circuit/1's
P(19..=32)is2^30 − 1, not the identity, and stays.The CPU executor mirrors the kernel's index arithmetic and equals the per-gate program on any words.
lanes32_tile.wgsl:The plan's tile kernel used workgroup memory. The SPIR-V validator rejects the explicit layouts that the shader translator puts on workgroup arrays, so the kernel was restructured rather than the defect waived.
A run record whose tiles or grid do not cover the state exactly once is refused. So is a gate whose
diagdisagrees with its words, or an op index ofu32::MAX.Tile steps are split into dispatches of at most
SUBMIT_BUDGETpair-updates.The checker holds the tile shader to its own rules, including a uniformity taint check on the barrier, and its SPIR-V to the validator. Three tile mutants each have a named detector, including a race witness for a missing barrier.
WebGpuMember::tiled()runs the tile implementation on the same device; it is probed and certified on its own.Placement: given both implementations' entries for one member and no energy figures,
placepicks the tile implementation, because its id sorts first. Discovery opens per-gate members, which remain the fallback.Review
An independent review of both stages found no input on which either implementation returns bits other than the reference's. It ran:
Its findings are fixed:
u32::MAXis refused;diagis validated;Checked locally (Metal)
spirv-valaccepts both shaders. Planted non-uniform barriers fail the checker, and the browser rejects them too.wasm32-wasip2gates pass, and the package carries both shaders.Timing is printed and never asserted, from a loaded debug build. The tiled kernel is much faster on long circuits over small registers and faster at 16 and 22 qubits on random circuits. It is slower on some 16- and 20-qubit circuits, so placement should rest on measured energy, which a later stage attaches.
wai-quantum 0.4.2 is additive: default features,
full, the per-gate implementation and every existing pin are unchanged.🤖 Generated with Claude Code
plan (PLAN_REVISION 2): Config { tile_bits, run_max, skip_identity } with PER_GATE (what compile makes) and TILED (tiles of up to 1024 amplitudes, runs of up to 1024 gates, capped at 2^30 / 2^n, 16 at 26 qubits); Step::Tile { first, count, size }; compile_with, schedule, execute_from, PlannedGate::{new, is_identity}. A tile run is a maximal run of consecutive gates that act inside a tile: diagonal gates on any target, others with their target's bit below the tile size. Only exact identities are skipped (circuit/1's P(19..=32) is 2^30 - 1 and stays). The CPU executor mirrors the tile kernel's index arithmetic tile by tile; lanes::exact_row is shared with apply_words. Tests: every configuration (10 of them) equals the native simulator over random-v1 (300) and fabric-v1 and certifies with the four lanes32 pins; long random circuits and full-range random words tile exactly as they run gate by gate; fabric-v1 covers every tile path; malformed programs are refused; a_rounded_product_is_never_negated runs under every configuration. wgsl: TILE_SHADER = lanes32.wgsl followed by lanes32_tile.wgsl (entry point apply_tile, workgroup 256, one workgroup per tile, the tile size, gate range and grid in a 32-byte uniform run record, gates in a 48-byte read-only storage record), tile_implementation_id() = wgsl-lanes32-tile/de6fb388454a0144 (pinned), tile records, tile_grid (x at most 8), TILE_MUTANTS T1 (barrier between gates removed, detector Race over race_witness), T2 (the report's minimum dropped, Range) and T3 (tbit < size -> <=, Malformed over malformed_tile_run). Deviation from the plan's kernel text: no workgroup memory. naga 30.0.1 decorates every array type with ArrayStride and struct members with Offset, and spirv-val (SPIRV-Tools 2026.4) rejects explicit layouts on Workgroup variables (VUID-StandaloneSpirv-None-10684); per the plan the kernel was restructured instead: each workgroup updates its own tile in place in the state planes, with storageBarrier() between gates. The uniformity argument is unchanged (one barrier, at the top level of the loop over the run's gates). The min of the report is taken once per gate so that T2's text occurs once; a tile outside the state reports bit 2; a record outside the gate buffer reads as malformed. Checker: SHADER and TILE_SHADER each under their own rules (entry points and workgroup sizes, bindings, no workgroup memory, bool/u32 only, literal shifts, atomics, barrier kind and placement at the top level of the body or of a top-level for loop with no break, continue or return), translation to MSL, SPIR-V and HLSL, mutants; lanes32_tile.spv for spirv-val; --tile-shader. Member: WebGpuMember::tiled() compiles TILE_SHADER, probes it, plans with TILED and reports the tile implementation; per-gate stays the default and the fallback. Runs interleave gate and tile dispatches per submission (a second uniform ring for run records, a storage buffer for the runs' gates), within SUBMIT_BUDGET. Device tests: g8 kills T1-T3 on the tile member; new g12 runs 2,000 full-range cases tiled vs per-gate vs the CPU, the four pinned certificates under the tile implementation, forced geometries, the conformance vectors, five repeated runs, and prints per-gate vs tiled timing. The member script requires 13 tests and both implementations' certificates and mutants. Browser: QuantumWebGpu.tiled(); the worker certifies and runs the vectors on the tile member too; browser_webgpu.mjs requires "tiles certified bit-exact 4 of 4" and fabric/expected.json pins tile_implementation. CI: checks validate lanes32_tile.spv and package lanes32_tile.wgsl; the browser job checks the tile pin and greps the tile certificates; the wasip2 job requires the new tests by name, and its timeout is 90 minutes (the planner test runs several minutes alone in a debug wasm build). Co-Authored-By: Claude Opus 5.5 <[email protected]>