open-standards/wai/quantum-conformance
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science 897ab7d808 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]>
2026-10-11 23:12:21 -04:00
..
accept wai-quantum circuit2: the number range decided on the literal's digits in both readers 2026-10-09 18:50:35 -04:00
fabric wai-quantum WebGPU member: tile review fixes 2026-10-11 23:12:21 -04:00
reject wai-quantum circuit2: the number range decided on the literal's digits in both readers 2026-10-09 18:50:35 -04:00
tools wai-quantum circuit2: the number range decided on the literal's digits in both readers 2026-10-09 18:50:35 -04:00
v2 wai-quantum circuit2: wai-rs registers circuit2 and carries the corpus in both capabilities 2026-10-09 12:38:07 -04:00
vectors wai-quantum circuit2: wai-rs registers circuit2 and carries the corpus in both capabilities 2026-10-09 12:38:07 -04:00
browser_verify.mjs wai-quantum circuit2: a strict I-JSON reader, the rules stated in full, an accept corpus 2026-10-09 17:46:02 -04:00
browser_webgpu.mjs wai-quantum WebGPU member: tile runs, a second implementation certified on its own 2026-10-11 17:01:16 -04:00
expected_hashes.json wai-quantum circuit2: wai-rs registers circuit2 and carries the corpus in both capabilities 2026-10-09 12:38:07 -04:00
README.md wai-quantum WebGPU member: tile runs, a second implementation certified on its own 2026-10-11 17:01:16 -04:00

quantum-conformance

Statevector-equivalence for both capabilities of the quantum-sim extension (../extensions/quantum-sim.md): given the same WQC circuit, a conforming sink MUST reconstruct the identical fixed-point statevector — hash equality, no tolerance.

Provenance. Generated here by wai_quantum_vectors from circuits authored in code. No media.

Four trees, each a pinned corpus:

tree capability what
vectors/ + expected_hashes.json wai.quantum.circuit (WQC1) bell, ghz3, qft3 and qft5, frozen as they were first written, then qft5_x22, dyadic_ladder and qft8_ones
v2/vectors/ + v2/expected_hashes.json wai.quantum.circuit2 (WQC2) the same seven circuits; each entry names its capability
reject/ + reject/reject.json both payloads a conforming reader refuses, each with the class it is refused as: malformed, contract or invalid (extension §2)
accept/ + accept/accept.json both payloads a conforming reader accepts, at the edges of the same rules, each with how it reads: capability, n_qubits, op count, circuit hash and measurement (extension §2)

An entry with no capability is a wai.quantum.circuit vector. The trees are the one reference all three surfaces are checked against, rather than being checked against each other.

Native

cargo build --release --no-default-features --features quantum --bin wai_quantum_vectors
./target/release/wai_quantum_vectors verify wai/quantum-conformance

WASI (the edge)

Same binary, same source, different architecture:

cargo build --release --target wasm32-wasip2 --no-default-features --features quantum \
  --bin wai_quantum_vectors
wasmtime run --dir wai/quantum-conformance::/corpus \
  target/wasm32-wasip2/release/wai_quantum_vectors.wasm verify /corpus

CI runs this leg as a debug build, so integer overflow panics instead of wrapping (wai-conformance.yml, job quantum-wasip2, which also runs the crate's bit_identity tests and the circuit core's unit tests under wasmtime).

Browser

node wai/quantum-conformance/browser_verify.mjs [path/to/quantum-ml/pkg] [module file]

Drives the deployed wasm-bindgen bundle in headless Chromium: the sink opens every file of both vector trees to its manifest entry, refuses every reject file with its listed class and reads every accept file as listed (the two 255-qubit accept files only to the simulate stage: the sink simulates on construction, so they are checked to be read, not compared), and the IDE builds its catalog circuits in each gateset to the matching manifest. It is run by hand, before the website deploys a bundle. Note that the IDE's statevector_hash_hex() is empty until run() is called — the circuit is built eagerly, the state is not.

Browser, on the fabric's WebGPU member

WAI_QUANTUM_WEBGPU_REQUIRE=1 node wai/quantum-conformance/browser_webgpu.mjs

Serves wai-web/demo and this directory on 127.0.0.1 and opens quantum_webgpu.html in Playwright's headless browser, with the quantum_webgpu bundle built into wai-web/demo/pkg-webgpu (wai-web/demo/README.md). The gate kernel runs on the page's WebGPU adapter, compiled by the browser's own WGSL compiler. The page must certify the kernel bit-exact for both gatesets on random-v1 and fabric-v1 with the digests fabric/expected.json pins (the CPU reference's), and run every vector of both trees to its statevector hash, on the per-gate implementation and again on the tile implementation fabric/expected.json names (the browser's compiler holds its barrier to WGSL's uniformity rules); refuse every reject file with its listed class; and refuse a circuit wider than the member holds. Without WAI_QUANTUM_WEBGPU_REQUIRE=1, a page offered no adapter is reported and passes. CI runs it on macOS (wai-quantum-webgpu.yml, job browser).

Referee

python3 -I wai/quantum-conformance/tools/referee.py wai/quantum-conformance

A second implementation of the extension in Python, integers only, sharing no code with the Rust reference. It derives both phase tables (circuit/1 by its recurrence, circuit2 by an interval-certified procedure) and requires their literal values and digests, and the extension's Appendix B to state the same; rebuilds every vector file byte for byte and recomputes every manifest entry; refuses every reject file with its listed class and by the rule its name states; accepts every accept file and reads it as listed; and requires dyadic_ladder to change its statevector hash under every ±1 change of every phase-table entry, in both tables. CI runs it on Linux (wai-conformance.yml, job independent-verifiers).

Scope

The corpus pins the container, the reader's refusals, the fixed-point arithmetic and both phase tables, where hash equality is the right bar. What it covers, and where it stops:

  • Every phase-table entry. Under either table, a change of ±1 to either component of any P(1..32), with H following re P(3), changes dyadic_ladder's statevector hash; the referee checks this on every run. A change of ±1 to H alone changes the hash of every vector that applies H.
  • The four original vectors see no P(k). They run the QFT from |0…0⟩, where every controlled phase acts on zero amplitudes, so no change to a P(k) entry moves their hashes except through H, which follows re P(3); the three vectors after them are there for that.
  • One control at most. No vector applies a gate with more than one control. Such gates appear in the reject tree, and in the accept tree as circuit/1's repeated control.
  • One measurement. The shot sampler is pinned by bell's measurement alone.

The floating-point layers (quantum_source, quantum_channel) are held to exact IEEE-754 bits by unit tests instead, since they have no WQC circuit to pin — see entropy_is_bit_identical_across_architectures.