52 min read

> "A 127-qubit processor is not 127 qubits. It is a population, and you get to choose your sample."

Prerequisites

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Learning Objectives

  • Compare backends on the metrics that predict circuit success, rather than on qubit count.
  • Read a device's calibration data and quantify the spread in qubit quality within a single chip.
  • Identify unusable qubits and gate pairs programmatically before submitting.
  • Select a high-quality qubit layout by scoring candidate paths against calibration data.
  • Manage asynchronous jobs: submission, monitoring, retrieval, and failure.
  • Apply a decision procedure that distinguishes device noise from a program bug.

Chapter 12: Running on Real Hardware

"A 127-qubit processor is not 127 qubits. It is a population, and you get to choose your sample."

Overview

Part II has been building to one question, and this chapter answers it: your circuit came back wrong — is that noise, or is that a bug?

Everything you need is now in place. Chapter 10 gave you the compiler's contribution, Chapter 11 gave you the noise signatures, Chapter 7 gave you the reference value, and Chapter 2's case study gave you the error-budget method. §12.7 assembles them into a procedure you can follow.

Before that, the chapter establishes something about hardware that is easy to know abstractly and hard to believe until you measure it: the variation in quality within a single device is far larger than the variation between devices.

Measured on one 127-qubit processor:

  • Readout error ranges from 0.29% to 50% — a factor of 171.
  • Two-qubit gate error ranges from 0.35% to 100% — a factor of 288, and nine gate pairs are simply dead.
  • $T_2$ ranges from 2.6 μs to 489 μs — a factor of 185.

And the consequence, measured on a three-qubit GHZ state: the best qubit triple returned the correct answer 97.3% of the time and the worst 28.4%. Same circuit, same chip, same second. A factor of 3.4 in correctness, from nothing but which three qubits you used.

Chapter 4's Case Study 1 discovered one dead qubit by accident. This chapter finds all nine systematically, and turns the search into a preflight check you run before every submission.

In this chapter, you will learn to:

  • Compare backends on metrics that predict success.
  • Read calibration data and quantify the spread within a chip.
  • Find unusable qubits and pairs programmatically.
  • Score candidate layouts against calibration data and pick a good one.
  • Manage asynchronous jobs.
  • Apply the noise-or-bug decision procedure.

Learning Paths

How to read this chapter by track. - 🔰 Beginner — §12.1, §12.4, and §12.7. The decision procedure is the durable skill. - 🔬 Researcher — §12.2 and §12.3. Reporting which qubits you used, with their calibration figures, is the difference between a reproducible result and an anecdote. - 🤖 Quantum ML — §12.3's layout scoring, and §12.5 on sessions — your training loop lives or dies on the second. - 🏗️ Quantum Engineer — all of it, especially §12.3's preflight check, which belongs in your submission path permanently. - 🔐 Security — skim; §12.7's decision procedure is the transferable part.


12.1 Choosing a Backend

Not by qubit count. Chapter 1 §1.5 said so; here is what to use instead.

import numpy as np

def summarize(backend):
    t = backend.target
    two_q = "ecr" if "ecr" in t.operation_names else "cz"
    return {
        "name": backend.name,
        "qubits": backend.num_qubits,
        "two_q_gate": two_q,
        "median_2q_error": np.median([p.error for p in t[two_q].values()
                                      if p and p.error is not None]),
        "median_readout": np.median([t["measure"][(q,)].error
                                     for q in range(backend.num_qubits)]),
        "median_t1_us": np.median([t.qubit_properties[q].t1
                                   for q in range(backend.num_qubits)]) * 1e6,
        "median_t2_us": np.median([t.qubit_properties[q].t2
                                   for q in range(backend.num_qubits)]) * 1e6,
    }
  backend            qubits  2q gate   median 2q err   median RO    T1 (μs)   T2 (μs)
  fake_sherbrooke      127     ecr        0.00779       0.0198       278.4     170.0
  fake_torino          133     cz         0.00419       0.0229       185.0     140.9
  fake_kyiv            127     ecr        0.01172       0.0127       287.1     118.1
  fake_osaka           127     ecr        0.00693       0.0211       287.3     140.0

Four devices, and the interesting differences are not in the qubit column.

Two-qubit gate error spans 2.8× across these four — 0.0042 to 0.0117. Since two-qubit gates dominate the error budget (Chapter 11 §11.7), that is the single most predictive number.

Note the gate set differs. fake_torino uses cz where the others use ecr — a different device generation with a different native entangler. That affects transpilation, and it is why Chapter 10 insisted on measuring against the device you will actually run on.

There is no single best device. fake_kyiv has the best readout error and the worst gate error; fake_torino has the best gate error and the worst readout. Which matters depends on your circuit: a shallow circuit is readout-dominated, a deep one is gate-dominated.

Your circuit Optimize for
Shallow, few two-qubit gates readout error
Deep, many two-qubit gates two-qubit gate error
Long duration, idle qubits $T_2$
Wide qubit count and connectivity

12.1.1 Write the procedure down before you look

That table is a menu, and a menu is dangerous. Four devices, five metrics, and a result you have not seen yet: that is enough freedom to justify any choice after the fact.

The failure mode is specific, and it does not feel like cheating at any step. You run on fake_kyiv, the result disappoints, and you reason — correctly, from the table — that your circuit is gate-dominated and Kyiv has the worst gate error of the four. You move to fake_torino, which has the best. The number improves. You report the Torino number.

Every individual step there is defensible. The result is not. What you have reported is the maximum over four devices, presented as though it were a single draw. Chapter 27 measured how badly a small sample misleads when you let it: a false-failure rate estimated at 1.0% from 2 failures in 200 runs turned out to be 0.150% at 2,000 runs. Selecting the best of four backends is the same error wearing better clothes — the search stopped when the answer looked good, which is the book's recurring observation that the easy number is almost always the flattering one, because it stops the search.

The fix costs five minutes and it has to happen before submission.

Step 0 — characterise the circuit, not the device. Transpile against one candidate at your intended optimization level and read off four numbers: two-qubit gate count, circuit width, circuit depth, and scheduled duration. These are properties of your problem. They do not depend on which device you eventually pick, and they determine which column of §12.1's table is load-bearing.

Step 1 — name the dominant metric and commit to it in writing. Use the table above. A circuit with two entangling gates and three measurements is readout-dominated and you should optimize readout error; the 137-two-qubit-gate QFT-8 of Chapter 39 §39.2 is gate-dominated and readout barely matters. Write the choice in the same file as the result. A metric chosen before the run is a hypothesis; a metric chosen after is a rationalization.

Step 2 — fix a tie-break rule in advance. There is no single best device — fake_kyiv has the best readout and the worst gate error, fake_torino the reverse — so ties and near-ties are the normal case, not the exception. A rule as crude as "dominant metric first, $T_2$ as tie-break, lowest queue last" is fine. What matters is that it is fixed, because an unfixed tie-break is exactly where the free parameter hides.

Step 3 — set the acceptance threshold before you submit. Build the error budget from the chosen device's calibration data and write down the number you expect. Case Study 2's Run A did this and predicted 0.9706 against a measured 0.9727 — but the value of that prediction comes entirely from its having been made first. A budget constructed after seeing 0.9727 would have landed on 0.9727 too, and would have meant nothing.

Step 4 — record the choice, the reason, and the rejected alternatives. One line: chose fake_torino for median 2q error 0.00419 because the transpiled circuit carries 137 two-qubit gates; rejected fake_kyiv (0.01172) despite its better readout. This is the cheapest defence there is against your own future reasoning.

Step 5 — if you change devices after seeing a result, say so, and report both. Switching is often the right call. Switching silently is what converts a measurement into an anecdote. Report the first number and the second, and the reader can see the selection you performed.

None of this is about honesty in the moral sense. It is about keeping backend choice out of the set of things you are unconsciously fitting to your data. There are four devices in that table, and choosing among them after the fact gives you four attempts at a result you only get to claim once.

📊 What the Numbers Say — a median is the right statistic for choosing a device and the wrong one for predicting your circuit.

Every column in §12.1's table is a median, and that is correct for its purpose. You are choosing among populations, and the median is a robust summary of a population you are about to sample from.

The error is carrying that median forward as a prediction. You will not run on the median qubit — you will run on whatever §12.3's scorer picks, and that is deliberately not a random draw.

Measured on fake_sherbrooke: the median ecr error across live links is 0.00750 (§12.2.3; 0.0078 if the dead links are left in), while the two links in the best three-qubit chain are 0.0049 and 0.0053, a mean of 0.0051. Choosing well beats the median by about a third, and it does so before any mitigation, any transpiler flag, or any extra shot.

Chapter 30 met the same problem from the reporting side: on one chip the "quoted two-qubit error" ranged from 0.00750 to 0.07205 — a factor of 9.6 — depending purely on which statistic the quoter chose. The median is a defensible choice among those. It is not the only one, and the range is wide enough that "the device's gate error" is not a well-formed quantity until you say which statistic you mean.

Read §12.1's table as which population do I want to sample from, and §12.3's scorer as which sample do I take. They answer different questions and the median only answers the first.

12.2 The Spread Within a Device

Now the finding that reframes everything.

t = backend.target
readout = np.array([t["measure"][(q,)].error for q in range(backend.num_qubits)])
two_q = np.array([p.error for p in t["ecr"].values() if p and p.error is not None])
t1 = np.array([t.qubit_properties[q].t1 for q in range(backend.num_qubits)])
t2 = np.array([t.qubit_properties[q].t2 for q in range(backend.num_qubits)])
                       min      median        max      max/min
  readout error     0.0029      0.0198     0.5000       170.7x
  2q gate error     0.0035      0.0078     1.0000       288.2x
  T1 (μs)          73.2       278.4      514.9           7.0x
  T2 (μs)           2.6       170.0      488.8         185.4x

Read those ratios against the between-device table above. The best and worst devices differ by 2.8× in median gate error. The best and worst qubits on a single device differ by 288×.

Choosing good qubits matters roughly a hundred times more than choosing a good device.

The broken ones

dead_readout = [q for q in range(backend.num_qubits) if readout[q] > 0.10]
dead_gates = [pair for pair, p in t["ecr"].items()
              if p and p.error is not None and p.error >= 0.99]
  qubits with readout error > 10%:  [6, 9, 13, 16, 34, 52, 56, 57, 64, 70, 84, 92]
  gate pairs with error ≥ 0.99:     [(6,5), (7,6), (8,9), (16,8), (56,52),
                                     (56,57), (83,84), (85,84), (92,102)]

Twelve unusable qubits and nine dead gate pairs on a device advertised as having 127 qubits.

Chapter 4's Case Study 1 found qubit 6 by accident, after a fidelity curve fell off a cliff. It is in that list — along with eight other dead pairs it never encountered. A five-line query finds all of them in a second.

And one entry in that list is stranger than it looks.

12.2.1 What the averaged number destroys

Qubit 84 has a readout error of exactly 0.5000. The natural reading is "a coin flip — it carries no information." That reading is wrong, and the way it is wrong matters.

readout_error is an average of two different quantities:

$$\texttt{readout\_error} = \frac{P(1|0) + P(0|1)}{2}$$

Both directions are in the calibration data under their own names. Pull them out:

qubit readout_error $P(1\mid 0)$ $P(0\mid 1)$ measured $P(1)$ from $\lvert 0\rangle$
6 0.2573 0.5044 0.0103 0.5044
13 0.1270 0.2500 0.0039 0.2554
70 0.1626 0.3188 0.0063 0.3262
84 0.5000 1.0000 0.0000 1.0000
92 0.3406 0.0127 0.6685 0.0142

Qubit 84 is not a coin flip. It is stuck at 1. $P(1|0) = 1$ and $P(0|1) = 0$: it reports 1 from either input, on every one of 4096 shots. And 0.5 is exactly the average a stuck qubit produces — $(1 + 0)/2$. The one summary statistic every device page quotes conceals precisely the failure it most needs to reveal.

Qubit 92 is the mirror image: an averaged 0.3406 that is really 1.3% one way and 67% the other.

A coin flip and a stuck bit both carry zero information, and they are not the same failure. A stuck bit produces no randomness and a hard bias; it is recognizable on sight, and correctable in principle once you know. Averaged into one number, it is invisible.

🗝️ Version Note — Two execution paths disagree about qubit 84.

NoiseModel.from_backend symmetrizes. Its readout matrix for qubit 84 is [[0.5, 0.5], [0.5, 0.5]] — a model of a coin flip. Run through AerSimulator.from_backend and you get {'0': 2054, '1': 2042}, changing with the seed as sampling should.

SamplerV2(mode=backend) honors the asymmetry. Same circuit, same backend, same snapshot: {'1': 4096}and the seed changes nothing, because nothing is being sampled.

"I simulated it with the device noise model" is therefore an ambiguous statement. Say which path. This affects only qubits with strongly asymmetric readout, which is a small minority — but those are exactly the qubits you are most likely to be investigating when the question arises.

Verified against Qiskit 2.5.1 / qiskit-aer 0.17.2 / qiskit-ibm-runtime 0.48.0. Check it on your own versions with example-06; the lesson outlives the version, the specific behavior may not.

12.2.2 Which direction does readout error run?

With both directions available, a question from Chapter 2 can finally be answered properly.

The textbook expectation is that $1 \to 0$ errors should dominate: $|1\rangle$ decays toward $|0\rangle$ during the measurement window, so a qubit prepared in $|1\rangle$ has a chance to relax before it is read. Chapter 2's Case Study 2 measured the opposite on both qubits it examined, and drew the lesson measure the asymmetry, don't inherit it.

Across all four devices, every qubit:

device $P(1\lvert 0) > P(0\lvert 1)$ reverse mean $P(1\lvert 0)$ mean $P(0\lvert 1)$
fake_sherbrooke 85 38 0.0585 0.0245
fake_torino 69 61 0.0512 0.0422
fake_kyiv 56 68 0.0281 0.0341
fake_osaka 51 76 0.0410 0.0428

The direction flips between devices. Sherbrooke leans hard toward $0 \to 1$ errors — 85 qubits to 38, and more than double in the mean, contradicting the textbook expectation exactly as Chapter 2 found. Kyiv and Osaka lean the other way. Torino is nearly balanced.

So there is no rule to memorize here, and that is the result. Chapter 2 drew the right lesson from two qubits; 513 qubits across four devices confirm it. The asymmetry is a property of a particular chip's readout hardware and calibration, not of the physics of decay, and any mitigation strategy that assumes a direction will be wrong on half the devices you try it on.

Asymmetry is also not rare: the median qubit is 1.3× to 1.9× asymmetric depending on device, and Sherbrooke has 11 qubits more than 10× asymmetric.

This is the third time this book has caught a summary statistic hiding what mattered. Chapter 2's Case Study 2 found the readout asymmetry running opposite to the textbook expectation. Chapter 11 found phase damping invisible in the computational basis. Now the averaging itself.

A summary statistic is a lossy compression. Read the raw fields when the decision matters.

12.2.3 288× is two claims wearing one number

The ratio at the top of §12.2's table deserves the same scrutiny the chapter just applied to readout_error, because it is built the same way — out of a maximum that is not what it appears to be.

The 1.0000 in the max column is not a measured gate error. It is a sentinel for a dead link. So 288× is the ratio of a broken thing to the best working thing, and it silently fuses two separate findings. Split them:

  ecr pairs, fake_sherbrooke                     144
  dead    (error ≥ 0.99)                           9        6.3%
  live                                           135

  live links only:  min 0.00347   median 0.00750   max 0.11736    ratio  33.8x
                    90th pct 0.01436    99th pct 0.08752

  readout, usable qubits only (< 0.10):  n = 115
                    min 0.00293   median 0.01758   max 0.09888    ratio  33.8x

Claim one: 6.3% of this chip's entangling links do not work at all. Claim two: among the ones that do, quality varies by 33.8×. Both are true, both matter, and they call for different responses — the first for a preflight check that refuses, the second for a scorer that ranks.

This forces a refinement of §12.2's headline. "Choosing good qubits matters roughly a hundred times more than choosing a good device" is built on 288× against the between-device 2.8×. Using the live-link spread instead, the comparison is 33.8× against 2.8× — about twelve times the leverage, not a hundred. Still decisive. Not the number the headline implies.

And it gets more honest still when you ask what is left after preflight. Score every connected three-qubit path on the device, then score only the ones a preflight check would let through:

  all 394 connected 3-paths          score 0.0501 - 6.6016      ratio 131.9x
  the 310 that pass preflight        score 0.0501 - 0.2197      ratio   4.4x
  predicted fidelity, over the 310 passing paths
     best    0.9706        median   0.9226        worst   0.8255
     infidelity ratio, worst to best                       5.9x

Preflight does most of the work, and scoring does the rest. The 131.9× spread the chapter opened with is overwhelmingly the dead-link tail, and rejecting nine links removes it for free. What remains — a 5.9× spread in infidelity between the best and worst acceptable layout — is worth having and is a different order of claim.

So the honest version of §12.2's lesson is two-tiered. Refusing to run on broken hardware is enormous and costs nothing. Choosing the best of the working hardware is worth roughly a factor of six in infidelity on this device and requires a second of enumeration. Report them separately, because a team that has implemented preflight and then measures "only" a 4.4× layout spread has not failed to reproduce this chapter — they have already collected the larger half of the benefit.

(That both ratios above land on 33.8× is a coincidence of this snapshot. Two unrelated distributions happened to span the same factor; nothing connects them.)

12.2.4 What is actually in a calibration snapshot

The chapter has been pulling individual fields out of backend.target and backend.properties(). Here is the whole surface, because you cannot decide which field answers your question until you know which fields exist.

  per qubit    T1, T2, frequency, anharmonicity,
               readout_error, prob_meas0_prep1, prob_meas1_prep0, readout_length
  per gate     gate_error, gate_length          (for each gate on each qubit or pair)
  per device   backend_name, backend_version, last_update_date
  general      jq_<pair>, zz_<pair>             coupling strengths and ZZ crosstalk terms

Four things in that list are worth pausing on.

prob_meas0_prep1 and prob_meas1_prep0 are separate fields. §12.2.1 is not an obscure trick; the two directions are first-class data and readout_error is the derived quantity. The average is the convenience; the terms are the measurement.

readout_length is a duration, not an error. On fake_sherbrooke every qubit reports the same 1,216 ns measurement window — and that single number is larger than two median ecr gates put together (533.3 ns each) and 21× a single sx (56.9 ns). Chapter 39 §39.2 measured the consequence on a different device: readout is 92.3% of a Bell circuit's duration. If your circuit is shallow, almost everything the device does for you is measurement.

frequency and anharmonicity are there and you will almost never use them directly. They are the physical parameters the calibration is of — the qubit's transition frequency and the spacing between its energy levels. They matter for the pulse-level work in Chapter 31 and for understanding why two neighbouring qubits with nearly equal frequencies have a bad link.

The general block carries zz_<pair> terms — the always-on residual coupling between qubits. This is crosstalk quantified, and it is the one field in the snapshot that describes an error your circuit suffers because of what a neighbouring circuit is doing. Nothing in this chapter's scoring function uses it. That is a gap, not a completeness.

How old is any of this? properties().last_update_date tells you, and it is the field to print alongside every result. The snapshot backing this chapter's numbers reports 2025-02-26 14:43:10-05:00, which makes every measurement here a statement about that Wednesday afternoon.

This environment has no credentials and therefore cannot measure how often a real device recalibrates — that is provider policy, not a physical constant, and it varies by device and by vendor. What the book can say is what it measured elsewhere: Chapter 29 found a hand-picked chain scoring 0.6790 where a calibration-picked one scored 0.9764, and Chapter 39 §39.6 measured that the layout you are assigned can shift fidelity by 2.03×. Both of those are the same underlying fact — the snapshot moves, and your layout decision is only as good as the snapshot it was made from. Print last_update_date, and if the gap between it and your execution timestamp is large, treat your layout score as a prior rather than a measurement.

⚛️ The Physics Underneath — $T_1$, $T_2$, and the bound that ties them together.

The two coherence times are not two flavours of the same thing.

$T_1$ is energy loss. A qubit in $|1\rangle$ is in an excited state, and it leaks energy into its environment — the substrate, the readout resonator, two-level defects in the oxide. The population decays as $e^{-t/T_1}$ toward $|0\rangle$. This is a directional error: it turns 1s into 0s and essentially never the reverse, which is why Chapter 11's $T_1$ signature is a tilted histogram with no impossible outcomes.

$T_2$ is phase loss. A qubit in a superposition carries a relative phase, and slow fluctuations in its transition frequency — magnetic flux noise, charge noise, the zz_ coupling to whatever a neighbour is doing — randomise it. Nothing about the populations changes. This is exactly Chapter 11 §11.7's finding that phase damping is invisible in the computational basis, and it is why §12.7 step 5 ends with "measure another basis."

The two are linked by an inequality that is not a convention but a theorem:

$$\frac{1}{T_2} = \frac{1}{2T_1} + \frac{1}{T_\phi} \qquad\Longrightarrow\qquad T_2 \le 2T_1$$

Energy decay also destroys phase — if the qubit has fallen to $|0\rangle$ there is no superposition left to carry a phase — so $T_2$ can never exceed twice $T_1$. $T_\phi$ is the pure dephasing time, everything that scrambles phase without moving energy.

Checked on all 127 qubits of fake_sherbrooke: the bound holds on 127 of 127. The measured $T_2/T_1$ ratio runs from 0.009 to 1.852, median 0.647 — so the typical qubit loses phase somewhat faster than energy, and the worst qubit loses it about a hundred times faster.

This is a live consistency check on calibration data, and it costs one line. A snapshot reporting $T_2 > 2T_1$ on any qubit is reporting something impossible, which means a stale field, a failed fit, or a unit error — and you would rather find that before you build an error budget on it than afterwards.

🔬 Honest Assessment — This is normal, and it is not a scandal.

Superconducting qubits are fabricated in large numbers and they do not come out identical. Some are defective from fabrication; some drift out of calibration; some are temporarily unusable and will be fine after the next calibration cycle. Vendors publish the data precisely so that you can route around it.

What is a problem is the gap between that reality and how devices are described. "A 127-qubit processor" is a statement about fabrication, not about usable computational resource. On this snapshot, twelve of those qubits cannot be used for anything, and the usable ones vary by two orders of magnitude in quality.

The practical posture: treat a device as a population you sample from, not a machine you run on. Query the calibration, score your candidates, choose deliberately, and record what you chose. That is not defensive pessimism; it is the difference between 97% and 28% correctness, measured below.

12.3 Choosing Qubits: Scoring Layouts

If the spread is 288×, choosing well is worth real effort. And the effort is small.

The scoring function. For a circuit that needs a chain of $n$ qubits, estimate the total error:

def score_chain(path, target, two_q="ecr"):
    """Lower is better. Readout error per qubit, plus 3x gate error per link
    (three CNOTs per SWAP is the wrong factor here, but the RELATIVE ranking
    is what matters -- see the caveat below)."""
    total = sum(target["measure"][(q,)].error for q in path)
    for a, b in zip(path, path[1:]):
        props = target[two_q].get((a, b)) or target[two_q].get((b, a))
        total += 3 * (props.error if props and props.error is not None else 1.0)
    return total

Enumerate the candidates by walking the coupling map:

  n=3: 394 connected paths
       best  (122, 123, 124)   score 0.0501
       worst  (83,  84,  85)   score 6.6016      ratio 131.9x

  n=5: 684 connected paths
       best  (126, 125, 124, 123, 122)   score 0.1104
       worst (102,  92,  83,  84,  85)   score 10.0220   ratio 90.7x

A 132-fold spread in predicted error across 394 candidate layouts — and enumerating all of them takes under a second.

Does the score predict reality?

The only question that matters. Run a three-qubit GHZ state on the best, median, and worst triples:

  layout            correct fraction
  BEST   [122, 123, 124]      0.9727
  median [ 67,  66,  65]      0.9207
  WORST  [ 83,  84,  85]      0.2844

97.3% versus 28.4%. A factor of 3.4 in the correctness of the answer, from nothing but qubit choice.

And the ranking is right: best beats median beats worst, in the order the score predicted. The score is crude — it adds readout and gate errors that combine multiplicatively rather than additively, and the factor of 3 is borrowed from SWAP cost where it does not strictly apply — and it does not need to be accurate to be useful. It needs to rank correctly, and it does.

Why a crude score ranks correctly: taking 0.0501 apart

"Crude but it ranks" is an assertion, and it is checkable without running anything. Decompose the three scores into the terms the function actually adds:

  layout             Σ readout      Σ gate error    ×3        score
  [122, 123, 124]      0.019531       0.010173    0.030519   0.050050
  [ 67,  66,  65]      0.059082       0.023628    0.070884   0.129966
  [ 83,  84,  85]      0.601562       2.000000    6.000000   6.601562

Now recombine the same inputs the way physics combines them — multiplicatively, with each gate counted once rather than three times:

  layout              predicted F     measured
  [122, 123, 124]        0.970641      0.9727
  [ 67,  66,  65]        0.919924      0.9207
  [ 83,  84,  85]        0.000000      0.2844

The best layout's predicted 0.970641 is exactly Case Study 2's error budget of 0.9706 — arrived at there from calibration data, arrived at here from the scoring function's own terms, because they are the same numbers. Measured: 0.9727. And the median layout, which no case study examined, predicts 0.919924 against a measured 0.9207 — eight parts in ten thousand.

Two of three predicted to better than a quarter of a percent. The third predicts exactly zero and measured 0.2844, which is Case Study 2's step-4 trap: $(1-1.0)^2 = 0$ is not a bad estimate, it is the absence of an estimate.

📐 Math Aside — the score is predicted log-infidelity with the gate term inflated 3×.

Write the score for a path $P$ with readout errors $r_q$ and link errors $e_\ell$:

$$\text{score}(P) = \sum_{q \in P} r_q + 3\sum_{\ell \in P} e_\ell$$

and the multiplicative fidelity model those same terms imply:

$$F(P) = \prod_{q}(1-r_q)\prod_{\ell}(1-e_\ell) > \qquad\Longrightarrow\qquad > -\ln F = -\sum_q \ln(1-r_q) - \sum_\ell \ln(1-e_\ell)$$

For small errors $-\ln(1-x) = x + x^2/2 + \dots \approx x$, so

$$-\ln F \;\approx\; \sum_q r_q + \sum_\ell e_\ell > \qquad\Longrightarrow\qquad > \boxed{\;\text{score} \;\approx\; -\ln F \;+\; 2\sum_\ell e_\ell\;}$$

The score is the log-infidelity plus twice the gate-error sum. Check it on the best layout: $-\ln(0.970641) = 0.0298$, score $= 0.0501$, difference $= 0.0203$, and $2\sum e_\ell = 2(0.010173) = 0.0203$. Exact to four decimals. On the median layout the difference is 0.0465 against a predicted 0.0473 — the 0.0008 gap is the second-order term, appearing right where the expansion says it should, because the errors are four times larger.

This is why the score ranks. Adding errors instead of multiplying them is not an approximation error at all; it is the exact log of the multiplicative model. The only real distortion is the factor of 3, which reweights gates against readout — and if a layout comparison is dominated by gate error, reweighting the gate term by a constant cannot change the order.

It also tells you what the score is not. $\text{score} = 0.0501$ does not mean 95% fidelity; $e^{-0.0501} = 0.951$, while the model's actual prediction is 0.9706. Never exponentiate the score. Compute $F$ separately if you want a number to compare against a measurement — the score is for ordering, $F$ is for predicting, and they are two different functions of the same data.

Where the score would rank wrongly

The factor of 3 is safe only while gate error dominates. The condition under which it inverts the true ranking falls straight out of the identity above.

Compare two layouts $A$ and $B$. Let $\Delta r = r_B - r_A$ and $\Delta g = g_B - g_A$ be the differences in their readout and gate-error sums. Truth prefers $A$ when $\Delta r + \Delta g > 0$; the score prefers $A$ when $\Delta r + 3\Delta g > 0$. They disagree exactly when those two expressions have opposite signs, which requires $\Delta r$ and $\Delta g$ to have opposite signs and

$$|\Delta g| \;<\; |\Delta r| \;<\; 3|\Delta g|$$

The score ranks wrongly precisely when one layout's readout advantage is between one and three times the other's gate-error advantage. A concrete pair inside that window:

  layout   Σ readout   Σ gate     score = r + 3g     -ln F ≈ r + g
    A        0.020      0.020         0.080              0.040
    B        0.050      0.005         0.065              0.055

  score prefers B.   The fidelity model prefers A.   They disagree.

And note which regime that is. The inversion needs readout error to be comparable to gate error in total, which happens when the circuit is shallow — exactly the case §12.1's table flags as readout-dominated. The crude score is most trustworthy on deep circuits and least trustworthy on simple ones, which is the reverse of the usual intuition about approximations.

The fix is not to abandon the score. It is to rank by $-\ln F$ when your circuit is shallow, which costs one line, uses the same fields, and removes the arbitrary constant entirely. Keep the ×3 form only where it came from — as a rough charge for the SWAPs a longer chain will attract.

The coherence budget: does the circuit fit inside $T_2$?

The scoring function has a hole in it, and the hole is time. score_chain contains no duration term at all. Two layouts with identical readout and gate errors score identically even if one routes through twice as many SWAPs and takes twice as long, and the longer one will be worse.

The missing model is one exponential. A qubit holding a superposition for duration $T$ retains coherence

$$C(T) = e^{-T/T_2}$$

and the useful form is the inverse — the coherence time a circuit demands in order to retain a fraction $f$:

$$T_2 \;\ge\; \frac{T}{\ln(1/f)}$$

Chapter 39 §39.2 scheduled four representative circuits and measured their durations. Take those durations and ask what this chapter's 127-qubit device could hold:

  circuit            duration     T2 needed      qubits         T2 needed     qubits
                                  for 99%       qualifying      for 90%     qualifying
  Bell                 1.69 μs      168.2 μs      65 / 127         16.0 μs    122 / 127
  GHZ-10               2.49 μs      247.8 μs      43 / 127         23.6 μs    116 / 127
  EfficientSU2-12      3.22 μs      320.4 μs      23 / 127         30.6 μs    113 / 127
  QFT-8               10.55 μs    1,049.7 μs     ★ 0 / 127        100.1 μs     86 / 127

No qubit on this chip can hold a 10.55 μs circuit to 99% coherence. The best $T_2$ on the device is 488.8 μs and the requirement is 1,049.7 μs — short by a factor of 2.1. That is not a bad-layout problem and no amount of scoring fixes it; it is a statement that a QFT-8-length circuit on this device pays at least 1% to dephasing before a single gate error is counted.

Run the same arithmetic against the worst qubits instead of the best, using §12.2's measured $T_2$ range:

  retained coherence e^(-T/T2)
                      T2 = 170.0 μs      T2 = 2.6 μs
                      (device median)    (worst qubit)
  Bell    1.69 μs        0.9901            0.5220
  QFT-8  10.55 μs        0.9398            0.0173

On the worst qubit a 10.55 μs circuit is 4.06 time constants long and retains 1.7% of its coherence. The readout_error on that qubit might be perfectly acceptable. The gate errors on its links might be fine. Nothing in §12.3's preflight or scoring function would object, and the run would come back as noise with no structural signature — which is exactly the case §12.7 step 5 sends you to another measurement basis to detect, because dephasing does not change populations.

Two practical rules follow.

Add duration to the preflight. Schedule the transpiled circuit, read its duration, and refuse any layout whose minimum $T_2$ is less than a few times that. It is one more comparison against data you already loaded.

Score long circuits on $T_2$ and short ones on readout. §12.1's table said this for device selection; it applies with more force to qubit selection, because the $T_2$ spread within this device is 185× and the spread between devices is not close to that.

📉 Noise Report — the score models two error channels and the device has more than two.

score_chain counts readout error and two-qubit gate error. Everything else it ignores: single-qubit gate error, idling decoherence (above), crosstalk from the zz_ terms of §12.2.4, leakage out of the computational subspace, and measurement-induced disturbance on neighbours.

That is not a fatal objection — the ignored channels are individually small on this hardware, which is why Case Study 2's two-channel budget landed within two parts in a thousand. But it bounds how much you should trust it. Chapter 30 measured the accuracy of exactly this class of estimate: the median prediction landed within 12% of Chapter 28's measured circuit fidelity. Treat 12% as the honest error bar on any number this function produces.

The uncomfortable consequence: an effect smaller than 12% cannot be established by comparing a measurement to this model. If a layout underperforms its prediction by 8%, you have learned nothing — that is inside the model's own noise. You need a measured baseline, not a modelled one, which is Chapter 30's whole subject.

And the remedy that seems obvious for idle-qubit dephasing is not one. Chapter 31 measured dynamical decoupling and found it significantly worse: XX sequences cost −0.0053 ± 0.0012, a 4.4 standard-error effect in the wrong direction. Filling idle time with pulses adds pulses, and on this hardware the pulses cost more than the idling did.

⚙️ Under the Transpiler — initial_layout pins the placement, not the route.

There is a gap between "I chose good qubits" and "my circuit ran on good qubits", and it is wide enough to lose a day in.

initial_layout fixes where your virtual qubits start. It does not constrain the routing pass, and the nine dead links of §12.2 are ordinary edges in the coupling map — they carry an error of 1.0, but they exist, they are traversable, and a routing pass that is minimising SWAP count has no reason to avoid them. A circuit pinned to three excellent qubits can still be routed across (83, 84) on its way to somewhere else.

So preflight the transpiled circuit, not the requested layout. Walk the two-qubit instructions of the ISA circuit, map each through final_index_layout(), and check the physical pairs that will actually execute. That is the only list that is true.

At optimization_level 2 and 3, VF2Layout and VF2PostLayout do score candidate placements against the target's error rates, which is the transpiler doing §12.3's job for you. Two measured cautions. Chapter 29 found a hardware-aware level 1 (0.9116) beating a naive level 3 (0.7720) — the pass is only as good as the target you hand it. And Chapter 39 §39.6 found that across a 24-seed sweep at level 1, both the best and worst layouts ran on links worse than the device median (effective per-gate errors 4.771 × 10⁻³ and 5.056 × 10⁻³ against a median 3.660 × 10⁻³). The transpiler was not shopping for good couplers at all, which is precisely the headroom a hand score recovers.

⚠️ Common Pitfall — The transpiler already does some of this. Do not skip it anyway.

Optimization levels 2 and 3 use noise-aware layout selection (Chapter 10 §10.6), and Chapter 4's Case Study 1 showed level 3 routing around the dead qubit that level 1 walked into. So why score by hand?

Three reasons.

To know what you got. The transpiler picks; it does not tell you whether its pick was good. A score gives you a number to record alongside the result.

To catch the case where it picks badly. The transpiler optimizes a heuristic objective under a time budget. It usually does well and it is not guaranteed to.

To fail before you spend queue time. A preflight check that refuses to submit a circuit landing on a 50%-readout qubit saves you an afternoon.

The preflight check

Put this in your submission path and leave it there:

def preflight(backend, layout, readout_limit=0.10, gate_limit=0.05):
    """Problems worth refusing to submit over. Returns a list; empty is good."""
    t, problems = backend.target, []
    props = backend.properties()
    for q in layout:
        # Check BOTH directions, not the average -- see 12.2.1. A qubit stuck
        # at 1 has an averaged readout_error of 0.5, which some thresholds pass.
        d = props.qubit_property(q)
        p10, p01 = d["prob_meas1_prep0"][0], d["prob_meas0_prep1"][0]
        if max(p10, p01) > 0.90:
            problems.append(f"qubit {q}: STUCK (P(1|0)={p10:.3f}, P(0|1)={p01:.3f})")
        elif max(p10, p01) > readout_limit:
            problems.append(f"qubit {q}: readout P(1|0)={p10:.3f} P(0|1)={p01:.3f}")
    two_q = "ecr" if "ecr" in t.operation_names else "cz"
    for a, b in zip(layout, layout[1:]):
        props = t[two_q].get((a, b)) or t[two_q].get((b, a))
        if props is None:
            problems.append(f"pair ({a},{b}): not connected")
        elif props.error is not None and props.error > gate_limit:
            problems.append(f"pair ({a},{b}): gate error {props.error:.3f}")
    return problems

Ten lines. It would have caught Chapter 4's dead qubit immediately, and it catches the other eight.

The full checklist: five things worth refusing over

The function above covers two of them. Here is the complete list, in the order they cost you time.

1. Width. Does the circuit fit? circuit.num_qubits <= backend.num_qubits is necessary and not sufficient — the real constraint is whether $n$ good qubits exist in a connected arrangement. On fake_sherbrooke, 127 qubits become 115 usable ones, and those 115 are not free to be arranged: the coupling graph has 144 couplers and a maximum degree of 3 (2 qubits of degree 1, 89 of degree 2, 36 of degree 3). A fully connected 127-qubit chip would need 8,001 couplers. Width is a graph question, not a counting question.

2. Connectivity. Is the requested layout actually a connected path? target[two_q].get((a,b)) returning None is the check, and it fires more often than expected on a degree-≤3 graph where most qubits have exactly two neighbours.

3. Dead links on the routed circuit. Not the requested layout — see the transpiler note above. Walk the ISA circuit's two-qubit instructions through final_index_layout() and check the physical pairs that will actually execute.

4. Readout, both directions. §12.2.1's lesson, and the reason preflight() reads prob_meas1_prep0 and prob_meas0_prep1 rather than readout_error. A threshold on the average at 0.6 passes qubit 84, the worst qubit on the device.

5. Duration against $T_2$. Schedule the transpiled circuit and compare its duration to the minimum $T_2$ across the layout. Nothing else in the checklist can see decoherence.

How often does this actually refuse something? Enumerate every connected path on the device and run the check:

             paths   fail readout   fail gate   PASS      pass rate
  n = 3        394             84          44    310         78.7%
  n = 5        684            220         114    464         67.8%

  (the two failure columns overlap -- a path through [83,84,85] fails both)

One in five three-qubit layouts on this device would be refused, and one in three five-qubit layouts. The refusal rate climbs with width, which it must — every additional qubit is another draw from a population where 12 of 127 are unusable.

A detail worth noticing. The naive independent model predicts $(115/127)^3 = 74.2\%$ and $(115/127)^5 = 60.9\%$ pass rates, and the measured rates are higher (78.7% and 67.8%) despite the check also requiring good gates. The bad qubits are not uniformly scattered — they cluster. Look at the list: 6, 9, 13, 16 sit together; so do 52, 56, 57; so do 83, 84, 85 and 92. A cluster spoils fewer distinct layouts than the same number of scattered defects would, because several bad qubits land on the same paths. The compensation is that when a cluster does catch you it takes the whole neighbourhood with it, which is why [83, 84, 85] was not merely bad but 28.4%.

12.4 Jobs

Hardware execution is asynchronous, and the workflow follows from that.

job = sampler.run([isa_circuit], shots=4096)
print(job.job_id())                      # SAVE THIS
print(job.status())                      # QUEUED / RUNNING / DONE / ERROR / CANCELLED

result = job.result()                    # blocks until done

Save the job ID and walk away. Jobs persist server-side; you can close your laptop and retrieve tomorrow:

job = service.job("cx1a2b3c4d5e6f7g8h9i0j")
counts = job.result()[0].data.c.get_counts()

Practical rules, most of which are about not wasting your own time:

Do not sit watching the queue. It is the single largest waste of a learner's day. Submit, record the ID, do something else.

Do not cancel and resubmit. You lose your queue position and start over.

Use least_busy() for iteration, and a chosen backend for results. Chapter 2 §2.6 introduced least_busy; it optimizes for availability, not quality. For a result you will report, pick the backend on §12.1's metrics and accept the wait.

Record everything with the result. Chapter 10 §10.9's provenance list, plus the job ID and the date — calibration drifts, and a result from three weeks ago was produced on a materially different machine.

12.4.1 The nine fields, and which four you can never get back

"Record everything" is advice with no edges. Chapter 39 §39.8 gives it edges by sorting the fields into tiers according to what losing one costs you.

Tier 1 — provider-side, unrecoverable. These exist only at execution time and only on the provider's side. Miss them in the moment and they are gone permanently:

  job_id                 the provider's handle -- your only pointer back
  execution_timestamp    when it RAN, not when you submitted
  calibration_snapshot   the properties the device actually had
  physical_qubits        which qubits you were given

Tier 2 — client-side, reconstructible but not for free. Your source could regenerate these, if you can identify the exact source six months later, which you cannot:

  qiskit_version         transpiler behaviour changes between releases
  optimization_level     determines which pass manager ran
  seed_transpiler        one input to a stochastic function
  shots                  sets the statistical floor
  mitigation settings    resilience level, twirling -- often defaulted

Nine fields, plus the backend name you will have anyway. This chapter adds two more that cost nothing and answer the questions §12.3 raised: the layout score, and the preflight output. A recorded score of 0.0501 versus 0.1300 is the difference between "we ran on good qubits" as a claim and as a fact.

Why Tier 1 is not negotiable. Everything in it describes the machine, and the machine is an input you do not control. §12.2.4's snapshot is stamped 2025-02-26 14:43:10-05:00; a run on a different Wednesday is a different experiment. Chapter 29 measured a hand-picked chain at 0.6790 against a calibration-picked 0.9764 on the same device. Without physical_qubits and calibration_snapshot you cannot tell which of those two things you did.

A fixed seed is not a fixed layout. seed_transpiler=42 fixes one input to the layout pass. The pass itself scores candidate placements against the device's current error rates, so when the device recalibrates the objective function moves and the same seed lands somewhere else. The seed is deterministic; the function it seeds is not stationary. Two things actually pin a layout: pass an explicit initial_layout recorded from the original run, or transpile once and serialize the transpiled circuit itself (Chapter 6's QASM 3) and submit that.

Write the record at result time, not at analysis time. The failure mode is universal and always identical — you intend to record the metadata when you write it up, and by then the job object has been garbage-collected and the calibration snapshot has been overwritten twice.

12.5 Sessions and Batch Mode

Chapter 7 §7.8 introduced the three modes. The operational summary:

Mode Behavior Use for
Job queue independently one-off circuits
Batch submit many together, run as a group independent circuits
Session reserved window, priority within it iterative workloads

The distinction that matters: a session keeps your queue position between iterations. Without one, a 200-iteration VQE queues 200 times, and queue time — not QPU time — dominates completely.

Sessions are metered while open, including while your classical optimizer thinks. So: keep the classical work fast, batch what the optimizer permits, and never open a session for a single circuit.

12.5.1 The three modes are three answers to one question

The question is how many times do you pay the queue? Everything else about the modes follows from that, and the reason it dominates is arithmetic Chapter 39 measured.

A 4,096-shot Bell job occupies the device for 6.92 ms. The deepest circuit in Chapter 39 §39.2's table, a transpiled QFT-8, occupies it for 43.20 ms. Put either next to a queue and the ratio is absurd:

  device busy 6.92 ms, queue 30 seconds   ->  utilization 2.31e-04    (  4,335x wall clock)
  device busy 6.92 ms, queue 5 minutes    ->  utilization 2.31e-05    ( 43,340x wall clock)
  device busy 6.92 ms, queue 8 hours      ->  utilization 2.40e-07    (4,160,504x wall clock)

At a five-minute queue you wait 43,000 times longer than you compute. For scale, Chapter 39 ran the same circuits on one laptop core and got 22–74 ms — the local simulator's wall clock is the same order of magnitude as the quantum device's execution time. Nothing about execution is the bottleneck. Everything that makes hardware feel slow happens around it.

(Those queue figures are representative, not measured — this book has no credentials to obtain real queue data, and says so rather than inventing it. The 6.92 ms is measured.)

Now price the modes against 100 independent circuits at a five-minute queue:

  mode      queue waits    wall clock                  speedup
  Job              100     100 x 300.007 s = 8.33 h       1.0x
  Batch              1     300 s + 0.692 s = 5.01 min    99.8x

Batching 100 circuits is worth about 99×, and it is not a quantum technique. It beats every transpiler flag in Chapter 10 and every mitigation technique in Chapter 13, and it is a scheduling change.

The shape of that speedup is worth knowing, because it tells you when to stop. Submitting $n$ circuits separately costs $n(t_q + t_d)$; batched they cost $t_q + n t_d$, so

$$S(n) = \frac{n(t_q + t_d)}{t_q + n t_d} \qquad\xrightarrow{\;n t_d \ll t_q\;}\qquad S(n) \approx n$$

Linear in the batch size, which is why 100 circuits is 99.8× and not something more interesting. The ceiling is $S(\infty) = 1 + t_q/t_d$, which at a five-minute queue is the same 43,340× that appears in the utilization table — batching's job is to stop wasting the queue, and there is only so much queue to waste. It stays linear until $n \approx t_q/t_d \approx 43{,}300$ circuits, so for any batch a working scientist will ever submit, batching returns its full payoff and has not begun to saturate. The real limit is your provider's cap on circuits per job. Look it up; that, not the formula, is what binds.

Sessions exist because batching requires knowing the circuits in advance. A variational loop does not: iteration $k+1$'s parameters depend on iteration $k$'s result. Chapter 39 §39.7 priced a 120-iteration VQE — as 120 separate jobs at a five-minute queue it spends about ten hours waiting and roughly half a minute computing; in one session it pays the queue once and finishes in about five minutes. The speedup is essentially the iteration count, for the same reason batching's is essentially the batch size.

And the two compose. Chapter 39 measured that VQE run at 27 tasks per iteration, exactly — one per Hamiltonian term in the active space. Those 27 are independent of each other, so they batch; the 120 iterations are not, so they need the session. Batch within the iteration, session across them. A loop that does neither pays $120 \times 27 = 3{,}240$ queue waits for 31 seconds of computation.

One honest limit: batching buys wall clock, not money. One hundred circuits batched into one job still run 100 circuits' worth of shots, so a per-shot bill is identical and the device time under a per-minute bill is identical too. It converts eight hours into five minutes at zero cost, which makes it the best deal available — and it is a latency optimization, not a cost one. Chapter 39 §39.5 measured how far apart those two axes are: the same VQE run priced $50 under one provider's per-minute model and $7,432 under another's per-shot model.

This also reframes the optimizations of Part II. Chapter 10 reduced depth, Chapter 11 characterised noise, §12.3 improved layout. All of them make the seven milliseconds better and none of them touch the five minutes — which is correct, because those are fidelity work and this is throughput work. They are different problems with different levers, and a team that conflates them optimizes the wrong one.

🧪 Run It — everything in §12.1 to §12.3 runs on a fake backend, with no account.

Five experiments, in ascending order of what they teach. Each is a few lines against FakeSherbrooke() or a device of your choosing.

1. Reproduce §12.2's spread, then check whether the max is real. Print min/median/max for gate error, and separately for links with error < 0.99. If the two maxima differ by orders of magnitude, your headline ratio is measuring the existence of dead links, not the spread of quality (§12.2.3).

2. Validate the snapshot with physics. Assert $T_2 \le 2T_1$ on every qubit. On fake_sherbrooke it holds 127 times out of 127. A device where it fails is reporting a stale field or a failed fit, and you want to know that before you build a budget on it.

3. Enumerate and score. Walk the coupling map for connected $n$-paths, score them, and print the distribution rather than just the best. On this device the 394 three-paths run 0.0501 to 6.6016, and 31% of them are within 2× of the best — good layouts are not rare, they are just not the ones you get by accident.

4. Measure your own preflight refusal rate. Count how many enumerated paths the check rejects, then compare against the naive $(\text{usable}/\text{total})^n$. A measured rate above the naive one means the bad qubits cluster on your chip.

5. Vary the transpiler seed 24 times on a 14-qubit circuit and count two-qubit gates. Chapter 39 §39.6 measured 49 to 112. Then run the identical sweep on 4 qubits and watch the variation vanish entirely — layout variance is a large-circuit phenomenon, and measuring it on a toy circuit teaches you the opposite of the truth.

The one thing on this page you cannot reproduce without credentials is the queue. Everything else — the spread, the dead links, the scoring, the preflight, the coherence budget — is in the calibration data that ships with the fake backends.

12.6 Reading the Histogram

You now have every tool. The reading procedure, in order:

1. Check backend.name. Confirm you ran where you think you ran. Chapter 7's Case Study 1 notes how often this is the actual problem.

2. Compute the two axes (Chapter 11 §11.7): error fraction and peak imbalance.

3. Compare against the noiseless reference (Chapter 7 §7.7). A ratio near 1 means noise; near 0.5 or near 0 means something structural.

4. Compare against your error budget (Chapter 2 Case Study 2). Build the prediction from calibration data before looking at the result.

5. If the reading is ambiguous, measure another basis (Chapter 11 §11.7). The computational basis cannot see phase.

🐛 Debug This — A tall peak on a single wrong outcome is never noise.

Noise spreads. Depolarizing, readout, and thermal errors all distribute probability across many outcomes, falling off with the number of bit flips required (Chapter 11 §11.7). A single wrong answer holding a quarter of your shots is a deterministic error, and deterministic errors live in your circuit, your layout, or your bit ordering — never in the device.

Case Study 2's Run C had two clean peaks of nearly equal height, which is exactly the shape of a healthy GHZ state. The peaks were 000 and 011. One bit off, and 111 appeared five times in 4096. The summary — "correct fraction 0.4897" — reported it as half noise and discarded the one feature that identified the bug.

Look at which outcomes are wrong, not just how many. The bit positions name the qubit.

12.7 Noise or Bug? A Decision Procedure

The chapter's payoff, and Part II's.

  Your circuit returned an unexpected result.

  1. DID IT RUN WHERE YOU THINK?
     print(backend.name), isa.layout.final_index_layout()
     |- ran on a simulator by accident?      -> that is the bug
     |- landed on a qubit in the dead list?  -> that is the bug (section 12.3)
     v
  2. DOES IT FAIL IN SIMULATION TOO?
     Run the SAME circuit on a noiseless simulator.
     |- fails there too  -> IT IS A BUG. Stop. Go to Chapter 26.
     v                      (noise cannot be the cause of a failure that
     |                       survives the removal of noise)
  3. HOW FAR FROM THE NOISELESS REFERENCE?
     ratio = measured / reference
     |- ratio ~ 1.0        -> noise. Proceed to mitigation (Ch. 13).
     |- ratio ~ 0.5, or ~0 -> structural. Check apply_layout (Ch. 7 section 7.6).
     v
  4. IS THE DEVIATION THE RIGHT SIZE?
     Build an error budget from calibration data (Ch. 2 Case Study 2).
     |- within 2x of prediction -> noise, explained. Done.
     |- 10x larger              -> not noise. Check routing overhead (Ch. 10 CS1)
     |                             and the layout score (section 12.3).
     |- much SMALLER            -> you probably ran a simulator. Back to step 1.
     v
  5. WHAT SHAPE IS THE DEVIATION?
     Two axes (Ch. 11 section 11.7):
     |- impossible outcomes, balanced peaks -> depolarizing or readout
     |     -> run the GATE-FREE circuit to separate them
     |- no impossible outcomes, tilted      -> T1
     |- both, scaling with duration         -> thermal relaxation
     |- neither, and it still looks wrong   -> MEASURE ANOTHER BASIS.
           The computational basis is blind to phase (Ch. 11 section 11.7).

Steps 1 and 2 are free and resolve most cases. They are also the two people skip.

12.7.1 When hardware disagrees with simulation

Step 2 handles the clean case: it fails in simulation too, so it is a bug. The harder case is the other branch — it works in simulation, it fails on hardware, and the gap is larger than noise plausibly explains. People reach for physics here, and the physics is almost never the answer.

Work the list in cost order.

1. Which simulation? §12.2.1 established that "the device noise model" is not one thing. NoiseModel.from_backend symmetrizes readout and gives qubit 84 the matrix [[0.5, 0.5], [0.5, 0.5]], producing {'0': 2054, '1': 2042}. SamplerV2(mode=backend) honours the asymmetry and produces {'1': 4096}. Same backend, same circuit, same snapshot, two different physics. Before comparing anything, say which path you ran.

The diagnostic is one line: change the seed. If the distribution does not move, nothing is being sampled, and you are looking at a deterministic effect that a stochastic model would have smeared.

2. Are the two circuits the same circuit? A noiseless simulator has no coupling map, so it never routes and never inserts a SWAP. The hardware ran the ISA circuit. Chapter 39 §39.6 measured what that difference can be: a 14-qubit ansatz containing 28 logical two-qubit gates transpiled to anywhere from 49 to 112 physical ones depending on the seed. If isa.count_ops() and the logical circuit's op counts differ by a factor of four, you are not comparing simulation to hardware — you are comparing two different circuits. Simulate the ISA circuit, not the source.

3. Are they on the same qubits? The simulator ran on virtual qubits $0 \ldots n-1$, which are all identical and all perfect. The hardware ran on whatever final_index_layout() reports. Given §12.2's 288× spread, "the same circuit on different qubits" is a bigger difference than most bugs.

4. Does the model contain the dominant channel? A gate-error noise model has no term for a 10.55 μs circuit idling on a 2.6 μs $T_2$ qubit, and §12.3's coherence budget put that at 1.7% retained. It also has no term for the zz_ crosstalk of §12.2.4. And Chapter 11 §11.7 measured a channel — phase damping — that is completely invisible in the computational basis, so simulation and hardware can agree perfectly on every population while disagreeing about the state. If everything above checks out, measure another basis before concluding anything.

5. Is the disagreement bigger than the model's error bar? Chapter 30 measured this class of prediction landing within 12% of measured fidelity at the median. A 9% disagreement between simulation and hardware is not a disagreement. It is the model's resolution, and reading a story into it is the book's most-repeated error in its most seductive form.

Then the judgement, which is not symmetric:

When they disagree, the hardware wins as a measurement and the simulation wins as a diagnosis. The hardware is the ground truth about what happened; it is also mute about why. The simulation is wrong about what happened and is the only one of the two you can interrogate — remove a gate, zero a channel, swap a layout, and watch what moves.

What not to do: tune the noise model until it matches. The moment you fit parameters to the observed result, the model stops predicting and starts describing, and you have converted your only independent check into a restatement of the data. Chapter 30's 12% is the honest bar. If a model has to be tuned to reach agreement, report the tuning, and report what it was before.

⚠️ Common Pitfall — Step 2 is the one that saves the most time, and it is almost never done first.

"Does it fail in simulation too?" costs one line and eliminates an entire hypothesis. A failure that survives the removal of noise is not a noise failure — that inference is airtight, and it immediately redirects the whole investigation.

This book has now hit the same pattern four times: Chapter 7's layout trap, Chapter 8's parameter ordering, Chapter 10's routing overhead, and Chapter 8's Case Study 1 team who tried four physics explanations before checking their pipeline. In every case a noiseless simulation would have reproduced the failure in seconds, and in every case it was tried late or not at all.

Check the pipeline before the physics.

🔀 In Another Framework — the procedure ports, the accessors do not, and on some hardware four of the five checks are empty.

Nothing in §12.7 is Qiskit-specific. What is Qiskit-specific is backend.target and backend.properties(), and every stack solves that differently.

Cirq keeps connectivity and calibration apart. A device object carries its coupling graph as metadata — a NetworkX graph you walk exactly as §12.3 walks a CouplingMap — while Google's calibration arrives from the engine as a mapping keyed by metric name, indexed by qubit tuples. There is no qubit.t1 attribute to reach for; you ask for a named metric and get a value or a KeyError. The preflight is the same five checks against a dictionary instead of an object.

PennyLane is device-agnostic by design and therefore has no calibration API at all. Run qml.device("qiskit.remote", backend=...) and the query is still Qiskit's, reached through the wrapped backend. The layer that makes PennyLane portable is precisely the layer that hides what this chapter needs — which is a fair trade for writing one ansatz that runs everywhere, and a bad one for choosing qubits.

Braket exposes a provider-specific properties block, and "provider-specific" is load-bearing: two vendors on the same service report different fields, so a preflight written against one will KeyError against the other. Write it defensively.

And the interesting case is a trapped-ion device, where the checklist collapses. Connectivity is all-to-all, so there is no coupling graph to walk, no routing, no SWAP overhead, and no layout variance — Chapter 39 §39.6's 2.03× spread simply does not exist there. Checks 1, 2 and 3 of §12.3's list become vacuous. What does not go away is check 5: trapped-ion gate times are orders of magnitude longer, so the coherence budget stops being a footnote and becomes the binding constraint. And the cost model moves with it — Chapter 39 priced the same VQE run at $185,542 on trapped-ion hardware against $50 under a per-minute superconducting model.

The transferable content is the ordering, not the code: refuse before you submit, rank before you choose, and predict before you look.

🧱 Project Checkpointbackends.py v3: the hardware path, with a preflight.

Three additions, all from this chapter.

device_health(backend) returns the calibration spread and the lists of unusable qubits and dead gate pairs. Run it before any session; it takes a second and it has caught a dead qubit in every device snapshot the book has examined.

best_layout(backend, n) enumerates connected paths, scores them against calibration data, and returns the best. Measured: it separates a 97.3% layout from a 28.4% one.

preflight(backend, layout) refuses to submit when the chosen qubits include a broken one, raising with the specific qubit and its error rate rather than letting the run waste queue time and return noise.

And submit() now records the job ID, the backend name, the layout, the layout score, and the date alongside every result — completing the provenance record Chapter 10 started.

12.8 Summary

Do not choose a backend by qubit count. Compare median two-qubit gate error, median readout error, and $T_1$/$T_2$. Across four current devices these spanned 2.8× in gate error, and the gate sets differ (ecr versus cz). Which metric matters depends on your circuit: shallow circuits are readout-dominated, deep ones gate-dominated.

The spread within a device dwarfs the spread between devices. On one 127-qubit chip: readout error 0.0029 to 0.50 (171×), two-qubit gate error 0.0035 to 1.0 (288×), $T_2$ 2.6 μs to 489 μs (185×). Twelve qubits were unusable and nine gate pairs were dead. Choosing good qubits matters roughly a hundred times more than choosing a good device.

readout_error is an average of $P(1|0)$ and $P(0|1)$, and the averaging hides things. Qubit 84's 0.5000 does not mean "coin flip" — it means $P(1|0) = 1$, $P(0|1) = 0$: stuck at 1, returning 1 from either input on every shot. $(1+0)/2 = 0.5$ is exactly what a stuck qubit averages to. Qubit 92's 0.3406 is really 1.3% one way and 67% the other. Check both directions in your preflight, and note that NoiseModel.from_backend symmetrizes while SamplerV2(mode=backend) does not — so the two paths simulate qubit 84 differently.

Third time in this book that a summary statistic hid what mattered (Chapter 2's asymmetry, Chapter 11's phase damping, now the averaging). A summary statistic is a lossy compression.

Score your layouts. Enumerating all 394 connected 3-qubit paths and scoring them against calibration data takes under a second and reveals a 132× spread in predicted error. Measured on a GHZ state: 97.3% correct on the best triple, 28.4% on the worst — a factor of 3.4, same circuit, same chip, same second.

The score is crude and does not need to be accurate — it needs to rank, and it does.

Run a preflight check before every submission: refuse to submit onto a qubit with readout error above 10% or a gate pair above 5%. Ten lines, and it would have caught Chapter 4's dead qubit immediately.

But 288× is two claims wearing one number, and the chapter separates them: the max of 1.0000 is a sentinel for a dead link, not a measured gate error. Nine of 144 links are dead (6.3%); among the 135 live ones the spread is 33.8×. Against the between-device 2.8×, that is twelve times the leverage, not a hundred. And after preflight removes the dead links, the 394 candidate three-paths narrow from a 131.9× score spread to 4.4× — a 5.9× range in predicted infidelity between the best and worst acceptable layout. Refusing broken hardware is the large, free half; choosing among the working hardware is the smaller, cheap half. Report them separately.

The score is not arbitrary and it is not a fidelity. Decomposed, $\text{score} \approx -\ln F + 2\sum e_\ell$ — the predicted log-infidelity with the gate term inflated 3×. The same terms recombined multiplicatively predict 0.970641 against a measured 0.9727 and 0.919924 against 0.9207, two of three within a quarter of a percent. Never exponentiate the score; compute $F$ separately. The ×3 inverts the true ranking only when one layout's readout advantage lies between one and three times the other's gate advantage — the shallow-circuit regime, so the crude score is least trustworthy on the simplest circuits.

Add duration to the preflight, because nothing else can see decoherence. A circuit of duration $T$ needs $T_2 \ge T/\ln(1/f)$ to retain a fraction $f$. Using Chapter 39's measured durations against this device's $T_2$ distribution: no qubit of the 127 can hold a 10.55 μs circuit to 99% (it needs 1,049.7 μs and the best on the chip is 488.8 μs), and on the worst qubit that circuit is 4.06 time constants long and retains 1.7%. On this device one in five three-qubit layouts and one in three five-qubit layouts fail preflight, and the twelve bad qubits cluster — they spoil fewer distinct layouts than a uniform model predicts, and spoil them harder.

Decide the backend before you look at the result. Four devices and five metrics is enough freedom to justify any choice after the fact, and a device selected post hoc turns a measurement into a maximum over four. Characterise the circuit first, name the dominant metric in writing, fix a tie-break, set the acceptance threshold from an error budget, record the rejected alternatives, and if you switch devices, report both numbers.

Jobs are asynchronous. Save the ID, walk away, retrieve later. Never cancel and resubmit. Use least_busy() for iteration and a chosen backend for results. Sessions keep your queue position across an optimizer loop and are metered while open.

The three modes are three answers to "how many times do you pay the queue?" A 4,096-shot Bell job is 6.92 ms of device time; at a representative five-minute queue that is a utilization of 2.31 × 10⁻⁵, or 43,340× wall clock. Batching 100 independent circuits turns 8.33 hours into 5.01 minutes — 99.8×, linear in $n$ until $n \approx t_q/t_d \approx 43{,}300$, so it never saturates in practice. Sessions exist because a variational loop cannot batch across iterations; Chapter 39's 120-iteration VQE runs ten hours as jobs and about five minutes in a session. Batch within the iteration, session across them. And batching buys wall clock, not money — the shot count is unchanged.

Record nine fields with every hardware result. Four are Tier 1, provider-side, and unrecoverable once the moment passes: job_id, execution_timestamp, calibration_snapshot, physical_qubits. Five are Tier 2, reconstructible but expensive: qiskit_version, optimization_level, seed_transpiler, shots, mitigation settings. Add this chapter's two: the layout score and the preflight output. A fixed seed is not a fixed layout — the layout pass scores against current error rates, so the seed is deterministic while the function it seeds is not stationary.

When hardware disagrees with simulation, work the list before the physics: which simulation (NoiseModel.from_backend symmetrizes, SamplerV2 does not); is it the same circuit (28 logical two-qubit gates became 49–112 physical ones in Chapter 39's sweep); the same qubits; does the model contain the dominant channel; and is the gap bigger than the model's own 12% error bar. Then: the hardware wins as a measurement, the simulation wins as a diagnosis — and never tune the noise model until it matches, because that converts your independent check into a restatement of the data.

The decision procedure: ① did it run where you think? ② does it fail in simulation too? ③ how far from the noiseless reference? ④ is the deviation the right size against an error budget? ⑤ what shape is the deviation?

Step 2 is nearly free and eliminates an entire hypothesis. A failure that survives the removal of noise is not a noise failure. This book has now seen four separate bugs that a noiseless simulation would have caught in seconds, each of which was investigated as physics first.

Check the pipeline before the physics.


Next: Chapter 13 — fighting back. Readout mitigation first, because Chapter 11 measured it as the highest-return technique; then dynamical decoupling, zero-noise extrapolation, probabilistic error cancellation, and an honest accounting of what each one costs in extra circuit executions.