Skip to content

Add OpenQASM 3 circuit input (from_qasm) #14

Description

@kateebonner

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:

  1. Parses an OpenQASM 3 string and extracts gate operations and qubit count
  2. 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)
  3. Converts 0-based QASM qubit indices to Stretto's 1-based indexing (e.g. q[0] → qubit 1, q[1] → qubit 2)
  4. 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.jlGateCircuit, GateOp, resolve_gate, and the full gate symbol table
  • src/compile.jlcompile_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

Metadata

Metadata

Assignees

Labels

unitaryHACKunitaryHACK 2026 bounty

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions