open-standards/wai/quantum-conformance/README.md
Transaction Science 8a3141366d determinism-tiers §5: CI validates the browser packages; the READMEs run CI's wasmtime
§5 said the browser crate's SIMD validation was done by hand, "which CI does
not check". Since "wai-web-wasm: the packages validate with relaxed SIMD and
threads off", wai-web-wasm.yml validates both bundles and
reach/record/wai_web_bg.wasm with relaxed SIMD and threads disabled. §5 now
says so, and says what CI still does not check: that they hold no other SIMD
instruction. The changelog gains the CI entry for this branch.

The commands that reproduce CI's wasmtime legs ran a stock wasmtime: the WAI
Quantum READMEs (English and Chinese), the bit_identity test's header, the WAI
README's edge example, and the conformance READMEs (quantum, qasm3, formats,
answers, intents). Each now passes -W nan-canonicalization=y
-W relaxed-simd-deterministic=y, as CI does. The determinism-cost run scripts
under wai/research keep their commands: they record runs already made.

The quantum docs check could not see that drift. For a `norun=ci:` block it
stripped every leading VAR=value before matching the command against the
workflow, and its pattern, \S*, did not read a quoted value. It now reads a
quoted or bare value, and when the workflow sets VAR (as an env: key or in a
script) the documented value must be one the workflow gives it, so
CARGO_TARGET_WASM32_WASIP2_RUNNER=wasmtime is refused against a workflow that
sets it to the flagged runner.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-04 12:29:00 -05:00

126 lines
6.4 KiB
Markdown

# 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) |
The OpenQASM 3 reader's corpus, programs with what the reader must do with
each, is `qasm3/`, with a README of its own. The error-correction text formats
(noisy Clifford circuits and detector error models, read and written back byte
for byte, with what each must count and what must be refused) are `qec-text/`,
with a README of its own. Programs in other formats (QIR under its profiles,
and jeff), each with the program it must read to, its round trip and its
refusals, and OpenQASM written to each, are `formats/`, with a README of its
own.
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
```sh
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:
```sh
cargo build --release --target wasm32-wasip2 --no-default-features --features quantum \
--bin wai_quantum_vectors
wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y --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
```sh
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
```sh
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
```sh
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`.