Circuit Translation¶
quantum-bench translate converts supported circuit descriptions through the package's neutral InternalCircuit model. It is intended for circuit portability, not arbitrary Python program migration.
Supported Inputs¶
openqasm: the OpenQASM 2/3 subset emitted by this projectinternal-json: the project's neutral circuit JSON formatqiskit: staticQuantumCircuitconstruction snippetscirq: staticcirq.Circuitsnippets using line qubitspennylane: static QNode-style operation snippetsbraket: staticbraket.circuits.Circuitsnippets
Use --from-format auto for basic detection, or set --from-format explicitly for predictable CI behavior.
Supported Outputs¶
SDK outputs are limited to free local Python SDK APIs for now:
cirqqiskit_aercircuit source using QiskitQuantumCircuitpennylanebraket_local
Neutral outputs are also available:
internal-jsonopenqasm
The JSON neutral formats are versioned in docs/SCHEMA.md: internal-circuit, pauli-json, workflow-json, and result-json currently use schema_version: "0.1".
Examples¶
Translate OpenQASM to Cirq:
quantum-bench translate artifacts/ghz.qasm \
--from-format openqasm \
--to-format cirq \
--output artifacts/ghz_cirq.py
Translate a static Qiskit snippet to PennyLane and verify exact probabilities:
quantum-bench translate examples/qiskit_circuit.py \
--from-format qiskit \
--to-format pennylane \
--verify exact \
--output artifacts/circuit_pennylane.py
Use sample-based verification when an exact comparison is too strict for the workflow:
quantum-bench translate examples/braket_circuit.py \
--from-format braket \
--to-format qiskit_aer \
--verify samples \
--sample-shots 4096 \
--verify-tolerance 0.02
Inspect a source file before writing translated output and save a CI-readable report:
quantum-bench translate-check examples/translation/qiskit_registers.py \
--from-format qiskit \
--save-report artifacts/translation_check.json
quantum-bench translate-check examples/translation/qiskit_registers.py \
--from-format qiskit \
--json
quantum-bench translate-check examples/translation/qiskit_registers.py \
--from-format qiskit \
--to-format cirq \
--explain
quantum-bench translate-check examples/translation/qiskit_registers.py \
--from-format qiskit \
--to-format cirq \
--save-markdown artifacts/translation_check.md
Semantic Contract and Migration Audit¶
Translation commands are lossless only within the declared neutral semantic subset. Saved reports include a semantic_contract object that lists preserved semantics, syntax rewrites, rejected constructs, behavior that is not modeled, verification modes, and the free local SDK target scope. This makes the translation promise explicit for CI and migration reviews.
translate-check --to-format ... --explain adds a target-aware migration_audit for circuit sources. It reports the supported source/target status, gate inventory, preserved circuit semantics, SDK syntax rewrites, constructs that would be rejected if present, behavior outside the model, and the recommended verification mode. This is a preflight audit; it does not broaden the supported subset or attempt approximate Python program migration.
Save a translation report containing diagnostics and verification metrics:
quantum-bench translate examples/translation/ghz.qasm \
--from-format openqasm \
--to-format cirq \
--verify exact \
--save-report artifacts/translation_report.json
Translate one source to all selected local SDK targets, neutral internal-json, per-target reports, a combined JSON report, and a compact Markdown summary:
quantum-bench translate-all examples/translation/qiskit_registers.py \
--from-format qiskit \
--output-dir artifacts/qiskit_registers_all
quantum-bench translate-all examples/translation/qiskit_registers.py \
--from-format qiskit \
--targets cirq qiskit_aer \
--output-dir artifacts/qiskit_registers_subset \
--fail-on-verification
Emit a runnable local script as well as circuit construction code:
quantum-bench translate examples/translation/ghz.qasm \
--from-format openqasm \
--to-format cirq \
--include-runner \
--runner-shots 1024 \
--output artifacts/ghz_cirq_runner.py
Tutorial Notebook¶
notebooks/05_circuit_translation_workflow.ipynb provides the end-to-end local workflow: import one static Qiskit circuit, preflight it, draw SDK-native diagrams for Qiskit Aer, Cirq, PennyLane, and Braket LocalSimulator, translate to all four local SDK targets, verify exact probabilities, save per-target source artifacts and a combined report, emit a runnable Cirq script, and inspect unsupported diagnostics.
Observable and Hamiltonian Translation¶
translate-hamiltonian extends SDK translation beyond circuits for the first safe semantic layer: weighted sums of Pauli I, X, Y, and Z products. Observables are represented as the single-term case of the same neutral model.
Supported inputs:
pauli-json: neutral weighted Pauli termsqiskit: staticSparsePauliOp.from_list(...)snippetscirq: static sums ofcirq.X/Y/Z(qubits[i])productspennylane: staticqml.Hamiltonian([...], [...])snippetsbraket: statichamiltonian_terms = [(coefficient, Observable..., targets)]snippets
Supported outputs:
qiskit_aer: QiskitSparsePauliOpcirq: Cirq Pauli-string expressionpennylane: PennyLaneqml.Hamiltonianbraket_local: Braket observable terms with explicit targetspauli-json: neutral JSON
Examples:
quantum-bench translate-hamiltonian examples/translation/ising_hamiltonian.json \
--from-format pauli-json \
--to-format pennylane \
--output artifacts/ising_pennylane.py \
--save-report artifacts/ising_translation_report.json
quantum-bench translate-hamiltonian examples/translation/ising_hamiltonian.json \
--from-format pauli-json \
--to-format qiskit_aer
quantum-bench translation-audit
quantum-bench translation-audit --from-format qiskit --to-format qiskit_aer --json
Verification supports two modes. canonical reimports generated SDK source and compares neutral qubit-indexed Pauli terms. matrix additionally compares dense matrices for small Hamiltonians up to 6 qubits, which is useful for stronger confidence during SDK migration. Non-Pauli operator algebra and symbolic coefficients remain future work. Neutral circuit-level noise annotations cover portable local channel syntax; provider-calibrated noise semantics remain outside the model.
Workflow-Level Translation¶
translate-workflow covers the next semantic layer around circuits. It accepts neutral workflow-json plus a first-pass static subset of Qiskit, Cirq, PennyLane, and Braket parameterized workflow snippets, then emits free local SDK Python for Qiskit Aer, Cirq, PennyLane, or Braket LocalSimulator. The workflow JSON can include:
- parameterized circuits using
H,X,Y,Z,RX,RY,RZ, andCNOT/CX - symbolic parameter names, arithmetic parameter expressions over declared parameters, and numeric parameter bindings
- counts, samples, probabilities, and Pauli expectation requests
- local shot-count execution wrappers and result extraction snippets
Example:
quantum-bench translate-workflow examples/translation/parameterized_workflow.json \
--to-format qiskit_aer \
--verify semantic \
--verify-tolerance 1e-9 \
--expectation-tolerance 1e-9 \
--output artifacts/parameterized_workflow_qiskit.py
Generated workflow scripts define a schema-versioned neutral_result and print actual normalized counts, shots, probabilities, Pauli expectations, and metadata. They also embed workflow_spec, which lets the verifier reimport generated snippets for canonical or exact neutral semantic comparison. --verify semantic reports measurement-distribution TVD, maximum expectation-value absolute error, and result-schema validity without requiring the target SDK to be installed. Golden workflow outputs live in examples/translation/expected/parameterized_workflow_to_*.py.
The portable result contract represents one distribution target set per workflow. Requests for multiple distinct distribution target sets, execution workflows without a result request, and explicit measurements without a distribution request fail with structured diagnostics instead of producing incomplete result JSON. translate-result also checks field types, shot totals, probability normalization, count/probability consistency, and finite expectation values.
translate-result normalizes SDK-shaped result JSON into the same portable result object with counts, shots, probabilities, optional expectations, and metadata:
quantum-bench translate-result examples/translation/qiskit_counts_result.json \
--from-format qiskit-counts-json \
--output artifacts/neutral_result.json
quantum-bench translate-result examples/translation/pennylane_samples_result.json \
--from-format pennylane-samples-json
group-pauli-terms groups weighted Pauli Hamiltonian terms into qubit-wise commuting measurement sets:
quantum-bench group-pauli-terms examples/translation/ising_hamiltonian.json \
--from-format pauli-json \
--output artifacts/ising_measurement_groups.json
This is intentionally not arbitrary Python migration. Static SDK workflow imports currently cover generated snippets and common local patterns such as Qiskit Parameter, Cirq sympy.Symbol, PennyLane QNode arguments/device shots, PennyLane qml.expval(...) over static Pauli products, Braket FreeParameter, and Braket circuit.expectation(...) Pauli result types. Broader user-authored Python migration remains future work; workflow-json is still the most precise migration contract for parameterized execution workflows.
Supported Gates and Annotations¶
The supported gate and annotation set matches the existing internal circuit model:
- Single-qubit gates:
H,X,Y,Z,S,T,SX, phase/P, andU - Rotations:
RX,RY,RZwith static numeric parameters - Two-qubit gates:
CNOT,CZ,SWAP - Three-qubit and controlled gates:
CCX,CRX,CRY,CRZ, andCPHASE - Measurements over static integer wires, with measurement-key and bit-order metadata where importers can preserve it
- Preservable neutral
RESET,BARRIER, andDELAYannotations. Qiskit emits these with native syntax; Cirq emits reset natively; PennyLane emits barrier natively; other unsupported annotation/target pairs are represented as explicit neutral comments with structured warnings. - Optional neutral local noise-channel annotations for depolarizing, bit-flip, phase-flip, amplitude-damping, and readout-error requests
Static Python Support¶
The Python snippet importers support static circuit construction only. They can resolve:
- numeric constants such as
theta = 0.25 - integer constants such as
n = 3 - simple loops such as
for i in range(n): circuit.h(i) - static wire lists such as
[0, 1]
Unsupported constructs produce structured diagnostics and fail instead of rewriting approximately. Unsupported examples include dynamic parameters from function calls, nonliteral wire expressions, custom gates, classical control, provider runtime calls, transpiler settings, and arbitrary result-processing code.
Reports¶
--save-report writes JSON for translate, translate-check, Hamiltonian, workflow, result, and grouping commands. Reports include detected formats, schema_metadata for neutral input/output formats, semantic_contract details, diagnostics, gate inventory for checks, verification total variation distance, canonical match, statevector distance, workflow expectation error, and result-schema validity where applicable. translate-check reports also include migration_audit guidance and can write a compact Markdown review with --save-markdown. translate-all writes per-target reports, a combined JSON report, neutral internal-json, selected target source files, and a Markdown summary. These reports are intended for CI and migration audits.
Verification¶
--verify exact reimports the generated circuit source and compares exact measurement probabilities with total variation distance.
--verify samples samples both neutral distributions with a deterministic local sampler and compares the sampled distributions. Use --sample-shots and --verify-tolerance to tune this check.
--verify canonical compares the reimported neutral operation timeline, measurement targets, global phase, and neutral noise annotations. It is stricter than probability checks and is useful when target syntax should preserve reset/barrier/delay annotations.
--verify statevector compares small noiseless final statevectors up to global phase. It rejects noisy annotations and reset because those are not unitary statevector semantics.
For translate-workflow, --verify canonical compares the reimported workflow structure, while --verify semantic evaluates the original and generated workflow specs with the neutral simulator. Semantic mode reports distribution TVD, expectation-value maximum absolute error, and result-schema validity; tune its thresholds with --verify-tolerance and --expectation-tolerance.
A failed verification exits with status 1. The translated source is still produced so users can inspect it, but the command reports the failed semantic check.
Caveats¶
Translation reports include warning diagnostics for backend-specific behavior that users should review: measurement bit ordering, Braket probability targets versus measurement counts, PennyLane QNode sampling, and controlled-phase conventions. Exact verification compares neutral measurement probabilities and is the recommended guardrail for these caveats.
Golden Outputs¶
quantum-bench translation-audit --json emits the current SDK translation coverage matrix, including neutral schema version, supported gates, parameter forms, measurements, Hamiltonian terms, result shapes, diagnostics, caveats, and verification modes per local SDK target. quantum-bench roundtrip-audit --verify canonical can use the stricter circuit-structure verifier for neutral-to-SDK-to-neutral checks.
Expected generated outputs for selected fixtures live in examples/translation/expected/. Regenerate them intentionally after codegen changes:
python examples/translation/update_expected.py
Check that committed expected outputs are current:
python examples/translation/update_expected.py --check
Hamiltonian golden outputs live alongside circuit golden outputs in examples/translation/expected/. The maintenance scripts cover both circuit and Hamiltonian examples:
python examples/translation/verify_examples.py
python examples/translation/update_expected.py --check
python scripts/check_translation_artifacts.py