Chapter 18 — Key Takeaways (Framework Comparison and Interoperability)
Part III's synthesis. §18.6's accounting — 90% of Parts I–II transfers — is the one to keep.
The same Bell state, five ways
framework lines what the syntax makes you say
Braket 1 almost nothing -- the shortest path to a circuit
Qiskit 3 how many classical bits, and which measurement goes where
Cirq 3 which qubit objects, and (implicitly) the moment structure
PennyLane 4 what you want MEASURED, as a return value
Q# 6 the type, the qubit lifetime, and the cleanup
None of it is verbosity for its own sake. Q#'s ResetAll exists because §15.5's runtime checks
it; PennyLane's return is what gets differentiated; Qiskit's classical register is what Chapter 9's
dynamic circuits need.
Five result formats for one physical outcome:
Qiskit {'11': 490, '00': 510}
Cirq {0: 503, 3: 497} <- INTEGER keys
Braket {'00': 489, '11': 511}
PennyLane {'00': 502.0, '11': 498.0}
Q# {'(Zero, Zero)': 527, '(One, One)': 473}
★ The endianness table
X on qubit 0 of a two-qubit register:
| Framework | Convention | Index | Measurement |
|---|---|---|---|
| Qiskit | little-endian | 1 | '01' |
| Cirq | big-endian | 2 | 2 |
| Braket | big-endian | 2 | '10' |
Qiskit is the outlier — 1 of 3. Parts I–II present little-endian ordering as a fact about quantum computing for thirteen chapters. It is a fact about Qiskit.
Neither convention is wrong. Little-endian makes $|q_1q_0\rangle$ read like a binary number ($q_0$ least significant) — convenient for arithmetic circuits (Ch. 22 QFT, Ch. 23 modular arithmetic). Big-endian makes the index read in the order you listed the qubits — convenient for diagrams. Neither will change. Convert at exactly one boundary.
Who speaks OpenQASM
| Framework | Exports | Imports | Note |
|---|---|---|---|
| Qiskit | QASM 2 + 3 | QASM 2 + 3 | native, both directions |
| Cirq | QASM 2 | QASM 2 | import is in cirq.contrib, needs pip install ply |
| Braket | QASM 3 | QASM 3 | OpenQASM 3 is Braket's native IR |
| PennyLane | qml.to_openqasm |
qml.from_qasm |
plus native plugins |
| Q# / QDK | qdk.openqasm.compile |
qdk.openqasm.circuit |
full module |
All five, both directions — a genuine standard.
★★ What QASM transfers, and what it does not
Transfers: gate identity, qubit indices, parameters, ordering. cx q[0],q[1] is unambiguous
anywhere.
Does NOT transfer — measured, Qiskit → QASM 2 → Cirq on an asymmetric state:
qiskit : [0, 0.7071, 0, 0.7071]
cirq (via qasm) : [0, 0, 0.7071, 0.7071]
match WITHOUT reversal : False
match WITH reversal : True
QASM names qubits explicitly, so the program moves correctly — but where qubit 0 sits in a state vector is a per-framework decision QASM has no opinion about.
A STANDARD INTERCHANGE FORMAT DOES NOT REMOVE THE BOUNDARY. IT DEFINES WHAT IS LEFT AT IT.
Also dropped (both re-confirming Chapter 6):
global phase 1.047198 -> 0.000000 LOST
parameters ['theta[0]','theta[1]'] -> ['_theta_0_','_theta_1_'] MANGLED
Global phase loss is not cosmetic: it becomes a relative phase when the circuit is controlled —
Chapter 6 watched it invert an answer ({'1':1757} → {'0':1758}) while passing every equivalence
test. Parameter mangling: note the leading underscore; normalize both sides rather than
reproducing the rule.
The three responsibilities of a pipeline
qasm = qasm2.dumps(circuit) # 1. QASM does this right
counts = cirq_histogram_to_qiskit_counts(hist, n) # 2. ONE boundary
assert_same_state(qiskit_circuit, cirq_circuit) # 3. ASYMMETRIC state
Step 3 is the one people skip — Bell and GHZ states are symmetric under bit reversal and prove nothing (Ch. 14 CS1).
Choosing — by capability, not preference
| Task | Framework |
|---|---|
| Learning · IBM hardware · device-accurate noise · full compiler | Qiskit |
| Explicit timing · grid topologies | Cirq |
| Resource estimation · large long-lived codebases | Q# |
| Variational / QML · autodiff integration | PennyLane |
| Non-superconducting hardware · verbatim control | Braket |
Only three genuine capability gaps: hardware access (Qiskit's open tier), resource estimation (Q#, uniquely), differentiability (PennyLane, by design). Everything else is ergonomics.
"A or B" is often a false choice.
pennylane-qiskitdifferentiates circuits that execute on IBM hardware; Q#'s estimator consumes logical counts from any framework (Ch. 15 §15.9); Braket's native QASM 3 makes it a translation hub.
★★★ What actually transfers (§18.6)
Framework-specific (~10%): API names · little-endian ordering · the primitives architecture ·
optimization_level · NoiseModel.from_backend.
Framework-independent (~90%):
- The physics. A Bell state is a Bell state.
- The noise signatures. Chapter 11 §11.7's two-axis table reproduced identically in Aer, Cirq, and Braket. Phase damping invisible in all three — a fact about measurement, not software.
- The diagnostic procedures. Chapter 12 §12.7's noise-or-bug tree works anywhere.
- The cost models. 2q gates dominate error · depth is the enemy · T gates dominate fault-tolerant cost · a gradient costs $2n+1$ · connectivity overhead is graph embedding.
- The habits. Independent reference value · asymmetric test case · check the condition number · assert on structure · report the stack.
- The epistemics: a number can be precise, reproducible, and about something other than what you think — Ch. 11, 12, 13, 14, 15, 16, 17. Seven chapters, one lesson, none of it about Qiskit.
🔬 How much does framework choice matter?
Less than this Part's length suggests. Ranked by measured impact:
| Decision | Impact | Chapter |
|---|---|---|
| Which qubits on a device | ~100× | 12 |
| Ansatz + optimizer | converged vs. stalled | 16 |
| Modality for the circuit shape | 3.18× | 17 |
| Mitigation stack + ordering | 79% (4.5× between orderings) | 13 |
| Which framework | ergonomics + 3 capability gaps | 14–18 |
Framework choice is last, and it is not close.
Common pitfalls
- Believing a standard interchange format removes the endianness boundary.
- Verifying a translation with a Bell or GHZ state.
- Using
Operator.equiv()to check a circuit you will control (it ignores global phase by design). - Scattering bit reversals instead of converting once.
- Forgetting Cirq's QASM importer needs
ply. - Spending on the framework decision what belongs on layout, ansatz, modality, and mitigation.
Project piece added this chapter
vqelab/interop.py — reverse_bits / reverse_state_vector / needs_reversal, to_qasm and
from_qasm (raising a clear error for Cirq's missing ply rather than letting
ModuleNotFoundError surface from deep in a pipeline), TranslationReport which is returned
rather than logged and names the consequence of each loss, and verify_translation which refuses
a symmetric test case. 17 tests pass, including
test_verify_translation_REFUSES_a_symmetric_test_case and
test_qiskit_is_the_endianness_outlier.