Exercises: Framework Comparison and Interoperability

These need several frameworks installed: pip install qiskit qiskit-aer cirq ply pennylane amazon-braket-sdk qdk. The ply package is required for Cirq's OpenQASM importer (§18.3). Solutions to starred exercises are in Answers to Selected Exercises.


Warm-up

18.1 ★ Write the same Bell state in all five frameworks and run each for 1000 shots. Present the five result formats side by side. Which uses integer keys? Which reports tuples?

18.2 Count the lines each framework needs. Then, for each, name one thing the syntax forces you to state and explain what that requirement is for.

18.3 ★ Run Chapter 14's one-gate endianness test in Qiskit, Cirq, and Braket. Reproduce §18.2's table. Which framework is the outlier?

18.4 Explain, in two sentences each, why little-endian is convenient for arithmetic circuits and why big-endian is convenient for reading circuit diagrams.


OpenQASM interoperability

18.5 ★ Export a 3-qubit circuit from Qiskit as OpenQASM 2 and read it back. Confirm count_ops() is unchanged.

18.6 ★ Export the same circuit and import it into Cirq. What happens if ply is not installed? Write the error message you get, and the error message a good pipeline should produce instead.

18.7 ★★ Round-trip an asymmetric circuit (X on qubit 0, H on qubit 1) from Qiskit through QASM 2 into Cirq. Compare state vectors with and without bit reversal. Which matches?

18.8 ★★ Repeat 18.7 with a Bell state. Does the comparison distinguish the two conventions? Explain what that tells you about using Bell states to verify a translation.

18.9 ★★ Set a nonzero global_phase on a Qiskit circuit, round-trip it through QASM 2, and report the phase before and after. Then build a controlled version of both and show that their measurement outcomes differ.

18.10 ★★ Create a ParameterVector("theta", 3) circuit and export it to QASM 3. Report the exact parameter names in the output. Write a normalize_name() function that maps both forms to a common key, and test it round-trips.

18.11 ★★★ Build a full pipeline: Qiskit circuit → QASM → Cirq → execute → results converted back to Qiskit-style bitstrings. Verify it end to end with an asymmetric circuit. How many places in your pipeline touch bit order? Reduce it to one.

18.12 ★★★ Braket's native IR is OpenQASM 3. Use that to route a circuit Qiskit → QASM 3 → Braket, run it, and convert the results back. Does routing through Braket lose anything Cirq's path does not?


What survives

18.13 ★ Reproduce Chapter 11 §11.7's noise signature table in two frameworks (Aer and Braket). Confirm the error fractions and imbalances agree qualitatively.

18.14 ★★ Take Chapter 12 §12.7's noise-or-bug decision procedure and rewrite each step in framework-neutral terms. Which steps, if any, cannot be expressed without naming a specific framework?

18.15 ★★ For each of these, decide whether it is framework-specific or framework-independent, and justify: (a) optimization_level=3; (b) "two-qubit gates dominate the error budget"; (c) SamplerV2; (d) "a gradient costs $2n+1$ circuit executions"; (e) little-endian ordering; (f) "phase damping is invisible in the computational basis."

18.16 ★★★ §18.6 claims roughly 90% of Parts I–II is framework-independent. Test the claim: go through Chapters 10–13's section headings and classify each as specific or independent. Report your percentage and where you disagree with the chapter's estimate.


Choosing

18.17 ★ For each scenario, name a framework and give a one-sentence reason: (a) a first quantum program; (b) estimating whether an algorithm needs a million qubits; (c) training a quantum classifier with PyTorch; (d) running on trapped ions; (e) an experiment where gate timing is the variable.

18.18 ★★ Case Study 2 ranks five decisions by measured impact. Reconstruct the ranking from the chapters cited, and for each give the specific measurement that establishes it.

18.19 ★★ Design a decision procedure for framework selection that takes at most one afternoon. It should ask no more than four questions. Test it against the five scenarios in 18.17.

18.20 ★★★ Use pennylane-qiskit to run a PennyLane QNode on a Qiskit fake backend. Confirm the gradient still works. What does this demonstrate about "PennyLane or Qiskit" as a framing?


Project

18.21 ★★ (Project Checkpoint) Build vqelab/interop.py with reverse_bits, reverse_state_vector, needs_reversal, to_qasm, from_qasm, a TranslationReport, and verify_translation. Write tests asserting:

  1. Qiskit is the only little-endian entry in the endianness table.
  2. reverse_bits is its own inverse for $n \leq 4$.
  3. A QASM round trip preserves count_ops().
  4. A nonzero global phase is reported as dropped, with a warning naming the consequence.
  5. A zero global phase produces no such warning.
  6. Parameter mangling is detected for ParameterVector names.
  7. An endianness difference is always reported.
  8. A same-endianness target reports is_lossless.
  9. Bell and GHZ states are detected as symmetric under bit reversal.
  10. X on qubit 0 is detected as asymmetric.
  11. verify_translation raises when handed a symmetric test case.
  12. It accepts a correctly-converted asymmetric translation and rejects an unconverted one.
  13. An unsupported import target raises a clear TranslationError, not ModuleNotFoundError.

Test 11 encodes Chapter 14's Case Study 1 so it cannot be forgotten; test 4 encodes this chapter's.

18.22 ★★★ Extend interop.py with round_trip_report(circuit, target) that performs a full out-and-back translation and returns a diff: gates added or removed, phase drift, parameter renames, and whether the final state matches after conversion. Run it on ten randomly generated circuits and report which properties survive.


Going further

18.23 ★★★ OpenQASM 3 supports classical control flow, which OpenQASM 2 does not. Take Chapter 9's dynamic circuit (mid-circuit measurement with feed-forward) and attempt to serialize it in both versions. What happens in each case, and what does that imply for translation pipelines that target QASM 2?

18.24 ★★★ Write a FrameworkAdapter protocol with methods build_bell(), run(shots), and counts_as_qiskit_bitstrings(), and implement it for three frameworks. What is the smallest interface that lets the rest of your code be framework-agnostic — and which of §18.6's "does not transfer" items does your abstraction hide? (Compare your answer to Chapter 17's Case Study 2.)

18.25 ★★★ Chapter 6 introduced QPY as Qiskit's native serialization format, which does preserve global phase and parameter names. Compare QPY and OpenQASM on: fidelity of round trip, cross-framework portability, and human readability. When is each the right choice?