qac-l-cloud / src /lowering.py
IHat0's picture
Upload folder using huggingface_hub
2db2be1 verified
Raw
History Blame Contribute Delete
2.24 kB
"""
lowering.py — spec → OpenQASM 3.
The "lowering pass" from the architecture diagram. For the four circuit-builder
actions (RANDOM, BELL, GROVER, QAOA) we build the circuit via `circuits.py` and
emit OpenQASM 3. VQE is a variational procedure (many circuits), so it lowers to
a description of its ansatz circuit rather than a single shot program.
OpenQASM 3 emission uses the `openqasm3` package if available; otherwise we
fall back to Qiskit's built-in QASM2 exporter so the pipeline never hard-fails
on a missing optional dependency (useful in minimal local test envs).
"""
from __future__ import annotations
from qiskit import QuantumCircuit
from .spec import QuantumSpec
from . import circuits
def _emit(qc: QuantumCircuit) -> str:
"""
Emit a QuantumCircuit as OpenQASM 3, falling back to QASM 2.
Exporter preference, most-expressive first:
1. `openqasm3.dumps` — true OpenQASM 3 (the architecture's target).
2. `qiskit.qasm2.dumps` — Qiskit 2.x's stable QASM2 exporter.
3. legacy `QuantumCircuit.qasm()` — older Qiskit versions only.
The pipeline must never hard-fail on a missing exporter.
"""
try:
import openqasm3 # noqa: WPS433
return openqasm3.dumps(qc)
except ImportError:
pass
try:
from qiskit import qasm2 # Qiskit 2.x
return qasm2.dumps(qc)
except Exception:
pass
fn = getattr(qc, "qasm", None) # legacy, pre-2.0
if callable(fn):
return fn()
raise RuntimeError("No QASM exporter available on this Qiskit version.")
def lower(spec: QuantumSpec) -> tuple[str, QuantumCircuit]:
"""
Lower a validated spec to (qasm_source, circuit).
Returns a 2-tuple so the caller gets the OpenQASM text for the receipt /
UI without re-exporting, and the live circuit object for execution.
"""
if spec.action == "VQE":
# VQE is variational; emit the ansatz template at θ=0 as the canonical
# representative. The engine re-parameterises it during optimisation.
qc = circuits.vqe_ansatz(0.0)
qasm = _emit(qc)
return qasm, qc
builder = circuits.BUILDERS[spec.action]
qc = builder(spec)
qasm = _emit(qc)
return qasm, qc