Skip to content

Support parameterized circuits in QASM3 export#159

Open
spital wants to merge 1 commit into
Qiskit:mainfrom
spital:qasm3-parameterized-export
Open

Support parameterized circuits in QASM3 export#159
spital wants to merge 1 commit into
Qiskit:mainfrom
spital:qasm3-parameterized-export

Conversation

@spital
Copy link
Copy Markdown

@spital spital commented Jun 7, 2026

Summary

Closes #146.

This moves the OpenQASM 3 export implementation out of QuantumCircuit into a dedicated exporter while keeping the public QuantumCircuit::to_qasm3() API. It also adds support for exporting parameterized circuits by emitting symbolic parameters as OpenQASM 3 input float[64] declarations.

What changed

  • Add a dedicated OpenQASM 3 exporter in src/circuit/qasm3_exporter.hpp and delegate QuantumCircuit::to_qasm3() to it.
  • Harvest symbolic identifiers from circuit parameter expressions and emit them as input float[64] declarations before registers and operations.
  • Allocate emitted input/register names so they avoid OpenQASM keywords, stdgates.inc globals, and custom gate definitions emitted by the exporter.
  • Preserve the existing flattened q register export behavior.
  • Emit valid OpenQASM 3 for controlled-U1, controlled-U3, and non-zero global phase (gphase).
  • Add regression tests for parameterized export, identifier collisions, custom-gate collisions, controlled-U definitions, and global phase.

Known limitations

The current Qiskit C API exposes the number of circuit parameter symbols but not an iterator over their names, so the exporter derives parameter identifiers from the string form returned by qk_param_str(). This supports normal symbolic parameters and expressions, but parameter names should be OpenQASM-identifier-like.

Some expression forms emitted by Qiskit's parameter string representation, such as power expressions (theta**2) or function calls (sin(theta)), are not currently round-trippable through qiskit_qasm3_import. The exporter preserves the expression spelling instead of rewriting it to a form that may change semantics.

Testing

  • make -C test/deps/qiskit c
  • cmake -S test -B /tmp/qisk146-hermes-review60-build
  • cmake --build /tmp/qisk146-hermes-review60-build -j20
  • ctest --test-dir /tmp/qisk146-hermes-review60-build --output-on-failure
  • /tmp/qisk146-hermes-review60-build/test_driver test_circuit
  • git diff --check origin/main...HEAD
  • Parser smoke tests with qiskit 2.4.1 / qiskit-qasm3-import 0.6.0 using qiskit.qasm3.loads() for reserved-name conflicts, keyword/constant-name conflicts, classical-register conflicts, controlled-U definitions, and global phase output.

AI assistance disclosure

I used Codex, Claude, and Hermes as AI assistants to help prototype, review, compare related approaches, and draft PR text. I manually reviewed the resulting diff, checked the live GitHub issue/PR state and unitaryHACK policy, refined the implementation, and ran the tests listed above locally. The PR is submitted with human oversight; any remaining mistakes are mine.

  • I have added the tests to cover my changes.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.

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.

QASM3 exporter with parameterized circuit support

1 participant