wai-quantum: OpenQASM 3 generators, one program for a family of circuits #466

Merged
dcharlot merged 1 commit from wai/quantum-qasm-generators into main 2026-10-25 17:54:00 -04:00
Owner

The OpenQASM reader refused loops, so a family of circuits (a GHZ state on n qubits, the QFT, an adder) had to be written out once per size. This makes one program describe the whole family. It is the first piece of the specification-and-evaluator workbench: its proposers evolve such programs, and its evaluator checks them across n.

Reader (wai-quantum, feature quantum_qasm):

  • qasm::parse_with / parse_lines_with read a program at given integer inputs, and qasm::inputs lists the inputs it declares.
  • Supported:
    • input int|uint n; and const int|uint k = …;;
    • for i in [a:b] { … }, plus [a:step:b] (both ends included, as OpenQASM 3 reads a range) and {a, b, c}, nested;
    • integer arithmetic in indices and sizes: + - * / % with C's truncating division, **, comparisons, && || !;
    • if on integers alone, decided on reading. One that reads bits stays classical control.
  • Unrolled gates keep the lines of their loop's body, so a critique still points into the generator.
  • qasm::instantiate writes the circuit at given inputs out as plain OpenQASM. It reads back as the same program, gate for gate (tested for the QFT at n = 1, 3 and 6).
  • Bounded:
    • at most 20 million tokens;
    • every integer operation checked for overflow;
    • a name an integer would shadow (a register, a gate's parameter or qubit, a word of the language) is refused with its line.
    • A loop variable may still be called i, which is also the identity gate's name: integers are substituted only where they don't start a statement.
  • A program with no input, const or for reads exactly as before: the unrolling pass returns its tokens untouched.

CLI: --input NAME=VALUE on every command, so run, plan, critique, equivalent and shortcuts each read one circuit of the family. wai-quantum instance gen.qasm --input n=5 prints that circuit.

READMEs (engine, CLI, service) and the changelog are updated. The service reads for and const already, and is told to send an instance for a generator with inputs.

Checked on the build host:

  • cargo test --features quantum_qasm --lib qasm::: 19 pass. New:
    • a generator unrolls to the circuit written out (GHZ, line attribution, empty range);
    • nested loops, angles and integer division make the QFT;
    • steps, sets, constants and folded sizes;
    • an if on integers is decided while one on bits stays control, inside a loop;
    • an instance reads back as the same program;
    • every refusal says why.
  • cargo test --features full --lib --tests: 736 pass.
  • CLI: cargo test passes, including a_generator_is_read_at_its_inputs_and_a_plain_program_as_it_is, which also runs a 12-qubit GHZ instance end to end. cargo clippy --all-targets -- -D warnings is clean.

🤖 Generated with Claude Code

The OpenQASM reader refused loops, so a family of circuits (a GHZ state on n qubits, the QFT, an adder) had to be written out once per size. This makes one program describe the whole family. It is the first piece of the specification-and-evaluator workbench: its proposers evolve such programs, and its evaluator checks them across n. **Reader** (`wai-quantum`, feature `quantum_qasm`): - `qasm::parse_with` / `parse_lines_with` read a program at given integer inputs, and `qasm::inputs` lists the inputs it declares. - Supported: - `input int|uint n;` and `const int|uint k = …;`; - `for i in [a:b] { … }`, plus `[a:step:b]` (both ends included, as OpenQASM 3 reads a range) and `{a, b, c}`, nested; - integer arithmetic in indices and sizes: `+ - * / %` with C's truncating division, `**`, comparisons, `&& || !`; - `if` on integers alone, decided on reading. One that reads bits stays classical control. - Unrolled gates keep the lines of their loop's body, so a critique still points into the generator. - `qasm::instantiate` writes the circuit at given inputs out as plain OpenQASM. It reads back as the same program, gate for gate (tested for the QFT at n = 1, 3 and 6). - Bounded: - at most 20 million tokens; - every integer operation checked for overflow; - a name an integer would shadow (a register, a gate's parameter or qubit, a word of the language) is refused with its line. - A loop variable may still be called `i`, which is also the identity gate's name: integers are substituted only where they don't start a statement. - A program with no `input`, `const` or `for` reads exactly as before: the unrolling pass returns its tokens untouched. **CLI:** `--input NAME=VALUE` on every command, so `run`, `plan`, `critique`, `equivalent` and `shortcuts` each read one circuit of the family. `wai-quantum instance gen.qasm --input n=5` prints that circuit. READMEs (engine, CLI, service) and the changelog are updated. The service reads `for` and `const` already, and is told to send an instance for a generator with inputs. Checked on the build host: - `cargo test --features quantum_qasm --lib qasm::`: 19 pass. New: - a generator unrolls to the circuit written out (GHZ, line attribution, empty range); - nested loops, angles and integer division make the QFT; - steps, sets, constants and folded sizes; - an `if` on integers is decided while one on bits stays control, inside a loop; - an instance reads back as the same program; - every refusal says why. - `cargo test --features full --lib --tests`: 736 pass. - CLI: `cargo test` passes, including `a_generator_is_read_at_its_inputs_and_a_plain_program_as_it_is`, which also runs a 12-qubit GHZ instance end to end. `cargo clippy --all-targets -- -D warnings` is clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
wai-quantum: OpenQASM 3 generators, one program for a family of circuits
All checks were successful
wai-quantum CPU vector units / member · vector unit, avx2 (x86_64 silicon) (pull_request) Successful in 16s
wai-quantum CPU vector units / member · vector unit, sve 512-bit (aarch64, emulated) (pull_request) Successful in 18s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m11s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 4m31s
wai-quantum command line / command line · macos (pull_request) Successful in 30s
wai-quantum dataflow member / member · dataflow device absent (macos) (pull_request) Successful in 14s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m32s
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 28s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 4m39s
wai-quantum neural-processor member / member · neural processor (macos) (pull_request) Successful in 5m46s
wai-quantum OpenCL member / member · OpenCL GPU (macos) (pull_request) Successful in 19s
wai-quantum service / service · macos (pull_request) Successful in 39s
wai-quantum matrix-extension member / member · matrix extension absent (macos) (pull_request) Successful in 10s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 2m15s
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 13s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 3m33s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 16s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 11s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 26s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 2m26s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 1m22s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 1m39s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 7m3s
wai-quantum HIP member / member · HIP absent (linux-arm64) (pull_request) Successful in 23s
wai-quantum npu-cores member / member · npu-cores absent (linux-arm64) (pull_request) Successful in 26s
wai-quantum tensor-engine member / member · tensor engine absent (linux-arm64) (pull_request) Successful in 17s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 14m51s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 42m2s
4523e604a1
The reader refused loops, so a family of circuits (a GHZ state on n qubits,
the QFT, an adder) had to be written out once per size. It now reads
generators, the first piece of the specification-and-evaluator workbench,
whose proposers evolve exactly such programs and whose evaluator checks
them across n.

- qasm::parse_with and qasm::parse_lines_with read a program at given
  integer inputs; qasm::inputs lists the inputs it declares. `input int`,
  `input uint`, `const int|uint`, and `for` over [a:b], [a:step:b] (both ends
  included) and {a, b, c}, nested, are unrolled on reading. Indices and sizes
  take integer arithmetic with C's truncating division, `%`, `**`,
  comparisons and `&& || !`. An `if` on integers alone is decided on reading;
  one on bits stays classical control. Unrolled gates keep the lines of
  their loop's body.
- qasm::instantiate writes the circuit at given inputs out as plain
  OpenQASM, which reads back as the same program, gate for gate.
- Bounded: at most 20 million tokens, checked integer arithmetic, and a
  name an integer would shadow (a register, a gate's parameter or qubit, a
  word of the language) is refused with its line. A loop variable may still
  share a gate's name, such as the identity `i`, since an integer is only
  substituted where it is not starting a statement.
- The lexer reads `% < > <= >= && ||`.
- The CLI takes `--input NAME=VALUE` on every command, and `instance`
  prints a generator written out.

A program with no input, const or for reads exactly as before: the
unrolling pass returns its tokens untouched.

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!466
No description provided.