Case Study 1: The Algorithm That Did Not Fit
"We counted the gates. We were counting the wrong gates."
Executive Summary
A team plans a six-qubit variational experiment. They count the two-qubit gates in their circuit — thirty, comfortably inside a budget of a hundred — and submit. The results are noise.
The circuit they wrote has thirty CNOTs. The circuit that ran has ninety, because their ansatz entangles every pair and the device connects each qubit to at most three neighbors. The extra sixty are SWAPs, inserted silently, at three CNOTs each.
This case study works through the diagnosis, then fixes it three ways — measuring each — and ends with the design rule that would have prevented it. The fix that works best costs nothing and changes one keyword argument.
Skills applied: routing cost (§10.3); optimization levels (§10.5); entanglement patterns (Ch. 8 §8.7); the transpiled-count audit (Ch. 6 §6.5).
Reproducibility. FakeSherbrooke, seed_transpiler=42, entirely local.
The Plan
from qiskit.circuit.library import efficient_su2
ansatz = efficient_su2(6, entanglement="full", reps=2)
print(f"logical two-qubit gates: {dict(ansatz.decompose().count_ops())['cx']}")
logical two-qubit gates: 30
The team's reasoning, and it is not unreasonable:
"Thirty two-qubit gates. Chapter 1 said the budget is a few hundred. At a 0.75% two-qubit error rate, thirty gates gives $(1-0.0075)^{30} \approx 80\%$ chance of an error-free run. Comfortable."
Every number in that paragraph is correct. The conclusion is wrong.
The Diagnosis
pm = generate_preset_pass_manager(optimization_level=1, backend=backend, seed_transpiler=42)
isa = pm.run(ansatz)
print(f"transpiled two-qubit gates: {two_qubit_count(isa)}")
transpiled two-qubit gates: 90
Ninety, not thirty. Redo the success arithmetic: $(1-0.0075)^{90} \approx 51\%$, not 80% — and that is before the depth-driven decoherence that sixty extra gates also bring.
The reason is visible the moment you compare the circuit's connectivity to the device's.
entanglement="full" on six qubits means every one of the fifteen pairs must interact. The
device's qubits have at most three neighbors. Most of those fifteen pairs are not adjacent, so each
one requires the router to walk the qubits together — and every step costs a SWAP, and every SWAP
costs three CNOTs.
The general measurement, from §10.3:
n | logical | all-to-all transpiled | ratio | chain transpiled | ratio
---|---------|-----------------------|-------|------------------|------
4 | 6 | 12 | 2.0x | 3 | 1.0x
5 | 10 | 18 | 1.8x | 4 | 1.0x
6 | 15 | 33 | 2.2x | 5 | 1.0x
7 | 21 | 44 | 2.1x | 6 | 1.0x
The ratio grows with $n$ for the mismatched circuit and stays at exactly 1.0 for the matched one.
Fix 1: Raise the Optimization Level (free, partial)
The first thing to try, because it costs one integer.
level | 2q gates | vs logical 30
------|----------|---------------
0 | 114 | 3.8x
1 | 90 | 3.0x
2 | 80 | 2.7x
3 | 83 | 2.8x
Level 0 to level 2 removed thirty-four two-qubit gates — a 30% reduction, from nothing but better layout and routing. Note also that level 3 is worse than level 2 here (83 vs 80), which is §10.5's warning arriving in practice.
This is real and it is nowhere near enough. Eighty is still 2.7× the logical count, and the circuit is still overwhelmingly routing-dominated.
Verdict: always do this, never stop here.
Fix 2: Best-of-N Seeds (nearly free, small)
From §10.9: SABRE is randomized, so sample it.
best = min((pm_with_seed(s).run(ansatz) for s in range(8)),
key=lambda c: (two_qubit_count(c), c.depth()))
On the routing-limited circuit of §10.9 this bought about 10% for 31 milliseconds. On this ansatz the gain is similar — a few gates, essentially free.
Verdict: always do this too. It is milliseconds against a circuit you will run thousands of times. But it does not change the shape of the problem.
Fix 3: Change the Entanglement Pattern (free, decisive)
The actual fix, and it is one keyword.
ansatz = efficient_su2(6, entanglement="linear", reps=2) # was "full"
Measured at $n = 6$, reps=2, all four optimization levels:
| Pattern | Logical 2q | Transpiled (L0 / L1 / L2 / L3) | Best ratio |
|---|---|---|---|
full |
30 | 114 / 90 / 80 / 83 | 2.67× |
circular |
12 | 60 / 42 / 40 / 40 | 3.33× |
linear |
10 | 10 / 10 / 10 / 10 | 1.00× |
pairwise |
10 | 10 / 10 / 10 / 10 | 1.00× |
From eighty transpiled gates to ten. An eightfold reduction, and the routing overhead vanishes
entirely — linear transpiles to exactly its logical count at every optimization level, because a
chain maps onto a chain with no movement required.
Note circular, which is instructive. Chapter 8's logical table made it look cheap: twelve gates
against full's thirty. After routing it needs forty — still less than full's eighty in absolute
terms, but with the worst ratio of all four, because that single wrap-around link from qubit $n-1$
back to qubit 0 requires walking a qubit the entire length of the chain.
A logical gate count cannot tell you which pattern is cheap. Only the transpiled count can.
And it gets worse with size
n | full logical -> transpiled | ratio | linear logical -> transpiled | ratio
---|----------------------------|-------|------------------------------|------
4 | 12 -> 21 | 1.75x | 6 -> 6 | 1.00x
6 | 30 -> 80 | 2.67x | 10 -> 10 | 1.00x
8 | 56 -> 156 | 2.79x | 14 -> 14 | 1.00x
10 | 90 -> 284 | 3.16x | 18 -> 18 | 1.00x
At ten qubits, full needs 284 two-qubit gates and linear needs 18 — a factor of nearly
sixteen. Against Chapter 1's few-hundred budget, full at ten qubits is already out of reach and
linear has room for a great deal more depth.
⚠️ Common Pitfall — But is the cheaper ansatz still good enough?
This is the question that makes the fix a design decision rather than a free win, and it must be asked.
fullentanglement is more expressive: it can reach stateslinearcannot at the same depth. So the honest comparison is not "10 gates versus 30" but "10 gates and less expressiveness versus 30 gates and more."Three things make the trade favorable here, and it is worth knowing all three rather than just taking the cheap option:
- Depth substitutes for connectivity. A linear ansatz at
reps=4has 20 two-qubit gates — still belowfullatreps=2— and entanglement propagates across the whole register through the extra layers.- More expressiveness is not free on the optimization side. Chapter 32 §32.5's barren-plateau result says highly expressive ansätze have flatter landscapes; the expressiveness that lets an ansatz represent the answer can make the answer harder to find. Chapter 16 §16.6 puts a number on how much relief a shallower ansatz buys: a constant factor, and no change in the exponent.
- You can measure it. Chapter 4's
reachable_entanglement()tells you whether the cheaper ansatz reaches the kind of state you need. Run it before committing.The rule is not "always use linear." It is: know what your entanglement pattern costs after routing, and buy expressiveness with depth rather than with connectivity when the topology is sparse.
What Would Have Prevented It
One line, at design time:
def routing_overhead(circuit, backend, level=2, seed=42):
"""Transpiled two-qubit gates divided by logical. 1.0 means no routing cost."""
pm = generate_preset_pass_manager(optimization_level=level, backend=backend,
seed_transpiler=seed)
logical = sum(v for k, v in circuit.count_ops().items() if k in TWO_Q)
physical = two_qubit_count(pm.run(circuit))
return physical / max(1, logical), logical, physical
Run it on any candidate ansatz before committing to it. A ratio near 1.0 means the circuit fits the device; a ratio of 2 or more means you are paying for routing and a structural change will help far more than any amount of compiler tuning.
Budget in transpiled gates, always. The number in your source file is a wish.
🔬 Honest Assessment — How often is this the real problem?
Often enough to check first.
When a variational experiment returns noise, the usual suspects are noise itself, ansatz expressiveness, and barren plateaus — all real, all discussed at length in the literature, and all harder to diagnose than routing overhead. Routing is the cheapest hypothesis to test: one transpilation and a division.
It is also the one most likely to be missed, because nothing tells you. The transpiler does not warn that it inserted thirty-nine SWAPs; it just does its job. The gate count in your source stays reassuringly small. And the symptom — a result that is noisier than expected — looks exactly like the symptoms of every other cause.
The broader pattern, and it is the third time this book has hit it: check the pipeline before the physics. Chapter 7's Case Study 1 was a layout that silently measured the wrong qubits; Chapter 8's was a parameter ordering that silently scrambled the angles; this one is a routing overhead that silently tripled the gate count. All three produce "the answer is worse than expected," all three are diagnosed in under a minute, and all three are usually diagnosed last.
Lessons
- Count transpiled gates, not written gates. Thirty in the source; ninety on the device.
- A SWAP costs three CNOTs, and there is no cheaper construction.
- Routing overhead scales with connectivity mismatch — exactly 1.0× for a chain, 1.75× to 3.16× and growing for all-to-all.
- A logical gate count cannot rank patterns.
circularlooks cheap logically (12 vs 30) and has the worst routing ratio of all four (3.33×). - Raise the optimization level first. Level 0 → 2 removed 30% here. Free, never sufficient alone — and level 3 was worse than level 2.
- Best-of-N seeds next. Milliseconds, a few percent.
- Then change the structure.
full→linearwent from 80 transpiled gates to 10, and eliminated routing entirely. - Buy expressiveness with depth, not connectivity, when the topology is sparse.
- Measure
routing_overheadat design time. A ratio near 1 means the circuit fits; 2 or more means structure, not tuning. - Check the pipeline before the physics. Three chapters, three silent pipeline failures, all diagnosed in under a minute and all diagnosed last.
Questions
-
Reproduce the measurement:
efficient_su2(6, entanglement="full", reps=2)at all four optimization levels. Report logical and transpiled two-qubit counts. -
Implement
routing_overheadand apply it tofull,linear,circular, andpairwiseat $n = 4, 6, 8, 10$. At what $n$ doesfullbecome clearly infeasible on a 100-gate budget? -
The chapter suggests buying expressiveness with depth. Compare
linearatreps=4againstfullatreps=2: transpiled gate counts, andreachable_entanglement()from Chapter 4's checkpoint. Which would you run? -
Use
initial_layoutto pin thefullansatz onto a set of qubits you choose by hand. Can you beat the transpiler's layout? What would you need to know about the coupling map to try? -
The team's original arithmetic — 30 gates at 0.75% error giving ~80% success — was correct given its premise. Redo it with the transpiled count at each optimization level. What success probability were they actually running at?
-
Construct a circuit for which
fullentanglement transpiles with a ratio near 1.0. What must be true of the device? (Chapter 17.) -
Hardest. Routing overhead depends on the order in which two-qubit gates appear, not just on which pairs interact — a router can sometimes reuse a SWAP for several subsequent gates. Construct two circuits with identical pair sets but different gate orders, and measure whether the transpiled counts differ. If they do, what does that suggest about how you should write an all-to-all ansatz that you cannot avoid?