Skip to content

Qiskit C++ Issue #146: Parameter-Aware OpenQASM 3 Export#155

Open
GoiBasia wants to merge 5 commits into
Qiskit:mainfrom
GoiBasia:main
Open

Qiskit C++ Issue #146: Parameter-Aware OpenQASM 3 Export#155
GoiBasia wants to merge 5 commits into
Qiskit:mainfrom
GoiBasia:main

Conversation

@GoiBasia
Copy link
Copy Markdown

@GoiBasia GoiBasia commented Jun 6, 2026

Summary

The final implementation follows the full long-term plan of C API symbol-enumeration: instead of relying on fragile wrapper-side parsing to recover parameter names, it adds a C API symbol-enumeration hook in Qiskit and uses that from qiskit-cpp. Please take into consideration that pure qiskit-cpp-only fix without Qiskit changes is possible, but only by using C++ wrapper-side parameter tracking, and it is less robust for circuits reconstructed from C API state.

On the qiskit-cpp side, src/qasm3/qasm3_exporter.hpp now owns the exporter. The default qasm3::dumps(circuit) path asks the C API for the number of free symbols, enumerates their names with qk_circuit_param_symbol_name(...), and emits declarations such as:

input float[64] theta;

Those declarations are written after:

OPENQASM 3.0;
include "stdgates.inc";

and before qubit, bit, and operation lines. Gate parameters themselves are still serialized with qk_param_str(), so numeric parameters, symbolic parameters, and expressions keep the C API's existing formatting behavior.

The explicit API:

Qiskit::qasm3::dumps(circuit, {"theta", "phi"});

is also supported. It validates that the caller-provided names match the circuit's free-parameter count and rejects empty or duplicate names.

On the Qiskit C API side, the fix adds:

char *qk_circuit_param_symbol_name(const QkCircuit *circuit, size_t index);

This complements the existing qk_circuit_num_param_symbols(...). The new function returns an owned C string that must be freed with qk_str_free, and returns NULL when the index is out of range. Internally it uses CircuitData::parameters(), giving qiskit-cpp the same canonical deterministic parameter order that Qiskit already tracks in the Rust circuit data.

Details and comments

The qiskit-cpp tests cover the expected exporter behavior:

  • non-parameterized QASM output remains valid
  • single symbolic parameter declarations
  • multiple parameter declarations in canonical order
  • parameter expressions such as theta + phi
  • numeric-only parameters with no input declarations
  • uppercase U(...) emission
  • qasm3::dumps(circuit, names) explicit-name export
  • wrong parameter count, empty name, and duplicate name validation
  • compatibility through QuantumCircuit::to_qasm3()
  • parameterized compose(...)
  • append(src[0]) after indexing a parameterized source circuit

The Qiskit C API tests cover the new symbol-name accessor directly:

  • symbol count plus names for ordinary parameterized circuits
  • expression parameters
  • numeric-only parameters
  • out-of-range index returning NULL

A parameterized circuit can now export self-contained OpenQASM 3:

OPENQASM 3.0;
include "stdgates.inc";
input float[64] theta;
qubit[1] q;
bit[1] c;
rx(theta) q[0];

Verification recorded for the final fix:

qiskit-cpp verification:

cmake -S test -B test/build
cmake --build test/build

DYLD_LIBRARY_PATH=/usr/local/anaconda3/lib:/opt/anaconda3/lib \
  ctest -V -C Debug --test-dir test/build
git diff --check

Qiskit C API verification, from qiskit:

cargo fmt -p qiskit-cext -p qiskit-cext-vtable
make cheader
make clib
DYLD_LIBRARY_PATH=/usr/local/anaconda3/lib:/opt/anaconda3/lib ctest -V -C Debug --test-dir test/c/build-release
git diff --check

The qiskit-cpp suite passed 3/3 and the C API suite passed 27/27.

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

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.

2 participants