wai-quantum 0.6.5 and the service: programs that measure in the middle #335

Merged
dcharlot merged 5 commits from wai/quantum-dynamic-circuits into main 2026-10-19 11:08:08 -04:00
Owner

Programs that measure in the middle, reset after a gate, or act on measured bits now run on the service. The library (wai-quantum 0.6.5) gains the two primitives they need. Additive: every pinned digest is unchanged, and a program that measures only at the end runs exactly as before.

Library

  • Tableau::measure(a, random) measures a qubit of the wide tableau and leaves the state the outcome selects (Aaronson–Gottesman).
    • A random outcome is the caller's to choose, so a branch can be followed on purpose.
    • The anticommuting stabilizer is multiplied into every other row at once: each row's phase is summed mod 4 in two bit planes, in the qubit-major layout.
  • Tableau::is_random(a) answers with a single column scan.
  • StateVector::probability_one (a fixed-chunk sum, so the same at any thread count) and StateVector::collapse.
  • Tests:
    • against the state vector's projection, Pauli string by Pauli string, over 60 random circuits with 6 measurements each;
    • on wide tableaux of 40–150 qubits, measuring every qubit lands inside the support the tableau held before, with one random outcome per dimension, and reading again repeats the result.
  • Mutants caught: signs kept, Y phase swapped, destabilizer not moved.

Service

  • Parsing (qasm::Instr): measurement and reset anywhere; if (c[0]) …, if (!c[0]) …, if (c == 3) { … } else { … }; OpenQASM 2's if(c==n) gate;; bit b = measure q;.
    • A program that needs any of these is kept as steps as well as gates. Every other program parses exactly as before.
  • Running (src/dynamic.rs): such a program runs on statevector or stabilizer. auto picks the tableau when every gate is Clifford.
    • Counts split their shots at each measurement and reset as independent shots would, each outcome running on in its own copy of the state.
    • Expectation values are the exact mixture over the branches (at most 4096), of the state before the final measurements.
    • Loops, noise in such a program, and amplitudes of one are refused with their reasons.
  • Tests:
    • teleportation, with ⟨Z⟩ = cos θ and ⟨X⟩ = sin θ exactly;
    • a Clifford teleport on the tableau, agreeing with the state vector;
    • reset, and re-measurement after a flip;
    • a bit-flip syndrome that corrects the flip, with the syndrome bits naming it;
    • seed determinism;
    • the step structure with its jumps, and the planner.
  • Mutants caught: terminal measurements made, a branch's outcome swapped, reset without its flip, condition bits reversed.
  • Docs: the README gains a "Programs that measure in the middle" section; the OpenAPI, MCP descriptions and parser header are updated; CHANGELOG entry added.

Checks run on the build host, on the tree merged with main

  • wai-quantum lib tests: 644 pass.
  • Service tests: 59 pass.
  • Service clippy is clean.
  • My library files have no clippy findings. Clippy --all-targets on wai-quantum reports pre-existing findings in other files.
  • scripts/check-lockfiles.sh passes.

Lockfiles. wai-quantum is 0.6.5 in every workspace that pins it. Cargo's rewrite of wai-rs's lock also re-picks two Windows-only edges (windows-sys 0.52, getrandom 0.3), and both versions were already in the lock.

Note for the reviewer: an unrelated, pre-existing failure. On #331, energy receipts · linux-arm64 failed quantum_noisy::tests::branching_runs_depend_on_neither_threads_nor_the_state_limit. At 16 qubits, the run limited to 1 state differs slightly from the 64-state run.

  • Reproduced in the arm64 runner's own image: 5 of 20 runs fail, against 0 of 60 on macOS. It is intermittent, so a nondeterminism.
  • It is being investigated separately, and this PR does not touch that code.

🤖 Generated with Claude Code

Programs that measure in the middle, reset after a gate, or act on measured bits now run on the service. The library (wai-quantum 0.6.5) gains the two primitives they need. Additive: every pinned digest is unchanged, and a program that measures only at the end runs exactly as before. **Library** - `Tableau::measure(a, random)` measures a qubit of the wide tableau and leaves the state the outcome selects (Aaronson–Gottesman). - A random outcome is the caller's to choose, so a branch can be followed on purpose. - The anticommuting stabilizer is multiplied into every other row at once: each row's phase is summed mod 4 in two bit planes, in the qubit-major layout. - `Tableau::is_random(a)` answers with a single column scan. - `StateVector::probability_one` (a fixed-chunk sum, so the same at any thread count) and `StateVector::collapse`. - **Tests:** - against the state vector's projection, Pauli string by Pauli string, over 60 random circuits with 6 measurements each; - on wide tableaux of 40–150 qubits, measuring every qubit lands inside the support the tableau held before, with one random outcome per dimension, and reading again repeats the result. - **Mutants caught:** signs kept, Y phase swapped, destabilizer not moved. **Service** - **Parsing** (`qasm::Instr`): measurement and `reset` anywhere; `if (c[0]) …`, `if (!c[0]) …`, `if (c == 3) { … } else { … }`; OpenQASM 2's `if(c==n) gate;`; `bit b = measure q;`. - A program that needs any of these is kept as steps as well as gates. Every other program parses exactly as before. - **Running** (`src/dynamic.rs`): such a program runs on `statevector` or `stabilizer`. `auto` picks the tableau when every gate is Clifford. - Counts split their shots at each measurement and reset as independent shots would, each outcome running on in its own copy of the state. - Expectation values are the exact mixture over the branches (at most 4096), of the state before the final measurements. - Loops, noise in such a program, and amplitudes of one are refused with their reasons. - **Tests:** - teleportation, with ⟨Z⟩ = cos θ and ⟨X⟩ = sin θ exactly; - a Clifford teleport on the tableau, agreeing with the state vector; - reset, and re-measurement after a flip; - a bit-flip syndrome that corrects the flip, with the syndrome bits naming it; - seed determinism; - the step structure with its jumps, and the planner. - **Mutants caught:** terminal measurements made, a branch's outcome swapped, reset without its flip, condition bits reversed. - **Docs:** the README gains a "Programs that measure in the middle" section; the OpenAPI, MCP descriptions and parser header are updated; CHANGELOG entry added. **Checks run on the build host, on the tree merged with main** - wai-quantum lib tests: 644 pass. - Service tests: 59 pass. - Service clippy is clean. - My library files have no clippy findings. Clippy `--all-targets` on wai-quantum reports pre-existing findings in other files. - `scripts/check-lockfiles.sh` passes. **Lockfiles.** wai-quantum is 0.6.5 in every workspace that pins it. Cargo's rewrite of wai-rs's lock also re-picks two Windows-only edges (windows-sys 0.52, getrandom 0.3), and both versions were already in the lock. **Note for the reviewer: an unrelated, pre-existing failure.** On #331, `energy receipts · linux-arm64` failed `quantum_noisy::tests::branching_runs_depend_on_neither_threads_nor_the_state_limit`. At 16 qubits, the run limited to 1 state differs slightly from the 64-state run. - Reproduced in the arm64 runner's own image: 5 of 20 runs fail, against 0 of 60 on macOS. It is intermittent, so a nondeterminism. - It is being investigated separately, and this PR does not touch that code. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The library:
- Tableau::measure measures a qubit of the wide tableau and leaves the state
  the outcome selects; a random outcome is the caller's to choose, so a
  branch can be followed on purpose. The anticommuting stabilizer is
  multiplied into every other row at once, each row's phase summed mod 4 in
  two bit planes. Tableau::is_random answers in one column scan.
- StateVector::probability_one (fixed-chunk sum) and StateVector::collapse.
- Tests: against the state vector's projection over 60 random circuits of six
  measurements each; on wide tableaux, measuring every qubit lands in the
  support held before, one random outcome per dimension. Mutants caught:
  signs kept, Y phase swapped, destabilizer not moved.

The service:
- reads measurement and reset anywhere, if/else on measured bits (bit,
  !bit, ==, !=, OpenQASM 2's if(c==n)), and `bit b = measure q;`. A program
  that needs them is kept as steps (qasm::Instr); every other program is
  exactly what it was.
- runs such a program on statevector or stabilizer (src/dynamic.rs): counts
  split their shots at each measurement and reset as independent shots
  would, each outcome running on in its own copy; expectation values are the
  exact mixture over the branches, of the state before the final
  measurements. Noise in such a program, amplitudes of one, and loops are
  refused with their reasons.
- Tests: teleportation (<Z> = cos θ, <X> = sin θ exactly; the tableau and the
  state vector agree), reset and re-measurement, a bit-flip syndrome that
  corrects the flip, the step structure with its jumps, the planner. Mutants
  caught: terminal measurements made, a branch's outcome swapped, reset
  without its flip, condition bits reversed.

Lockfiles: wai-quantum 0.6.5 in every workspace that pins it; cargo's
rewrite of wai-rs's also re-picks two Windows-only edges (windows-sys
0.52, getrandom 0.3), both already in the lock.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-quantum-service: the exact walk's eight parameters, as clippy allows the library's walker
Some checks failed
wai-quantum FPGA member / member · FPGA simulation absent (linux) (pull_request) Successful in 21s
wai-quantum Metal member / member · Metal absent (linux) (pull_request) Successful in 21s
wai-quantum FPGA member / member · FPGA datapath, simulated (macos) (pull_request) Successful in 1m28s
wai-quantum neural-processor member / member · neural processor absent (linux) (pull_request) Successful in 18s
wai-quantum OpenCL member / member · OpenCL absent (linux) (pull_request) Successful in 20s
wai-quantum-qpu / clients against their contracts (linux) (pull_request) Successful in 19s
wai-quantum Metal member / member · Metal (macos) (pull_request) Successful in 1m13s
wai-quantum service / service · linux (pull_request) Failing after 38s
wai-quantum matrix-extension member / member · matrix extension, emulated (aarch64 Linux) (pull_request) Successful in 19s
wai-quantum neural-processor member / member · neural processor (macos) (pull_request) Successful in 6m3s
wai-quantum OpenCL member / member · OpenCL GPU (macos) (pull_request) Successful in 54s
wai-quantum service / service · macos (pull_request) Failing after 40s
wai-quantum matrix-extension member / member · matrix extension absent (macos) (pull_request) Successful in 13s
wai-quantum portable tensor program / tensor program · Metal and the arm64 CPU (macos) (pull_request) Successful in 20s
wai-quantum CPU vector units / member · vector unit absent (macos) (pull_request) Successful in 19s
wai-quantum tensor-engine member / member · tensor engine, the kernel toolchain's simulator (linux) (pull_request) Successful in 8m15s
wai-quantum portable tensor program / tensor program · CPU, mutants, GPU builds (pull_request) Successful in 29s
wai-quantum CPU vector units / member · vector unit, rvv 1024-bit (riscv64, emulated) (pull_request) Successful in 17s
wai-quantum CPU vector units / member · vector unit, sve 128-bit (aarch64, emulated) (pull_request) Successful in 26s
wai-quantum CPU vector units / member · vector unit, rvv 128-bit (riscv64, emulated) (pull_request) Successful in 13s
wai-quantum signal processor / processor and member · signal processor, emulated (pull_request) Successful in 13m52s
wai-quantum CPU vector units / member · vector unit, sve 2048-bit (aarch64, emulated) (pull_request) Successful in 10s
wai-quantum CPU vector units / member · vector unit, sve 512-bit (aarch64, emulated) (pull_request) Successful in 13s
wai-quantum CPU vector units / member · vector unit, avx2 (x86_64 silicon) (pull_request) Successful in 23s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m10s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m7s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 5m29s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 2m8s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m19s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 5m17s
d73788c5b0
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-quantum-service smoke: if is no longer the refusal example; teleportation checks the dynamic path
All checks were successful
wai-quantum FPGA member / member · FPGA simulation absent (linux) (pull_request) Successful in 19s
wai-quantum OpenCL member / member · OpenCL GPU (macos) (pull_request) Successful in 19s
wai-quantum matrix-extension member / member · matrix extension absent (macos) (pull_request) Successful in 9s
wai-quantum Metal member / member · Metal absent (linux) (pull_request) Successful in 22s
wai-quantum service / service · macos (pull_request) Successful in 27s
wai-quantum neural-processor member / member · neural processor absent (linux) (pull_request) Successful in 18s
wai-quantum portable tensor program / tensor program · Metal and the arm64 CPU (macos) (pull_request) Successful in 12s
wai-quantum OpenCL member / member · OpenCL absent (linux) (pull_request) Successful in 20s
wai-quantum CPU vector units / member · vector unit absent (macos) (pull_request) Successful in 12s
wai-quantum-qpu / clients against their contracts (linux) (pull_request) Successful in 20s
wai-quantum matrix-extension member / member · matrix extension, emulated (aarch64 Linux) (pull_request) Successful in 19s
wai-quantum service / service · linux (pull_request) Successful in 39s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 2m13s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 1m26s
wai-quantum tensor-engine member / member · tensor engine, the kernel toolchain's simulator (linux) (pull_request) Successful in 7m50s
wai-quantum portable tensor program / tensor program · CPU, mutants, GPU builds (pull_request) Successful in 28s
wai-quantum CPU vector units / member · vector unit, rvv 1024-bit (riscv64, emulated) (pull_request) Successful in 17s
wai-quantum CPU vector units / member · vector unit, sve 128-bit (aarch64, emulated) (pull_request) Successful in 26s
wai-quantum CPU vector units / member · vector unit, rvv 128-bit (riscv64, emulated) (pull_request) Successful in 12s
wai-quantum signal processor / processor and member · signal processor, emulated (pull_request) Successful in 13m22s
wai-quantum CPU vector units / member · vector unit, sve 2048-bit (aarch64, emulated) (pull_request) Successful in 10s
wai-quantum CPU vector units / member · vector unit, avx2 (x86_64 silicon) (pull_request) Successful in 13s
wai-quantum CPU vector units / member · vector unit, sve 512-bit (aarch64, emulated) (pull_request) Successful in 19s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m7s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m17s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m1s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 3m14s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 4m55s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m45s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m11s
33397f925a
The refusal check sent `if (c) x q;`, which now parses (and is refused for
an undeclared register instead). It sends a `while` loop, still refused.
A new check runs teleportation through the service: <Z2> = cos 0.7 and
<X2> = sin 0.7 exactly, four branches weighed, the shots all counted. All
checks held against the branch's release build on the build host.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge origin/main into wai/quantum-dynamic-circuits; CHANGELOG keeps every entry
All checks were successful
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 1m15s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 2m19s
wai-quantum tensor-engine member / member · tensor engine, the kernel toolchain's simulator (linux) (pull_request) Successful in 9m5s
wai-quantum portable tensor program / tensor program · CPU, mutants, GPU builds (pull_request) Successful in 29s
wai-quantum CPU vector units / member · vector unit, rvv 1024-bit (riscv64, emulated) (pull_request) Successful in 18s
wai-quantum signal processor / processor and member · signal processor, emulated (pull_request) Successful in 14m40s
wai-quantum CPU vector units / member · vector unit, sve 128-bit (aarch64, emulated) (pull_request) Successful in 29s
wai-quantum CPU vector units / member · vector unit, rvv 128-bit (riscv64, emulated) (pull_request) Successful in 25s
wai-quantum CPU vector units / member · vector unit, sve 2048-bit (aarch64, emulated) (pull_request) Successful in 17s
wai-quantum CPU vector units / member · vector unit, avx2 (x86_64 silicon) (pull_request) Successful in 18s
wai-quantum CPU vector units / member · vector unit, sve 512-bit (aarch64, emulated) (pull_request) Successful in 20s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m18s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m19s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m30s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 5m31s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m47s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 14m58s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m28s
wai-pack / wai-pack · macos (pull_request) Successful in 1m12s
wai-quantum dataflow member / member · dataflow device absent (macos) (pull_request) Successful in 14s
wai-quantum FPGA member / member · FPGA datapath, simulated (macos) (pull_request) Successful in 1m10s
wai-quantum Metal member / member · Metal (macos) (pull_request) Successful in 32s
wai-quantum neural-processor member / member · neural processor (macos) (pull_request) Successful in 6m20s
wai-quantum OpenCL member / member · OpenCL GPU (macos) (pull_request) Successful in 45s
wai-quantum service / service · macos (pull_request) Successful in 34s
wai-quantum matrix-extension member / member · matrix extension absent (macos) (pull_request) Successful in 11s
wai-quantum portable tensor program / tensor program · Metal and the arm64 CPU (macos) (pull_request) Successful in 16s
wai-quantum CPU vector units / member · vector unit absent (macos) (pull_request) Successful in 14s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 4m54s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 1m51s
69681dcc40
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!335
No description provided.