Skip to content

Add OpenQASM 3 circuit input via from_qasm (#14)#30

Closed
mk0dz wants to merge 1 commit into
harmoniqs:mainfrom
mk0dz:feat/14-openqasm3-input
Closed

Add OpenQASM 3 circuit input via from_qasm (#14)#30
mk0dz wants to merge 1 commit into
harmoniqs:mainfrom
mk0dz:feat/14-openqasm3-input

Conversation

@mk0dz

@mk0dz mk0dz commented Jun 17, 2026

Copy link
Copy Markdown

Closes #14

What was built

from_qasm(qasm::String) -> GateCircuit in src/qasm.jl, plus the include +
export from_qasm in src/Stretto.jl.

Coverage (vs #24's 9 discrete gates):

  • Discrete: id, x, y, z, h, s, sdg, t, tdg, sx, cx/cnot, cz, swap, ccx/toffoli, ccz
  • Parametric: rx(θ), ry(θ), rz(θ), p/phase/u1(θ), cp/cphase(θ), crz(θ), u/u3(θ,φ,λ)
  • Registers: qubit[N] q; (QASM3) and qreg q[N]; (QASM2); 0→1 based index conversion
  • Headers (OPENQASM, include), // and /* */ comments, barrier, gphase ignored
  • Unsupported (measure/reset/classical/control-flow/custom-gates/multi-register) → ArgumentError

Idiomatic to Stretto: parametric gates register a unique symbol + matrix in
EXTRA_GATES and emit GateOp(sym, qubits) — exactly how library.jl's
qft_circuit handles cp_gate. So circuit_unitary resolves them with no core
changes.

Security/quality note: angle expressions (pi/2, 3*pi/4, tau, -0.5) are
evaluated by a small hand-written recursive-descent arithmetic parser — no
eval
, so untrusted QASM can never execute code. (Replaced an initial
whitelisted-eval version after a security lint flagged it; the parser is both
safer and cleaner for a library.)

Validation

8 @testitem blocks, 17 assertions, all pass, each checking correctness by
round-tripping through circuit_unitary (the issue's acceptance criterion):

  • qubit count + 0→1 index conversion (both register syntaxes)
  • discrete round-trip (bell) and Toffoli vs toffoli_circuit()
  • parametric rx/ry/rz/p vs their matrix definitions; two-qubit cp vs diag(1,1,1,e^{iθ})
  • angle arithmetic (3*pi/4-pi/2 + 5*pi/4; tau2*pi)
  • comments/barriers ignored
  • 5 error cases (measure, unknown gate, out-of-range index, 2 registers, no declaration)

Package loads cleanly (the change is additive: one new file + include/export),
so the existing suite cannot regress from it.

Files changed (PR contents)

 src/qasm.jl       (new: parser + 8 @testitem tests)
 src/Stretto.jl    (+2: include("qasm.jl"); export from_qasm)

AI Acknowledgement: I would like to thanks claude sonnet 4.6 to make me understand the codebase and structure of Stretto

from_qasm parses a static subset of OpenQASM 3 into a GateCircuit: discrete
gates plus parametric rx/ry/rz/p/cp/crz/u (registered through the existing
EXTRA_GATES mechanism, like qft_circuit's cp_gate), both qubit[N]/qreg register
syntaxes, 0->1 based index conversion, comments/barriers ignored, and
ArgumentError on unsupported constructs. Angle expressions are parsed by a small
recursive-descent evaluator (no eval). Includes 8 @testitem round-trip tests
validated against circuit_unitary.
@mk0dz mk0dz marked this pull request as draft June 17, 2026 03:29
@jack-champagne

Copy link
Copy Markdown
Member

We have many quality submissions and it was a tough decision, but there is still so much work to do on this package and we encourage everyone who made a submission to continue contributing and making suggestions, PRs, and issues on this repo. Thank you all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add OpenQASM 3 circuit input (from_qasm)

2 participants