Evaluation
A design is judged by numbers: how long its programme runs, how hot it makes its ions, how much hardware it takes, and how often the logical qubit it stores is lost. On this website every one of those numbers is a term of a small language, printed on this page, evaluated on three texts: the device, the programme, and the evaluation. Nothing else is read, so every number on the leaderboard can be recomputed from the files it came from, and traced to the line of text that defines it.
The language is the Rules page’s, extended. A rule is a formula that holds or fails; an evaluation adds named numbers (metric), the assertions a design must meet to be ranked (require), and noise (channel): a clause that says which Pauli error goes where in the circuit a run becomes. The noisy circuit the Goal 1 board samples is the programme’s stabilizer translation with those clauses applied. The grader reads these texts: every number it publishes — the metrics, the hardware budget, the noisy circuit and its error budget — is computed by the interpreter of the language from the text on this page, and the same interpreter runs in every workspace. The Design page reads the same texts in the browser with a second interpreter, held to the first metric by metric: every number it shows (cost, steps, runtime, heat, DACs, the noise each budget line books) is a metric of these texts, and its Report checks itself against the grader’s values.
- Three texts and one function
- The evaluation language
- The words of an evaluation
- The state a programme leaves
- Speed: how long a programme runs
- Heat: what the motion costs
- Hardware: electrodes, switches and DACs
- From a run to a stim circuit
- The noise model, qccd-noise@2
- A Goal 1 entry, recomputed
- The noiseless check
- The logical error rate and its interval
- Reading the Goal 1 board
- What is proved, decided, computed and estimated
- Writing your own evaluation
Three texts and one function
where μ gives every metric a value, ρ gives every requirement a verdict, and C is the noisy circuit: a stim circuit with the experiment’s detectors. The logical error rate is a statistic of C, LER(C) = Pr[the decoder’s correction leaves a logical observable wrong].
In words: the device and the programme are replayed once, which fixes where every ion is, how hot it is and what the clock says at every instant; the evaluation is then read over that record.
Proof sketch. The replay is a deterministic transition system: each instruction’s duration and heat are read off the device’s tables (below). Every word of the vocabulary reads the device, the programme, the run the replay produced, or a parameter written in E; the interpreter evaluates terms by structural recursion, with no clock, no random number and no file besides the three. ∎
So the grader is an interpreter of the text, not an authority: a second interpreter must agree with it, and where it does not, one of them is wrong in a way the text decides.
Until 2026-10-26 the grader wrote its circuit with a hand-written extraction; since then it reads the text. The switch changed no circuit: on every Goal 1 design we hold, 71 in all, from the 10-ion repetition code to the 180-ion bivariate bicycle code, the circuit the text writes and the one the old extraction wrote are the same qubit by qubit (what “the same” means), every channel of the error budget agrees to 10−9, and so does every metric the board shows. Every logical error rate published before the switch is therefore a sample of the circuit on this page.
| release | designs | same circuit | same metrics |
|---|---|---|---|
bb18xz_mem@1 | 6 | 0 | 0 |
bb72seq_mem@1 | 2 | 0 | 0 |
bb90seq_mem@1 | 1 | 0 | 0 |
rep3xz_mem@1 | 12 | 0 | 0 |
rep5xz_mem@1 | 11 | 0 | 0 |
shorxz_mem@1 | 5 | 0 | 0 |
steanexz_mem@1 | 6 | 0 | 0 |
surface3xz_mem@1 | 11 | 0 | 0 |
surface5xz_mem@1 | 14 | 0 | 0 |
surface7xz_mem@1 | 3 | 0 | 0 |
The evaluation language
An evaluation is a text file. Its terms and formulas are the rule language’s, unchanged — quantifiers over finite sets, comparisons, arithmetic, count, sum, max, min and set builders — with one more term, if C then a else b. What it adds are items:
file = { item } ;
item = "evaluation" STRING | "title" STRING | "about" STRING
| "include" STRING | "clock" STRING | "rules" STRING | "rank" NAME
| "param" NAME "=" expr
| "define" NAME [ "(" NAME { "," NAME } ")" ] "=" expr
| metric | requirement | channel ;
metric = "metric" NAME STRING { "unit" STRING | "better" ( "low" | "high" ) | "clock" STRING
| "group" STRING | "about" STRING | "source" STRING }
"=" expr ;
requirement = "require" ID STRING { "about" STRING | "source" STRING } formula ;
channel = "channel" NAME STRING { "about" STRING | "source" STRING }
( "before" | "after" ) binders [ "where" formula ] ":"
NOISE "(" expr ")" "on" expr [ "counted" "as" budget ] ;
budget = NAME | NAME "=" expr { "," NAME "=" expr } ;
NOISE = "X_ERROR" | "Y_ERROR" | "Z_ERROR" | "DEPOLARIZE1" | "DEPOLARIZE2" ;
primary = ... the rule language's primaries ...
| "if" formula "then" expr "else" expr ;
| item | what it says |
|---|---|
param n = term | a number the evaluation fixes, said once, with where it comes from |
define f(x, …) = term | a named term, with or without arguments; it may use earlier names, never itself |
metric n "title" … = term | a number every design gets, with its unit and which way is better; with clock "table", on a replay at that table’s operating points |
require ID "title" formula | what must hold for a design to be ranked |
channel n "title" after x in D where C: OP(p) on S | noise: for every binding of x that satisfies C, the Pauli channel OP with probability p on the ions S, just after (or before) what x names; counted as k books its expected faults under the budget line k, and counted as k₁ = t₁, k₂ = t₂ shares them out in proportion to the terms |
include, clock, rules, rank | another evaluation’s items; the operating-point table the replay prices at; the rule set the programme is judged by; the metric a board ranks by |
after x₁ in D₁, …, xₙ in Dₙ where C: OP(p) on S and every binding of x₁…xₙ at which C holds, the circuit carries OP(p) q₁ … qₘ, the q being the qubits of the ions S, immediately after (for before, immediately before) the translation of what x₁ names; x₁ ranges over operations or over steps. A probability of 0, or no ions, writes nothing.Goal 1’s evaluation, whole. It takes the board’s metrics and hardware budget from board.eval and its noise from qccd-noise@2, sets the release’s budget and adds three requirements of its own. Download it, or board.eval, metrics.eval, qccd-noise@2.eval and qccd-noise@1.eval.
evaluation "goal1" title "Goal 1: the best QEC memory under 200 ions" about "Every curated memory experiment under 200 ions, compiled for a design, run under qccd-noise@2 on the cited Helios-class physics, and ranked by its logical error rate per round per logical qubit." include "board" include "qccd-noise@2" clock "quantinuum" rules "standard" rank ler_per_round_per_logical # the release's budget: its fixed physics, which a design may not change param max_dacs = 128 param max_junctions = 200 param max_ions = 200 require G1 "Every rule of the standard rule set holds" about "The programme is judged by the Rules page's standard set, rule by rule." rules_hold() require G2 "No more than 200 ions" about "The board's own filter: an entry over it is graded, and not listed." n_ions <= max_ions require G3 "With its noise taken out, the circuit is the experiment" about "Every detector and every logical observable has a fixed value, and it is 0: the value the experiment's own circuit gives it." noiseless_ok()
The words of an evaluation
Every word a term may use, with what it means. A word the rule language also has means the same thing here. The instants are the evaluation’s own: the start and the end of every step, because a number like the hottest an ion gets needs the state at the end of a step, before a cooling resets it.
The device
sites | Every place an ion can stand: the traps, the docks, the slots of a loop (the nodes the device declares as sites). |
junctions | The nodes where three or more rails meet, whatever the device calls them. |
nodes | Every node of the device: its sites and its junctions. |
rails | The rails (segments) along which ions are carried between nodes. |
capacity(x) | How many ions the node or rail x may hold at once, as the device declares it. |
degree(n) | How many rails meet at node n. |
zone(s) | The zone type of site s. |
can(s, a) | Whether site s is equipped for ability a: "gate", "spam" (preparation and measurement) or "cool". |
The device's wiring
wiring(key, d) | What the device's wiring block declares for key (electrodes_per_trap, electrodes_per_junction, compensation_electrodes_per_trap, shim_per_dac, dacs_dynamic, scheme), or d when it declares nothing. |
budget(key, d) | The device budget's value for key (max_dacs, max_junctions, junction_electrode_multiplier), or d when it has none. |
channel_map() | Whether the device declares a channel map: which control channel drives each electrode role of each site. |
grouping() | How the declared map groups its channels: "broadcast" (one channel per electrode role for every site), "row", "column", "row_column", "direct" (every site its own) or "explicit"; none without a map. |
shared_channels() | The channels of the declared map that drive more than one site, counted from the map: one per role and bank for a broadcast plane, one per row or column for a row or column plane, one per site for a direct one, one per entry for an explicit list. |
compensation_channels() | The compensation (shim) DACs of the declared map: the sites times their shim electrodes, divided by the demultiplexer, rounded up. |
map_electrodes() | The electrodes of the declared map: every site's role and shim electrodes and every junction's. |
map_switches() | The switches of the declared map: two per electrode when each site has its own switch, none otherwise. |
driven(s) | How many channels of the declared map drive site s (0 without a map). |
The programme
steps | The steps of the programme: one instruction each, run one after another. The preparation and the appended readout are not steps of the programme. |
operations | Every operation of the programme, of any kind. |
two_qubit_gates | Every gate on two ions together: one per pair of a gate step. |
single_qubit_gates | Every gate on one ion: one per ion of a gate step, the frame change VZ included. |
measurements | Every measurement of an ion: the programme's, and the experiment's appended readout. |
resets | Every reset of an ion to |0⟩. |
coolings | Every cooling operation. |
moves | Every transport of one ion in one step, from where it stood to where it stops. |
preparations | The preparation of every ion in |0⟩ before the first step: one operation. |
qubit_operations | Every operation that acts on an ion's qubit: the gates (a frame change included), the measurements (the appended readout's too) and the resets. |
hops | Every rail crossed by an ion: one move over three rails is three hops. |
readout | The experiment's appended readout, as one step after the last (empty when the programme reads the data itself). |
ions | Every ion the programme places. |
kind(x) | What operation x is ("gate2", "gate1", "measure", "reset", "cool", "move", "prepare"), or what instruction step x is ("init", "simd", "gate", "measure", "reset", "cool", "barrier", and "readout" for the appended readout). |
ions(x) | The ions operation x acts on or carries, in order (control first for a pair); for a step, the ions of its operations. |
operated(k) | The ions whose qubit step k acts on: named by its gates (a frame change included), measurements or resets. Carrying an ion or cooling it does not operate on its qubit. |
gate(o) | The gate operation o fires: "MS", "R", "VZ", or an abstract Clifford ("CX", "H", ...). |
basis(m) | The basis measurement m reads in: "Z" for the programme's, the experiment's own basis for its appended readout. |
site(o) | Where operation o happens: for a gate, measurement or reset, the site its (first) ion stands in when it starts; none for transport and cooling. |
step(o) | The step operation o belongs to. |
cls(k) | The movement class transport step k drives (none for other steps). |
from(h) | Where hop h picks its ion up. |
to(h) | Where hop h (or move h) leaves its ion. |
path(o) | The nodes move o carries its ion through, first to last. |
crossed(o) | The junctions move o carries its ion into, on the way or to stop, once for every time it enters one. |
move(h) | The move hop h is part of. |
entails(o) | The splits and merges move o is charged: a split where it leaves a site other ions stay in or leave for elsewhere, a merge where it arrives where ions stay or others arrive from elsewhere, and both for a dock -- a class that declares them, or a hop onto a spur off a closed loop. Once per move in each cycle, however many rails it crosses; a rotation, every slot moving into a slot vacated in the same cycle, has neither. |
cycles(k) | How many machine cycles step k drives: |delta| for a rotation by delta slots, 1 for any other step that takes time, 0 for init and barrier. |
depth(k) | How deep step k is: for each of its cycles, its longest route -- one for every rail crossed and every split or merge the move is charged -- added up over the cycles; 1 for any other step that takes time, 0 for init and barrier. |
movers(k) | How many ions step k carries. |
rotation(k) | Whether step k turns a loop as a whole: its movement class is one of the device's rotations (named rotate...). |
loop_riders(k) | How many ions a transport step k counts as moving, as the leaderboard counts it: for a rotation of a closed loop, every ion the programme placed on a closed loop at its start; for any other transport step, its participants. |
Instants and the state
deposited(c) | Every quantum the run deposited from source c, over every ion and the whole execution, before any cooling took it away: "shuttle" (rails), "junction", "split_merge", "gate" or "anomalous" (the clock). |
instants | The start and the end of every step, the preparation's and the readout's included. |
start(x) | The instant step x (or operation x's step) begins. |
end(x) | The instant step x (or operation x's step) is over. |
final() | The end of the programme's last step. |
time(t) | The clock at instant t: the durations of every step before it, added up. |
duration(k) | How long step k (or operation k's step) takes on the clock: the sum of its cycles, each as long as its slowest participant. |
position(i, t) | The node where ion i stands at instant t. |
occupancy(x, t) | How many ions stand in node x at instant t. |
nbar(i, t) | Ion i's motional energy n̄ at instant t, as the replay accrues it: every rail, junction, split and merge it is carried through, and every microsecond for every ion, since it was last cooled. At the end of a cooling step it is the heat before the reset; at the start of the next step, after it. |
waited(i, o) | How long ion i has waited, when operation o starts, since a step last operated on it (or since the start): the durations of the steps between, which carried it, cooled it or left it alone. |
The device's laws
primitive(p, f) | Field f of the device's primitive p, as its physics declares it: primitive("measure", "fidelity"), primitive("ms_gate", "us"), ... |
slope(p) | The k of primitive p's error_vs_quanta law "linear:k": how much its error grows per quantum of n̄. |
chain_reference(p) | The N_ref of primitive p's error_vs_chain law "murali:N_ref": the chain length its error is calibrated at; none when it declares no chain law. |
coherence_time() | The qubit's coherence time T₂ as the device's species block declares it (T_coh_s); none when it declares none. |
heating_rate() | The anomalous heating every ion accrues per microsecond, moving or not (the physics' quanta per millisecond, over 1000). |
The experiment
rounds() | How many rounds of syndrome extraction the experiment runs. |
logical_qubits() | How many logical qubits the experiment protects: its observables, halved when it measures both bases (one Z and one X observable per logical qubit). |
observables() | How many logical observables the experiment declares. |
distance() | The code distance the experiment's circuit is built to. |
The sample
shots() | How many times the sampler ran the noisy circuit. |
failures() | In how many of those shots the decoder's correction left some logical observable wrong. |
noiseless_ok() | Whether the circuit, with its noise taken out, gives every detector and observable a fixed value, and that value is 0. |
rules_hold() | Whether every rule of the evaluation's rule set holds on the programme (the Rules page's verdict). |
Arithmetic
ln(x) | The natural logarithm. |
exp(x) | e to the power x. |
sqrt(x) | The square root. |
sin(x) | The sine, of an angle in radians. |
pow(x, y) | x to the power y. |
ceil(x) | The least whole number not below x. |
abs(x) | The size of x, without its sign. |
min(x, y, ...) | The smallest of its arguments. |
max(x, y, ...) | The largest of its arguments. |
pi | π. |
size(A) | How many things set A holds. |
The state a programme leaves
Every metric reads the run, and the run is the replay: the semantics of the hardware language, the same one the rules judge. It is worth writing out, because every number below inherits it.
A transport step lasts as long as its slowest ion; a rotation by δ slots is |δ| such cycles. A gate step lasts τMS or τ1q (a frame change VZ three one-ion pulses, unless the device declares a one-pulse Z gate); a measurement, reset or cooling its own τ; init and barrier no time at all. Splits and merges are what a move entails: leaving a site where other ions stay, joining one where ions wait, or docking.
In words: the clock adds up the steps; a step waits for its slowest ion; every rail, junction, split and merge heats the ion carried through it, every microsecond heats every ion, and a cooling sets the ions it cools back to zero at the end of its step.
The Rules page’s walk through a T-junction, on a 2×3 lattice: six lattice nodes, of which J0_1 and J1_1 are degree-3 T-junctions and the other four degree-2 corners, with one trap site (T…) on every wire between them. Every cell is the term in its column’s head, evaluated at that row’s step k. The walk is charged two rails, the junction’s entry and the merge into the trap where d1 waits; every ion heats a little with the clock; the cooling takes both back to zero at the end of its step, and the gate meets them cold.
p.init({"d0": "T0_0v", "d1": "T0_1h"})
p.shuttle("d0", ["T0_0v", "J0_1", "T0_1h"])
p.cool()
p.gate("CX", [["d0", "d1"]])| step k | duration(k) | time(end(k)) | nbar("d0", end(k)) | nbar("d1", end(k)) | position("d0", end(k)) |
|---|---|---|---|---|---|
| init d0@T0_0v, d1@T0_1h | 0 | 0 | 0 | 0 | T0_0v |
| move (shuttle) d0 T0_0v→J0_1→T0_1h | 185 | 185 | 9.209 | 0.00925 | T0_1h |
| cool all | 300 | 485 | 9.224 | 0.02425 | T0_1h |
| gate CX d0,d1 @ T0_1h | 25 | 510 | 0.00125 | 0.00125 | T0_1h |
Two clocks appear on this page. The small examples run on the website’s default device document; Goal 1 runs on the cited Helios-class physics every one of its releases fixes (clock "quantinuum"), and a design may not change it.
Goal 1’s clock, primitive by primitive
| primitive | time | heat / error | source |
|---|---|---|---|
| carry one ion along one rail | 94 µs | 0.0075 quanta | arXiv:2206.11888 Fig. 1 and Table II |
| split a chain | 128 µs | 1 quantum | arXiv:2003.01293 Table II |
| merge two chains | 128 µs | 1 quantum | arXiv:2003.01293 Table II |
| swap two ions in a chain | 200 µs | 2 quanta | arXiv:2003.01293 Table II |
| cross a junction of 3 rails | 0 µs | 0 quanta | arXiv:2206.11888 Table II |
| cross a junction of 4 rails | 0 µs | 0 quanta | arXiv:2206.11888 Table II |
| the two-ion gate MS | 70 µs | ε₀ = 0.00079, linear:9.5e-4, murali:2 | arXiv:2511.05465 Table II and p.5; arXiv:0810.0670 Sec. 5.2 |
| a one-ion pulse R | 5 µs | error 2.5e-05 | arXiv:2511.05465 Table II; duration arXiv:2003.01293 Table III |
| a readout | 120 µs | error 1e-06 | arXiv:2511.05465 Table II; Quantinuum Helios-1E emulator parameters (p_meas); duration arXiv:2003.01293 Table III |
| a reset | 10 µs | error 0.0005 | Quantinuum Helios-1E emulator parameters (p_init); arXiv:2511.05465 Table II; duration arXiv:2003.01293 Table III |
| a cooling (every ion at once) | 300 µs | n̄ := 0 | arXiv:2511.05465 p.5 |
| anomalous heating, every ion | 0.029 quanta/ms | arXiv:2206.11888 Fig. 3 caption |
The examples’ clock
| primitive | time | heat / error | source |
|---|---|---|---|
| carry one ion along one rail | 5 µs | 0.1 quanta | 2510.23519 |
| split a chain | 80 µs | 6 quanta | 2510.23519 |
| merge two chains | 80 µs | 6 quanta | 2510.23519 |
| swap two ions in a chain | 18 µs | 1 quantum | 2605.25118 |
| cross a junction of 3 rails | 100 µs | 3 quanta | 2510.23519 |
| cross a junction of 4 rails | 120 µs | 3 quanta | 2511.15910 |
| the two-ion gate MS | 25 µs | ε₀ = 0.00184, linear:2.0e-3, murali:2 | 2305.03828 |
| a one-ion pulse R | 5 µs | error 2.5e-05 | 2305.03828 |
| a readout | 120 µs | error 0.0016 | 2305.03828 |
| a reset | 50 µs | error 0.005 | 2510.23519 |
| a cooling (every ion at once) | 300 µs | n̄ := 0 | 2606.06455 |
| anomalous heating, every ion | 0.05 quanta/ms | 2605.25118 |
Speed: how long a programme runs
Time is the first thing a design spends. Under qccd-noise@2 every microsecond an ion is not operated on is memory error, and the coherent part grows with the square of each wait, so a slow schedule pays twice. The speed metrics read the clock and the steps:
Execution timeT
metric T = time(final()) / 1000
How long the programme runs on the device's clock: its steps one after another, each as long as its slowest participant.
Execution time, on QCCDSim's clockT_jones
metric T_jones = time(final()) / 1000
The same execution time, priced at the operating points of the qccdsim_jones table: QCCDSim's durations with Jones and Murali's heating. The round-time boards rank by it.
Execution time, on the transport-excitation clockT_transport
metric T_transport = time(final()) / 1000
The execution time at the transport_excitation table's operating points (Munoz and colleagues): slower, colder transport.
Execution time, on Goal 1's clockT_quantinuum
metric T_quantinuum = time(final()) / 1000
The execution time at the quantinuum table's operating points, the cited Helios-class physics every Goal 1 release fixes.
Transport timetime_transport
metric time_transport = sum(duration(k) for k in steps where kind(k) = "simd") / 1000
The part of the execution time spent carrying ions.
Gate timetime_gates
metric time_gates = sum(duration(k) for k in steps where kind(k) = "gate") / 1000
The part spent on laser gates, the frame changes VZ included.
Cooling timetime_cooling
metric time_cooling = sum(duration(k) for k in steps where kind(k) = "cool") / 1000
The part spent cooling ions back toward their motional ground state.
Readout and reset timetime_spam
metric time_spam = sum(duration(k) for k in steps where kind(k) in {"measure", "reset"}) / 1000
The part spent measuring ions and preparing them in |0>.
Instructionsinstructions
metric instructions = count(k in steps)
How many instructions the programme has: one machine step each.
Two-ion gatestwo_ion_gates
metric two_ion_gates = count(g in two_qubit_gates)
How many times two ions are brought into contact for an entangling gate: every pair of every MS or two-qubit gate.
Transport instructionstransport_instructions
metric transport_instructions = count(k in steps where is_transport(k))
How many instructions carry ions.
Ions moved per transport instructionions_per_instruction
metric ions_per_instruction = if transport_instructions = 0 then 0 else sum(loop_riders(k) for k in steps where is_transport(k)) / transport_instructions
How much of the machine one waveform moves at once: the broadcast a design gets out of its wiring.
Transport costcost
metric cost = count(h in hops) + count(h in hops where degree(to(h)) >= 3) + sum(size(entails(o)) for o in moves)
Every rail crossed, every junction entered and every split or merge, counted once each.
Machine stepsdepth
metric depth = sum(depth(k) for k in steps)
The steps' depths added up: a transport cycle is as deep as its longest route, one for each rail it crosses and each split or merge it is charged; any other step that takes time is one deep.
define is_transport(k) = kind(k) = "simd" and (rotation(k) or loop_riders(k) > 0)
ions_per_instruction is how much of the machine one waveform moves: on a broadcast-wired device a rotation moves every ion on its loop for the price of one instruction, which is why the rings run their rounds in few instructions.
Four short programmes on the small devices of the Language and Rules pages, every value computed by the text above:
walk — a walk to a waiting ion, a cooling, a gate and a readout, on chain4:
p.init({"d0": "C3", "d1": "C0"})
p.shuttle("d0", ["C3", "C2", "C1", "C0"])
p.cool()
p.gate("CX", [["d0", "d1"]])
p.measure(["d0", "d1"])junction — the same, through a T-junction, on grid2x3:
p.init({"d0": "T0_0v", "d1": "T0_1h"})
p.shuttle("d0", ["T0_0v", "J0_1", "T0_1h"])
p.cool()
p.gate("CX", [["d0", "d1"]])pair — two ions carried together on one waveform, on race8:
p.init({"d0": "S0", "d1": "S4"})
p.simd("shuttle", [["d0", "S0", "S1"], ["d1", "S4", "S5"]])
p.simd("shuttle", [["d0", "S1", "S2"], ["d1", "S5", "S6"]])rotation — the whole loop turned by two slots, on race8:
p.fill() p.rotate(2)
| metric | unit | walk chain4 | junction grid2x3 | pair race8 | rotation race8 |
|---|---|---|---|---|---|
T | ms | 0.54 | 0.51 | 0.01 | 0.01 |
time_transport | ms | 0.095 | 0.185 | 0.01 | 0.01 |
time_gates | ms | 0.025 | 0.025 | 0 | 0 |
time_cooling | ms | 0.3 | 0.3 | 0 | 0 |
time_spam | ms | 0.12 | 0 | 0 | 0 |
instructions | count | 7 | 4 | 3 | 2 |
two_ion_gates | count | 1 | 1 | 0 | 0 |
transport_instructions | count | 3 | 1 | 2 | 1 |
ions_per_instruction | ions | 1 | 1 | 2 | 8 |
cost | model cost units | 4 | 4 | 4 | 16 |
depth | steps | 7 | 5 | 2 | 2 |
The rotation moves all eight ions in each instruction: its ions_per_instruction is 8, against 2 for the pair and 1 for the walks.
Heat: what the motion costs
Every operation on a trapped-ion machine is paid for in motional quanta. A two-ion gate shares a motional mode between its ions, and a hot mode blurs the spin-dependent force that entangles them, so the gate’s error grows with the heat it meets (rule R16), and rule R7 refuses a gate above the device’s budget. The device’s law is part of the metrics file:
define eps0 = 1 - primitive("ms_gate", "fidelity_at_n0") define kappa = slope("ms_gate") define Nref = chain_reference("ms_gate") define chain_factor(N) = max(max(N, 2) / ln(max(N, 2)), Nref / ln(Nref)) define chain_ratio(N) = chain_factor(N) / chain_factor(Nref) define ms_error(n, N) = if Nref = none or chain_ratio(N) = 1 then eps0 + kappa * max(n, 0) else (eps0 - kappa / 2) + kappa / 2 * chain_ratio(N) * (2 * max(n, 0) + 1) define gate_nbar(g) = max(nbar(i, start(g)) for i in ions(g)) define gate_chain(g) = occupancy(site(g), start(g))
ε(n̄, N) = ε₀ + κ·n̄ in a chain no longer than the reference; in a longer one, ε = (ε₀ − κ/2) + (κ/2)·r(N)·(2n̄ + 1), where r(N) is Murali’s laser-instability factor N/ln N relative to the reference length (arXiv:2004.04706, Eq. 1): the two forms are the same function at the reference, and a longer chain is never better than it.
Hottest any ion getspeak_nbar
metric peak_nbar = max(max(nbar(i, end(k)) for i in ions) for k in steps)
The most motional energy any ion carries at any moment of the execution, before a cooling takes it away: the hottest ion at the end of each step, and the hottest of those.
Hottest a two-ion gate startsgate_nbar_max
metric gate_nbar_max = if count(g in two_qubit_gates) = 0 then 0 else max(gate_nbar(g) for g in two_qubit_gates)
The hottest pair any two-ion gate meets; rule R7 caps it at the device's heat budget.
Mean heat at a two-ion gategate_nbar_mean
metric gate_nbar_mean = if count(g in two_qubit_gates) = 0 then 0 else sum(gate_nbar(g) for g in two_qubit_gates) / count(g in two_qubit_gates)
The hotter ion's n-bar, averaged over every two-ion gate.
Junction crossingsjunction_crossings
metric junction_crossings = count(h in hops where degree(to(h)) >= 3)
How many times an ion is carried into a node where three or more rails meet.
Heat put in by transporttransport_quanta
metric transport_quanta = deposited("shuttle") + deposited("junction") + deposited("split_merge")
Every quantum the rails, junctions, splits and merges deposited, on every ion, before any cooling took it away.
All the heat put intotal_quanta
metric total_quanta = deposited("shuttle") + deposited("junction") + deposited("split_merge") + deposited("gate") + deposited("anomalous")
The same, with the heat the gates deposit and the anomalous heating every ion accrues with the clock.
Coolingsn_coolings
metric n_coolings = count(o in coolings)
How many cooling operations the programme needs.
Summed two-ion gate errorgate_error_sum
metric gate_error_sum = sum(ms_error(gate_nbar(g), gate_chain(g)) for g in two_qubit_gates)
The device's gate error law summed over every two-ion gate, at the heat and chain length each meets: the heat's whole price.
The same four programmes. Both walks end by joining a waiting ion, and on this clock the merge is the dear part, 6 quanta against a tenth for a rail; the walk through the T-junction pays 3 more for the junction. Each still reaches its gate cold, because the cooling comes between the walk and the gate; with the cooling first, R7 would refuse the junction walk’s gate.
| metric | unit | walk chain4 | junction grid2x3 | pair race8 | rotation race8 |
|---|---|---|---|---|---|
peak_nbar | quanta | 6.32 | 9.224 | 0.2005 | 0.2005 |
gate_nbar_max | quanta | 0 | 0 | 0 | 0 |
gate_nbar_mean | quanta | 0 | 0 | 0 | 0 |
junction_crossings | count | 0 | 1 | 0 | 0 |
transport_quanta | quanta | 6.3 | 9.2 | 0.4 | 1.6 |
total_quanta | quanta | 6.354 | 9.251 | 0.401 | 1.604 |
n_coolings | count | 1 | 1 | 0 | 0 |
gate_error_sum | expected errors | 0.00184 | 0.00184 | 0 | 0 |
Hardware: electrodes, switches and DACs
The half of a design that is not time or heat is what it costs to build and drive. Each trap carries DC electrodes that shape its wells; each electrode is wired through a two-way switch; and each needs a digital-to-analogue converter (DAC) to play its waveform — one per electrode when wired directly, which is the first thing that does not scale. Broadcast wiring shares one DAC among every electrode that plays the same role, which holds the count near constant at the price that one cycle carries one motion (rule R22). The floors below are the deck’s array (pp. 19–20) and WISE (arXiv:2305.12773): a device may declare more, never less.
param least_electrodes_per_trap = 24 param least_compensation_per_trap = 8 param most_shims_per_dac = 100 param least_channels_per_site = 32
Junctionsn_junctions
metric n_junctions = count(n in junctions)
The nodes where three or more rails meet.
Places for ionsplaces
metric places = sum(capacity(n) for n in nodes)
How many ions the device can hold at once: every node's capacity, added up.
Electrodeselectrodes
metric electrodes = if channel_map() then map_electrodes() else n_sites * per_trap + n_junctions * per_junction
The DC electrodes that shape the wells: so many a trap, more at a junction, or as the channel map lists them.
Switchesswitches
metric switches = if channel_map() then map_switches() else 2 * (n_sites * per_trap + n_junctions * per_junction)
Every DC electrode is wired through a two-way switch: it follows the motion bank or the hold bank.
DACsdacs
metric dacs = broadcast_dacs + compensation_dacs
The digital-to-analogue converters that drive the electrodes: one an electrode when wired directly; under broadcast wiring a constant bank for the shared waveforms plus the compensation shims.
define scheme = wiring("scheme", "direct") define broadcast_wiring = scheme in {"wise", "broadcast_groups"} define per_trap = if channel_map() or broadcast_wiring then wiring("electrodes_per_trap", 24) else max(wiring("electrodes_per_trap", 24), least_electrodes_per_trap) define per_junction = if channel_map() or broadcast_wiring then wiring("electrodes_per_junction", 48) else max(wiring("electrodes_per_junction", 48), budget("junction_electrode_multiplier", 2) * per_trap) define least_compensation = ceil(n_sites * least_compensation_per_trap / most_shims_per_dac) define least_driven = min(driven(s) for s in sites where driven(s) > 0) define broadcast_dacs = if channel_map() then (if count(s in sites where driven(s) > 0) > 0 and least_driven < least_channels_per_site then ceil(shared_channels() * least_channels_per_site / least_driven) else shared_channels()) else if broadcast_wiring then max(wiring("dacs_dynamic", 0), least_channels_per_site) else 0 define compensation_dacs = if channel_map() then max(compensation_channels(), least_compensation) else if broadcast_wiring then max(ceil(n_sites * wiring("compensation_electrodes_per_trap", 8) / wiring("shim_per_dac", 1)), least_compensation) else electrodes
Written out from the definitions above, with N sites and J junctions:
with p, q the declared electrodes per trap and per junction, d the declared broadcast DACs, c the shims per trap, M the demultiplexer’s ratio, B and C the shared and compensation channels the map lists, and b the fewest channels driving any site.
Every task release fixes a hardware budget with its physics, and every board judges a design’s device by two requirements of the same language. The grader’s device stage evaluates them with the release’s numbers; a design over budget keeps its numbers and is not ranked.
evaluation "board" title "A board's measure: the metrics, and the hardware a design may use" about "Every task release fixes a hardware budget with its physics: at most so many DACs and so many junctions. A design over it keeps its numbers, and is not ranked. The grader judges every entry's device by these two requirements, with the release's numbers." include "metrics" # the device's own budget block, unless the release sets these (the grader does) param max_dacs = budget("max_dacs", none) param max_junctions = budget("max_junctions", none) require B1 "The wiring fits the DAC budget" about "The DACs the wiring needs, counted with the physics' floors, are at most the budget's." max_dacs = none or dacs <= max_dacs require B2 "The device fits the junction budget" max_junctions = none or n_junctions <= max_junctions
The small devices and the devices the repository ships, by the text above; the last column is requirement B1 of every board, dacs <= max_dacs, with Goal 1’s max_dacs = 128. The grader’s device stage evaluates exactly these two requirements, with the release’s numbers.
| device | wiring | sites | junctions | electrodes | switches | shared + shim DACs | DACs | B1 |
|---|---|---|---|---|---|---|---|---|
chain4 | broadcast channel map | 4 | 0 | 128 | 256 | 32 + 1 | 33 | holds |
grid2x3 | broadcast channel map | 7 | 2 | 512 | 1,024 | 32 + 1 | 33 | holds |
ring6d | broadcast channel map | 8 | 2 | 256 | 512 | 32 + 1 | 33 | holds |
grid9x9 shipped | direct channel map | 144 | 77 | 8,496 | 16,992 | 4,608 + 1,152 | 5,760 | fails |
deck_unit_cell shipped | broadcast channel map | 144 | 77 | 8,496 | 16,992 | 32 + 12 | 44 | holds |
cyclone_base shipped | broadcast channel map | 72 | 0 | 2,304 | 4,608 | 32 + 6 | 38 | holds |
h2_racetrack shipped | broadcast channel map | 40 | 0 | 160 | 320 | 32 + 40 | 72 | holds |
ring144_24v shipped | broadcast channel map | 168 | 24 | 5,376 | 10,752 | 32 + 14 | 46 | holds |
chain12 a Goal 1 entry | broadcast channel map | 12 | 0 | 384 | 768 | 32 + 1 | 33 | holds |
grid9x9 a Goal 1 entry | broadcast channel map | 144 | 77 | 8,496 | 16,992 | 32 + 12 | 44 | holds |
The shipped grid9x9 gives every site channels of its own (a direct channel map): 40 DACs a site, 5,760 in all, far over the budget. The Goal 1 entry on grid9x9 has 144 sites and 77 junctions, wired with a broadcast channel map: one waveform bank shared by every site, 32 DACs for it and 12 for the shims, 44 in all. That is what broadcast wiring buys, and rule R22 is its price: one motion a cycle.
Chip area is not a metric: no grader measures it, so no design is ranked by it.
From a run to a stim circuit
A memory experiment is a circuit, written in OpenQASM, together with its detectors — parities of its measurement results that are 0 when nothing went wrong — and its logical observables. To learn how often the logical qubit is lost on a design, the compiled programme is turned back into a circuit, with noise where the run says it belongs, and sampled.
| hardware | stim | because |
|---|---|---|
the preparation | R on every qubit | every ion starts in |0⟩ |
gate MS(θ) on a, b | SQRT_XX a b for θ = π/2, SQRT_XX_DAG for −π/2, X a and X b for π, nothing for 0 | MS(θ) = exp(−iθ/2 X⊗X) |
gate R(θ, φ) on a | by quarter turns of θ about the axis φ: X or Y for a half turn, SQRT_X / SQRT_X_DAG / SQRT_Y / SQRT_Y_DAG for a quarter, nothing for none | R(θ, φ) = exp(−iθ/2 (cos φ X + sin φ Y)) |
gate VZ(λ) on a | S, λ/(π/2) times (mod 4) | VZ(λ) = diag(1, e^{iλ}) |
gate CX / CZ / SWAP / H / S / ... | the stim gate of that name | the gadget layer's Clifford names |
measure a | M a (MX a for an X-basis readout) | its record is the classical bit it writes |
reset a | R a | |
transport, cool, init, barrier | nothing | an ion keeps its qubit wherever it is carried |
Which is why the same circuit run on two designs gives two logical error rates: the gates are the same, the noise is not.
measure q[…] -> c[b] of q writes in the source circuit: a compiler may reorder operations on different qubits, never two measurements of one. Each detector and observable then becomes a DETECTOR or OBSERVABLE_INCLUDE line over those records. A programme that measures a qubit more or fewer times than the circuit does is refused. Where an experiment’s programme stops after its last round, its data readout is appended: one measurement of every data ion in the experiment’s basis, after the last step.- every
beforechannel bound to the step; - every
beforechannel bound to one of its operations, channel by channel; - for each operation in order: its translation, then every
afterchannel bound to it; - every
afterchannel bound to the step.
Two circuits are the same when every qubit sees the same operations in the same order, and the measurements come in the same order: operations on different qubits commute, so such circuits sample the same distribution. That is the sense in which this page’s circuit is the grader’s.
The noise model, qccd-noise@2
What a schedule costs, so that two machines running one circuit get different logical error rates when they spend different time idle, in transport or beside a readout. Every number is a published measurement on trapped-ion QCCD hardware, or arithmetic on two of them; every channel is a Pauli channel stim samples directly: a coherent rotation enters as its Pauli twirl, leakage as the Pauli error the vendor's own stabilizer emulator charges it as. What the literature does not support is left out rather than given an invented number: no error per shuttle, junction, split or swap (transport costs its time and its heat, which the channels below charge), no ion loss, no two-ion-gate crosstalk.
param memory_rate = 7.9e-3 # = 0.0079 param coherent_rate = 0.058 # = 0.058 param nbar_floor = 0.05 # = 0.05 param crosstalk_near = 2.1e-4 # = 0.00021 param crosstalk_far = (97 * 4.8e-5 - 3 * 2.1e-4) / (97 - 3) # = 4.283e-05 param crosstalk_reset = 3.5e-6 # = 3.5e-06
define near(k) = {i for i in ions where position(i, start(k)) in {position(j, start(k)) for j in operated(k)} and i not in operated(k)} define far(k) = {i for i in ions where i not in operated(k) and i not in near(k)}
The first preparationprepare
channel prepare "The first preparation" after p in preparations: X_ERROR(min(1 / 2, scale * primitive("reset", "error"))) on ions(p) counted as reset
Every ion starts in |0>, prepared as a reset is, with a reset's error.
Quantinuum Helios-1E emulator parameters (p_init); arXiv:2511.05465 Table II
Coherent dephasing over a waitmemory_coherent
channel memory_coherent "Coherent dephasing over a wait" before o in qubit_operations, i in ions(o): Z_ERROR(min(1 / 2, scale * pow(sin(pi * coherent_rate * waited(i, o) * 1e-6), 2))) on i
When an operation reaches an ion, the ion has waited since the last one: a coherent Z rotation of angle 2 pi f T over that wait T, entered as its Pauli twirl. It grows as T squared, so one long wait costs far more than many short ones.
arXiv:2511.05465 Table II (quadratic memory term, 7(2)e-5 per 55 ms layer squared); Quantinuum Helios-1E emulator parameters (quadratic_dephasing_rate)
A wrong readoutreadout_z
channel readout_z "A wrong readout" before m in measurements where basis(m) = "Z": X_ERROR(min(1 / 2, scale * (1 - primitive("measure", "fidelity")))) on ions(m) counted as measure
The readout reports the wrong outcome with probability 1 - F: a flip the measurement then sees.
arXiv:2511.05465 Table II; Quantinuum Helios-1E emulator parameters (p_meas)
A wrong readout, in the X basisreadout_x
channel readout_x "A wrong readout, in the X basis" before m in measurements where basis(m) = "X": Z_ERROR(min(1 / 2, scale * (1 - primitive("measure", "fidelity")))) on ions(m) counted as measure
The same flip, for the experiment's own readout of an X memory.
The two-ion gatems
channel ms "The two-ion gate" after g in two_qubit_gates: DEPOLARIZE2(min(15 / 16, scale * ms_error(gate_heat(g), gate_length(g)))) on ions(g) counted as ms_base = ms_error(0, 2), ms_heating = ms_error(gate_heat(g), 2) - ms_error(0, 2), ms_chain = ms_error(gate_heat(g), gate_length(g)) - ms_error(gate_heat(g), 2)
The device's gate error law at the heat the pair meets (the hotter ion, plus what ground-state cooling leaves behind) and at the length of the chain in its trap.
arXiv:2511.05465 Table II; arXiv:0810.0670 Sec. 5.2 (the slope per quantum); arXiv:2004.04706 Eq. 1 (the chain factor); arXiv:2206.11888 Fig. 3 (the cooling floor)
A one-ion pulsegate_1q
channel gate_1q "A one-ion pulse" after g in single_qubit_gates where gate(g) != "VZ" and gate(g) != "I": DEPOLARIZE1(min(3 / 4, scale * (1 - primitive("1q_gate", "fidelity")))) on ions(g)
Every pulse R, and every abstract one-qubit Clifford, fails with the device's one-qubit infidelity. The frame change VZ is a phase update, not a pulse: it costs time, never this.
arXiv:2511.05465 Table II
A wrong resetreset
channel reset "A wrong reset" after r in resets: X_ERROR(min(1 / 2, scale * primitive("reset", "error"))) on ions(r)
A reset leaves its ion in |1> instead of |0> with the device's reset error.
Quantinuum Helios-1E emulator parameters (p_init)
Readout crosstalk in the trapcrosstalk
channel crosstalk "Readout crosstalk in the trap" after k in steps where kind(k) = "measure": DEPOLARIZE1(min(3 / 4, scale * crosstalk_near)) on near(k)
A measurement disturbs the other ions of its trap.
arXiv:2511.05465 Sec. III B5 p.10, Fig. 10 (local crosstalk 2.1(1)e-4)
Readout crosstalk elsewherecrosstalk_global
channel crosstalk_global "Readout crosstalk elsewhere" after k in steps where kind(k) = "measure": DEPOLARIZE1(min(3 / 4, scale * crosstalk_far)) on far(k)
And, less, every ion in every other trap.
arXiv:2511.05465 Sec. III B5 p.10 (global crosstalk 4.8(1)e-5, the three adjacent ions taken out)
Reset crosstalkcrosstalk_reset
channel crosstalk_reset "Reset crosstalk" after k in steps where kind(k) = "reset": DEPOLARIZE1(min(3 / 4, scale * crosstalk_reset)) on far(k) counted as crosstalk_global
A reset disturbs the ions in the other traps far less.
Quantinuum Helios-1E emulator parameters (p_crosstalk_init)
Memory error while the clock runsmemory
channel memory "Memory error while the clock runs" after k in steps where duration(k) > 0: Z_ERROR(min(1 / 2, scale * memory_rate * duration(k) * 1e-6)) on {i for i in ions where i not in operated(k)}
For as long as a step takes, every ion it does not operate on -- idling, riding a rotation, being carried -- dephases linearly in time. Most of the measured linear term is leakage, which the vendor's stabilizer emulator charges as Z, as here. The experiment's appended readout is not a step of the programme, so it is not charged.
arXiv:2511.05465 Table II and Sec. III B4 (linear memory term); Quantinuum Helios-1E emulator parameters (linear_dephasing_rate)
Read as a list, the model says where every error a trapped-ion machine is measured to make enters the circuit: at the gates, at the readouts and resets, beside a readout, and with the clock. What it does not say is said in its about: no error per rail, junction, split or swap (transport pays in time and heat, which memory, memory_coherent and ms charge), no ion loss, no crosstalk from a two-ion gate.
The older model, qccd-noise@1, which the first boards were graded under
Deliberately simple: two-ion gates priced by the heat they meet and the chain they sit in, one-ion pulses, readout and reset by their infidelities, and every ion dephasing for as long as each step takes. The first preparation is noiseless, and nothing is charged for crosstalk or for the shape of an idle stretch.
evaluation "qccd-noise@1" title "Gate noise and dephasing, from the device's own physics" about "Deliberately simple: two-ion gates priced by the heat they meet and the chain they sit in, one-ion pulses, readout and reset by their infidelities, and every ion dephasing for as long as each step takes. The first preparation is noiseless, and nothing is charged for crosstalk or for the shape of an idle stretch." include "metrics" clock "qccdsim_jones" # The model's knobs. The official model is scale 1 with heating, chain length and idling # priced against the species' own coherence time; a sweep may set them otherwise. param scale = 1 # every probability is multiplied by this (0: noiseless) param heating = true # price the n-bar a two-ion gate meets param chain = true # price the length of the chain in its trap param idle = true # dephase every ion for as long as each step takes param t2 = coherence_time() # seconds; the species' T_coh unless a sweep sets it define gate_heat(g) = if heating then gate_nbar(g) else 0 define gate_length(g) = if chain then gate_chain(g) else 2 channel readout_z "A wrong readout" before m in measurements where basis(m) = "Z": X_ERROR(min(1 / 2, scale * (1 - primitive("measure", "fidelity")))) on ions(m) counted as measure channel readout_x "A wrong readout, in the X basis" before m in measurements where basis(m) = "X": Z_ERROR(min(1 / 2, scale * (1 - primitive("measure", "fidelity")))) on ions(m) counted as measure channel ms "The two-ion gate" about "The device's gate error law at the heat the pair meets and the chain in its trap." after g in two_qubit_gates: DEPOLARIZE2(min(15 / 16, scale * ms_error(gate_heat(g), gate_length(g)))) on ions(g) counted as ms_base = ms_error(0, 2), ms_heating = ms_error(gate_heat(g), 2) - ms_error(0, 2), ms_chain = ms_error(gate_heat(g), gate_length(g)) - ms_error(gate_heat(g), 2) channel gate_1q "A one-ion pulse" after g in single_qubit_gates where gate(g) != "VZ" and gate(g) != "I": DEPOLARIZE1(min(3 / 4, scale * (1 - primitive("1q_gate", "fidelity")))) on ions(g) channel reset "A wrong reset" after r in resets: X_ERROR(min(1 / 2, scale * primitive("reset", "error"))) on ions(r) channel idle "Dephasing while the clock runs" about "Pure dephasing of every ion over every step's duration, against the species' coherence time; the appended readout takes one measurement's time." after k in steps + readout where idle and duration(k) > 0 and t2 != none: Z_ERROR(min(1 / 2, scale * ((1 - exp(-duration(k) * 1e-6 / t2)) / 2))) on ions
Dephasing while the clock runsidle
channel idle "Dephasing while the clock runs" after k in steps + readout where idle and duration(k) > 0 and t2 != none: Z_ERROR(min(1 / 2, scale * ((1 - exp(-duration(k) * 1e-6 / t2)) / 2))) on ions
Pure dephasing of every ion over every step's duration, against the species' coherence time; the appended readout takes one measurement's time.
A Goal 1 entry, recomputed
The repetition code’s two-basis memory, three rounds, ten ions, on a twelve-site linear chain: one of the entries on the Goal 1 board, submitted by John Zhuoyang Ye (os_30293bca0826939b). Its bundle — the device, the programme and the certificate — is evaluated here by the text above, and set beside the official report.
| metric | this page | official report | |
|---|---|---|---|
T | 15.161 | 15.161 | equal |
instructions | 133 | 133 | equal |
transport_instructions | 32 | 32 | equal |
ions_per_instruction | 1.4375 | 1.4375 | equal |
dacs | 33 | 33 | equal |
The circuit is 627 lines over 10 qubits, with 18 measurements (the programme’s 12 and the appended readout’s 6). The first steps, as the circuit writes them, with what wrote each line; probabilities are shown to four figures, and the whole circuit has them exactly:
| hardware step | duration | the stim it becomes, and what wrote each line |
|---|---|---|
| the preparation | 0 | R 0 1 2 3 4 5 6 7 8 9 ← translation X_ERROR(0.0005) 0 1 2 3 4 5 6 7 8 9 ← prepare |
| init q0@C2, q1@C4, q2@C6, q3@C11, q4@C9, q5@C7, q6@C3, q7@C5, q8@C10, q9@C8 | 0 | (nothing on the qubits) |
| cool all | 300 µs | Z_ERROR(2.37e-06) 0 1 2 3 4 5 6 7 8 9 ← memory |
| move (shuttle) q0 C2→C3 | 222 µs | Z_ERROR(1.754e-06) 0 1 2 3 4 5 6 7 8 9 ← memory |
| gate R q3; q4; q5; q0 | 5 µs | Z_ERROR(9.047e-09) 3 ← memory_coherent Z_ERROR(9.047e-09) 4 ← memory_coherent Z_ERROR(9.047e-09) 5 ← memory_coherent Z_ERROR(9.047e-09) 0 ← memory_coherent SQRT_Y_DAG 3 ← translation DEPOLARIZE1(2.5e-05) 3 ← gate_1q SQRT_Y_DAG 4 ← translation DEPOLARIZE1(2.5e-05) 4 ← gate_1q SQRT_Y_DAG 5 ← translation DEPOLARIZE1(2.5e-05) 5 ← gate_1q SQRT_Y 0 ← translation DEPOLARIZE1(2.5e-05) 0 ← gate_1q Z_ERROR(3.95e-08) 1 2 6 7 8 9 ← memory |
| gate VZ q3; q4; q5 | 15 µs | S 3 ← translation S 3 ← translation S 4 ← translation S 4 ← translation S 5 ← translation S 5 ← translation Z_ERROR(1.185e-07) 0 1 2 6 7 8 9 ← memory |
| cool all | 300 µs | Z_ERROR(2.37e-06) 0 1 2 3 4 5 6 7 8 9 ← memory |
| gate MS q0,q6 @ C3 | 70 µs | Z_ERROR(3.294e-09) 0 ← memory_coherent Z_ERROR(2.354e-08) 6 ← memory_coherent SQRT_XX 0 6 ← translation DEPOLARIZE2(0.0008375) 0 6 ← ms Z_ERROR(5.53e-07) 1 2 3 4 5 7 8 9 ← memory |
| gate R q0 @ C3 | 5 µs | SQRT_X_DAG 0 ← translation DEPOLARIZE1(2.5e-05) 0 ← gate_1q Z_ERROR(3.95e-08) 1 2 3 4 5 6 7 8 9 ← memory |
| gate R q6 @ C3 | 5 µs | Z_ERROR(8.3e-13) 6 ← memory_coherent SQRT_X_DAG 6 ← translation DEPOLARIZE1(2.5e-05) 6 ← gate_1q Z_ERROR(3.95e-08) 0 1 2 3 4 5 7 8 9 ← memory |
| measure q6 | 120 µs | Z_ERROR(3.738e-08) 6 ← memory_coherent X_ERROR(1e-06) 6 ← readout_z M 6 ← translation DEPOLARIZE1(4.283e-05) 0 1 2 3 4 5 7 8 9 ← crosstalk_global Z_ERROR(9.48e-07) 0 1 2 3 4 5 7 8 9 ← memory |
| reset q6 | 10 µs | Z_ERROR(8.08e-08) 6 ← memory_coherent R 6 ← translation X_ERROR(0.0005) 6 ← reset DEPOLARIZE1(3.5e-06) 0 1 2 3 4 5 7 8 9 ← crosstalk_reset Z_ERROR(7.9e-08) 0 1 2 3 4 5 7 8 9 ← memory |
| the appended readout | 120 µs | Z_ERROR(8.017e-07) 0 ← memory_coherent Z_ERROR(1.935e-07) 1 ← memory_coherent Z_ERROR(5.803e-08) 2 ← memory_coherent Z_ERROR(4.303e-07) 3 ← memory_coherent Z_ERROR(5.803e-08) 4 ← memory_coherent Z_ERROR(1.912e-09) 5 ← memory_coherent X_ERROR(1e-06) 0 ← readout_z X_ERROR(1e-06) 1 ← readout_z X_ERROR(1e-06) 2 ← readout_z Z_ERROR(1e-06) 3 ← readout_x Z_ERROR(1e-06) 4 ← readout_x Z_ERROR(1e-06) 5 ← readout_x M 0 ← translation M 1 ← translation M 2 ← translation MX 3 ← translation MX 4 ← translation MX 5 ← translation |
Reading it: the preparation resets every qubit and charges each a reset’s error; a transport step writes no gate, only the memory error of everyone who waited through it; a pulse is its stim gate followed by its infidelity; a two-ion gate is SQRT_XX followed by the gate law at its heat; a readout is preceded by the coherent dephasing of each ion’s wait and the readout flip, and followed by the crosstalk on the ions beside and elsewhere.
Each channel’s expected number of faults: its probabilities added over every place it writes (a pair counts once). It is not the logical error rate, which the decoder decides, but it says where the faults come from.
| channel | this page | official report | |
|---|---|---|---|
| ms | 0 | 0.0201 | differs |
| gate_1q | 0.002475 | 0.002475 | equal |
| readout | 0 | 1.8×10-5 | differs |
| reset | 0.009 | 0.009 | equal |
| memory | 0.001155 | 0.001155 | equal |
| memory_coherent | 1.25×10-5 | 1.25×10-5 | equal |
| crosstalk | 0.00126 | 0.00126 | equal |
| crosstalk elsewhere | 0.004607 | 0.004607 | equal |
The same check on the distance-3 surface code’s entry on a 9×9 grid (os_4c75a8b07249aea2, 3,195 lines, 34 qubits): T 87.68 ms against the report’s 87.68 (equal), 44 DACs against 44 (equal), 0.2169 expected faults against 0.2169 (equal); its circuit.
The noiseless check
It is decided, not sampled: a stabilizer simulation computes both facts exactly, in time polynomial in the number of qubits. Determinism alone is not enough: an MS pulse turned the other way round keeps every detector deterministic and flips some of their values.
The entry above passes (noiseless_ok() holds). Turn its first MS pulse, instruction #5, from MS(π/2) to MS(−π/2), and the check fails: 2 detector(s) have parity 1 where the source circuit gives 0 (first [0, 2]).
The logical error rate and its interval
The estimate. stim samples C in batches of 10,000 shots (fewer where a release says so), each batch is decoded — minimum-weight matching where every fault touches at most two detectors, BP-OSD otherwise — and sampling stops at the release’s number of failures or of shots. With k failures in n shots, LER ≈ k/n, inside Wilson’s 95 % interval, which stays honest at k = 0.
param z95 = 1.959963984540054
define wilson_centre(k, n) = (k / n + z95 * z95 / (2 * n)) / (1 + z95 * z95 / n) define wilson_half(k, n) = z95 * sqrt(k / n * (1 - k / n) / n + z95 * z95 / (4 * n * n)) / (1 + z95 * z95 / n) define wilson_lo(k, n) = if n = 0 then 0 else if k = 0 then 0 else max(0, wilson_centre(k, n) - wilson_half(k, n)) define wilson_hi(k, n) = if n = 0 then 1 else if k = n then 1 else min(1, wilson_centre(k, n) + wilson_half(k, n)) define per_round(p) = if rounds() <= 1 then p else if p >= 1 then 1 else 1 - pow(1 - p, 1 / rounds())
Logical error rateler
metric ler = failures() / shots()
The fraction of shots in which the decoder's correction left some logical observable wrong.
Logical error rate per roundler_per_round
metric ler_per_round = per_round(ler)
The rate per round of syndrome extraction that compounds to the experiment's.
Logical error rate per round per logical qubitler_per_round_per_logical
metric ler_per_round_per_logical = ler_per_round / n_logical
Goal 1's ranking: the per-round rate shared out over the logical qubits the experiment protects.
Lower end of its 95 % intervaller_per_round_lo
metric ler_per_round_lo = per_round(wilson_lo(failures(), shots()))
Upper end of its 95 % intervaller_per_round_hi
metric ler_per_round_hi = per_round(wilson_hi(failures(), shots()))
The entry’s official sample: 467 failures in 50,000 shots (pymatching, seed 20261021). Through the text above:
| metric | from the counts, by this page | official report | |
|---|---|---|---|
ler | 0.00934 | 0.00934 | equal |
ler_per_round | 0.003123 | 0.003123 | equal |
ler_per_round_per_logical | 0.003123 | 0.003123 | equal |
ler_per_round_lo | 0.002853 | 0.002853 | equal |
ler_per_round_hi | 0.003419 | 0.003419 | equal |
Sampled again when this page was built, from this page’s circuit with the same seed and budget: 463 failures in 50,000 shots, 0.003096 per round — inside the official interval. stim’s samples repeat exactly only on one machine architecture and stim version, so the server’s number is the board’s, and any other is an estimate of the same quantity.
Reading the Goal 1 board
Goal 1 asks for the best quantum memory under 200 ions. Every curated memory experiment is one release, every release is graded by the evaluation above, and every entry of every release is ranked on one list by ler_per_round_per_logical.
| on the board | metric | what it is |
|---|---|---|
| rank by | ler_per_round_per_logical | the logical error rate per round, shared out over the logical qubits |
| 95 % interval | ler_per_round_lo, ler_per_round_hi | Wilson's interval on the failures, per round |
| logical qubits | n_logical | one per observable pair: a Z and an X memory of each |
| ions | n_ions | every ion the programme places |
| ions per logical qubit | ions_per_logical_qubit | FTL's target is 60 logical qubits within 2,000 ions |
| T_quantinuum | T | the round's execution time on Goal 1's clock |
| instructions, DACs, ions per instruction | instructions, dacs, ions_per_instruction | speed and hardware |
Logical qubitsn_logical
metric n_logical = logical_qubits()
How many logical qubits the experiment protects.
Ions per logical qubitions_per_logical_qubit
metric ions_per_logical_qubit = n_ions / n_logical
The ions each logical qubit costs.
The releases on the board
| release | code | d | rounds | ions | k | decoder | at most shots | stop at failures |
|---|---|---|---|---|---|---|---|---|
rep3xz_mem@1 | rep3_x2 | 1 | 3 | 10 | 1 | pymatching | 2,000,000 | 400 |
rep5xz_mem@1 | rep5_x2 | 1 | 5 | 18 | 1 | pymatching | 2,000,000 | 400 |
steanexz_mem@1 | steane_x2 | 3 | 3 | 32 | 1 | bposd | 200,000 | 400 |
surface3xz_mem@1 | rotated_surface_d3_x2 | 3 | 3 | 34 | 1 | pymatching | 2,000,000 | 400 |
shorxz_mem@1 | shor_x2 | 2 | 3 | 36 | 1 | pymatching | 2,000,000 | 400 |
bb18xz_mem@1 | bb18_x2 | 4 | 4 | 90 | 4 | bposd | 20,000 | 400 |
surface5xz_mem@1 | rotated_surface_d5_x2 | 5 | 5 | 98 | 1 | pymatching | 2,000,000 | 400 |
bb72seq_mem@1 | bb72_seq | 6 | 3 | 144 | 12 | bposd | 3,000 | 100 |
bb90seq_mem@1 | bb90_seq | 10 | 3 | 180 | 8 | bposd | 1,500 | 100 |
surface7xz_mem@1 | rotated_surface_d7_x2 | 7 | 7 | 194 | 1 | pymatching | 2,000,000 | 400 |
An entry is on the board only when it is eligible and places at most 200 ions. Five conditions are requirements of the evaluation, decided on this page’s terms: the wiring fits 128 DACs (B1) and the device 200 junctions (B2), the rules hold (G1), the programme places at most 200 ions (G2, the board’s own filter rather than a stage of grading), and the noiseless check holds (G3). The other stages are about the submission itself, and the grader decides them before any number is computed:
| stage | decides | how |
|---|---|---|
| bundle | the files are the ones the manifest names, for this release | sha-256 of every file |
| physics lock | the device’s gates, transport, heating and budget are the release’s | equality of four blocks |
| correspondence | the graded programme is the certified one, with only coolings added | instruction by instruction |
| certificate binding | the certificate is about this circuit, operation by operation | the compiler’s witnesses |
| R10, first half | every gate happens, once, in order, with its own ions together | the proved checker (Lean) |
| R10, second half | the pulses compose to the circuit | stabilizer tableau, against the circuit as written |
Every entry’s bundle is on its page on the board. With the website’s tools installed, python -m qccd.evalset bundle <id>-bundle.zip --sample prints every metric and requirement of this page’s evaluation for it, and --stim circuit.stim writes its noisy circuit; qccd grade <id>-bundle.zip runs the whole grader, every stage above included.
What is proved, decided, computed and estimated
| what | status | by |
|---|---|---|
| every rule of the rule set | decided | the rule language, on the run |
| every gate happens, in order, with its ions together (R10, first half) | proved | a checker whose correctness is proved in Lean |
| the pulses compose to the circuit (R10, second half) | computed | a stabilizer tableau or exact matrices |
| time, heat, hardware, size | exact | the evaluation’s metrics, on the run |
| the budget requirements | decided | the evaluation’s requirements |
| the noisy circuit | exact | the evaluation’s channels and the translation |
| the circuit is the experiment, without noise | decided | the noiseless check |
| the logical error rate | estimated | a sample and a decoder, with a 95 % interval |
The replay’s heat is an upper bound (rule R15): excitations from successive motions are added, and the interference that can cancel them is not modelled. The noise model’s numbers are measurements on one machine family, cited channel by channel; a design is ranked by them as a machine built to that family would run it.
Writing your own evaluation
An evaluation may start from another (include), change its numbers (param), and add metrics, requirements and channels of its own, in the language above and with the words above, and nothing else. A word the vocabulary does not have is refused with the line it is on.
evaluation "mine" title "Goal 1, with a price on every junction crossing" include "goal1" param junction_error = 1e-4 # per crossing: an assumption, not a measurement channel junction "A junction crossing dephases the ion" after o in moves where size(crossed(o)) > 0: Z_ERROR(1 - pow(1 - junction_error, size(crossed(o)))) on ions(o) metric T_us "Execution time in microseconds" unit "us" better low = time(final())
On the 9×9 grid entry above, whose ions cross 455 junctions, the new channel writes 455 lines and adds 0.0455 expected faults to the 0.2169 the board’s model charges.