Preamble
This issue is part of unitaryHACK26. You have to be registered to complete this issue. Learn more about the Pull Request process here and about unitaryHACK rules here! A note about AI Slop: while we are open to collaboration with LLMs for unitaryHACK, fully AI-generated PRs are not acceptable. It is at the maintainers' discretion whether or not LLM-generated PRs are the right fit for the issues, and those that appear fully AI-generated may be immediately rejected. Read unitaryHACK's full AI Policy here.
Background
Stretto currently only accepts circuits defined using its own GateCircuit type. This means users who define circuits in Qiskit, Cirq, PyTKET, or any other framework have no way to feed them into Stretto without manually translating each gate to a GateOp.
OpenQASM 3 is the lingua franca of quantum circuits — every major framework can export to it. Adding an OpenQASM → GateCircuit parser as a single entry point would make Stretto accessible to the entire quantum software ecosystem, including UCC users.
Minimal Reproducible Example
Today, using a circuit from any external framework requires manual translation:
using Stretto
# ❌ No way to import from Qiskit, Cirq, UCC, etc. — must build manually
circuit = GateCircuit([
GateOp(:H, (1,)),
GateOp(:CX, (1, 2)),
], 2)
After this issue is resolved, any OpenQASM 3 string (e.g. exported from Qiskit, Cirq, UCC) should work directly:
using Stretto
qasm = """
OPENQASM 3;
qubit[2] q;
h q[0];
cx q[0], q[1];
"""
# ✅ Parse directly into a GateCircuit (note: QASM 0-based indices → Stretto 1-based)
circuit = from_qasm(qasm)
result = compile_block(circuit, HeronR3(), [1, 2])
And from a file:
circuit = from_qasm(read("my_circuit.qasm", String))
What to implement
Add a from_qasm(qasm::String) -> GateCircuit function in a new file src/qasm.jl that:
- Parses an OpenQASM 3 string and extracts gate operations and qubit count
- Maps standard OpenQASM gate names (
h, cx, cz, x, y, z, s, t, ccx) to Stretto's existing GateOp symbols (:H, :CX, :CZ, etc. — see the full gate table in circuits.jl)
- Converts 0-based QASM qubit indices to Stretto's 1-based indexing (e.g.
q[0] → qubit 1, q[1] → qubit 2)
- Returns a
GateCircuit ready to pass to compile_block
The subset of OpenQASM 3 needed to cover Stretto's gate set is small — a minimal hand-written parser for gate statements is a reasonable approach and avoids adding a heavy dependency. Alternatively, OpenQASM.jl exists but has been unmaintained for a while. Quasar.jl remains a good alternative.
Add tests verifying round-trip correctness: parse a known QASM string, compute circuit_unitary, and confirm it matches the expected matrix.
Out of scope
- Parametric gates (e.g.
rz(θ)) — static gates only for now
- OpenQASM 2 support (focus on 3)
- A
to_qasm exporter (separate issue)
- Python interop / PyCall — pure Julia only
- 3+ qubit circuits (the substrate
BilinearIntegrator in compile_block is adequate for 1-2 qubit problems; 3+ qubit support requires the private Strettissimo package)
Why this matters
Right now Stretto is an island — users can't bring circuits from Qiskit, Cirq, UCC, or any other tool without manual translation. OpenQASM 3 support closes that gap in one PR and makes Stretto usable in any existing quantum workflow. It's also a prerequisite for submitting Stretto results to Metriq, which benchmarks compilers against standard circuits defined in QASM.
Getting started
src/circuits.jl — GateCircuit, GateOp, resolve_gate, and the full gate symbol table
src/compile.jl — compile_block which consumes the GateCircuit (1-2 qubits with the substrate integrator)
src/library.jl — existing hand-built circuits to use as test references
- OpenQASM 3 spec — language reference
- UCC docs — example of a framework that can export OpenQASM 3 to feed into this
Preamble
This issue is part of unitaryHACK26. You have to be registered to complete this issue. Learn more about the Pull Request process here and about unitaryHACK rules here! A note about AI Slop: while we are open to collaboration with LLMs for unitaryHACK, fully AI-generated PRs are not acceptable. It is at the maintainers' discretion whether or not LLM-generated PRs are the right fit for the issues, and those that appear fully AI-generated may be immediately rejected. Read unitaryHACK's full AI Policy here.
Background
Stretto currently only accepts circuits defined using its own
GateCircuittype. This means users who define circuits in Qiskit, Cirq, PyTKET, or any other framework have no way to feed them into Stretto without manually translating each gate to aGateOp.OpenQASM 3 is the lingua franca of quantum circuits — every major framework can export to it. Adding an OpenQASM →
GateCircuitparser as a single entry point would make Stretto accessible to the entire quantum software ecosystem, including UCC users.Minimal Reproducible Example
Today, using a circuit from any external framework requires manual translation:
After this issue is resolved, any OpenQASM 3 string (e.g. exported from Qiskit, Cirq, UCC) should work directly:
And from a file:
What to implement
Add a
from_qasm(qasm::String) -> GateCircuitfunction in a new filesrc/qasm.jlthat:h,cx,cz,x,y,z,s,t,ccx) to Stretto's existingGateOpsymbols (:H,:CX,:CZ, etc. — see the full gate table incircuits.jl)q[0]→ qubit1,q[1]→ qubit2)GateCircuitready to pass tocompile_blockThe subset of OpenQASM 3 needed to cover Stretto's gate set is small — a minimal hand-written parser for gate statements is a reasonable approach and avoids adding a heavy dependency. Alternatively, OpenQASM.jl exists but has been unmaintained for a while. Quasar.jl remains a good alternative.
Add tests verifying round-trip correctness: parse a known QASM string, compute
circuit_unitary, and confirm it matches the expected matrix.Out of scope
rz(θ)) — static gates only for nowto_qasmexporter (separate issue)BilinearIntegratorincompile_blockis adequate for 1-2 qubit problems; 3+ qubit support requires the private Strettissimo package)Why this matters
Right now Stretto is an island — users can't bring circuits from Qiskit, Cirq, UCC, or any other tool without manual translation. OpenQASM 3 support closes that gap in one PR and makes Stretto usable in any existing quantum workflow. It's also a prerequisite for submitting Stretto results to Metriq, which benchmarks compilers against standard circuits defined in QASM.
Getting started
src/circuits.jl—GateCircuit,GateOp,resolve_gate, and the full gate symbol tablesrc/compile.jl—compile_blockwhich consumes theGateCircuit(1-2 qubits with the substrate integrator)src/library.jl— existing hand-built circuits to use as test references