wai-quantum 0.4.2: tile runs certified on their own, and the WebGPU member in a browser #225
Merged
dcharlot
merged 5 commits from 2026-10-12 15:27:57 -04:00
wai-quantum-webgpu-tile into main 2026-10-11
wai-quantum 0.4.2: tile runs and the browser member, as their own release
Some checks failed
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 4m29s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 5s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 17m20s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 4s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m8s
wai-pack / wai-pack · linux (pull_request) Successful in 1m30s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 17s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m24s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 4m2s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m42s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m8s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 6m40s
standards workspaces build + test / aac-rs (pull_request) Successful in 3m38s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 2m0s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 1m33s
standards workspaces build + test / map-rs (pull_request) Successful in 49s
standards workspaces build + test / mesh-rs (pull_request) Successful in 48s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Failing after 7m44s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 24s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 2m31s
standards workspaces build + test / openpay (pull_request) Failing after 15m34s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m40s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 5m25s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 9m52s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 28m19s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 42s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 5m46s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 3m44s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 2m13s
wai-pack / wai-pack · macos (pull_request) Failing after 44s
0.4.1 is published, so the tile implementation and the browser member go out as 0.4.2, additive. Their CHANGELOG entries move out of the 0.4.1 entry into one of their own; the version line changes in the six lockfiles that resolve wai-quantum. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-quantum WebGPU member: tile review fixes
From an independent review of the tile implementation (no input gave wrong bits); each finding fixed: - expected.json is authoritative: tests/fabric_expected.rs (excluded from the package, so publishing is unaffected; cargo drops its target and verification builds the library only) requires quantum-conformance/fabric/expected.json to be exactly the four certificates of the pinned corpora (gateset, corpus, seed, cases, wide circuits, the digest the CPU computes) and both implementation ids; a missing file fails. The browser job runs it in place of the grep step, whose comment now says what is checked. A copy giving fabric-v1 random-v1's digests fails it. - The checker's step 6 adds a uniformity taint check: a barrier must not sit under a condition, or after a return, break or continue under a condition, that depends on the invocation's ids or on memory other invocations write (read-write storage, workgroup memory, atomics), directly or through a variable or a call. Uniform buffers, read-only storage, buffer lengths and the workgroup id, count and size are uniform. Planted early returns on local_invocation_index (the reviewer's variant among them), on a read-write load, through a variable and through a call each fail; the real shaders pass. - The tile kernel refuses a run record (bit 4, nothing touched) unless its tiles cover each state plane exactly and its grid (num_workgroups, one deep) holds every tile once with x_groups to a row. The tile implementation id is now wgsl-lanes32-tile/54e443520c020013, re-pinned in wgsl.rs and expected.json. - PlannedGate::is_well_formed: diag must match the words and the op index must not be u32::MAX (the tile kernel's "no op"). plan::execute_from returns None and the member refuses Internal(4) otherwise; compile never makes either. - The member splits a tile step into dispatches of at most SUBMIT_BUDGET pair-updates (splitting a run is exact), so every submission keeps the budget the module and POLL_TIMEOUT documents state. - g12 adds, for the tile member: starts other than zero; a first out-of-range op in a later submission with circuit/1 P(19) as filler (never skipped); a 600-gate run at 20 qubits that the member splits; ill-formed planned gates refused by both implementations; and, inside WAI_QUANTUM_WEBGPU_WIDE only, the widest sizes (run cap 16, grid (8, 8192) at 26 qubits), which the member script then requires. - Placement's tie order is documented as it is: with both implementations' entries for one member and no energy figures, place picks the tile implementation (its name sorts first); discovery opens per-gate members, which are the fallback. A test pins the order. - wai/wai-web/src/lib.rs is in the workflow's paths; the wasip2 job requires the new unit test by name. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-quantum WebGPU member: tile runs, a second implementation certified on its own
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]>
wai-quantum WebGPU member in a browser: wai-web bundle, page, check, CI
wai-web gains the feature `quantum_webgpu` (wai/quantum_fabric, wai/quantum_fabric_webgpu and wasm-bindgen-futures 0.4.77), which compiles src/quantum_webgpu.rs on wasm32: quantum_webgpu_discover() opens the page's adapter as a fabric member and probes its arithmetic; QuantumWebGpu reports the member and returns promises for certify (random-v1 or fabric-v1, as certificate JSON) and statevector_hash_hex (rejections read `<stage> (<class>): <reason>`). The default build is unchanged: its bundle has the same size, and differs only in the five panic-location line numbers of src/lib.rs that the new module declaration shifts. wai-web/Cargo.lock only adds entries (web-sys resolves to 0.3.104 beside js-sys 0.3.104 and wasm-bindgen 0.2.127); indexmap's hashbrown entry is relabelled with its version. demo/quantum_webgpu.html runs demo/quantum_webgpu_worker.js, which certifies both gatesets on random-v1 and fabric-v1, runs every quantum vector, offers every reject file and a circuit one qubit wider than the member holds; a second worker repeats the width check with the adapter offering the WebGPU default buffer limits, where the member holds 25 qubits and refuses 26 as too-wide. The bundle builds into demo/pkg-webgpu (ignored, as demo/pkg is). quantum-conformance/browser_webgpu.mjs drives the page headless and holds every result to the committed corpus and to fabric/expected.json (the four pinned digests and the implementation id). On macOS a headless page is offered a hardware adapter only with --use-angle=metal, which the script passes. CI: the checks job builds the bundle; a new browser job on macos checks that fabric/expected.json's pins are the crate's, builds the bundle with the wasm-bindgen CLI 0.2.127, installs Playwright 1.60.0 and its headless browser into the job's temp directory, and requires a GPU member certified bit-exact 4 of 4. Co-Authored-By: Claude Opus 5.5 <[email protected]>