Compilation
The compiler takes a quantum circuit and a device, and writes the programme the device runs: which ion holds each qubit, how ions are carried so that the two ions of every two-qubit gate stand in the same trap, and the laser operations, in order. Every example on this page can be played.
Every programme it writes is checked twice: against the rules of the machine, and against the circuit, to show that it computes what the circuit says.
The input, and the machine's three operations
The input is a circuit in OpenQASM 2.0, the standard text format for quantum circuits (its specification). A trapped-ion machine cannot apply most of its gates directly. This one has three operations, and every gate is rewritten into them:
| operation | acts on | what it does | as a matrix |
|---|---|---|---|
R(θ, φ) | one ion | One laser pulse. It rotates the qubit by the angle θ about an axis lying in the X–Y plane, at the angle φ from X: φ = 0 is a rotation about X, φ = π/2 about Y. Written Rx(θ) and Ry(θ) for those two. | cos(θ/2)·I − i sin(θ/2)·(cos φ·X + sin φ·Y) |
VZ(λ) | one ion | A rotation by the angle λ about Z, the one axis an R pulse cannot turn about. | diag(1, eiλ) |
MS(θ) | two ions in one trap | One laser pulse reaching both ions, which entangles the two qubits by the angle θ. It is the only way two qubits interact here, which is why the two ions of a two-qubit gate must first be carried into the same trap. | cos(θ/2)·I − i sin(θ/2)·X⊗X |
What a VZ costs. On a machine that can set the phase of the laser reaching each ion on its own, a rotation about Z is free: no laser fires, and the phase of that ion's later pulses is shifted instead. Here the beams are shared between ions, so the rotation has to be made with pulses: Rx(π/2)·Ry(λ)·Rx(−π/2), three R pulses (the rightmost first), equals VZ(λ) up to a global phase. The programme still writes it as one VZ, and the clock charges it the time of three pulses, unless the device declares a gate that turns about Z in one pulse.
The two identities every gate is rewritten by. Each is proved, so the operations written for a gate are that gate (the rightmost factor happens first):
u3(θ, φ, λ) = VZ(φ + λ) · R(θ, π/2 − λ) CX = e−iπ/4 · [Ry(−π/2) ⊗ I] · [Rx(−π/2) ⊗ Rx(−π/2)] · MS(π/2) · [Ry(π/2) ⊗ I]
The first says any single-qubit gate is one pulse followed by one rotation about Z: u3 is OpenQASM's general single-qubit gate, and every named one is a u3 with fixed angles (h is u3(π/2, 0, π), t is u3(0, 0, π/4)). The second says a CNOT is one MS between four single-ion pulses. That the operations which actually fire are the ones for the gate you wrote is checked separately, by composing them back into the circuit (R10, below).
| what you write | which gates | what the machine does |
|---|---|---|
| single-qubit | 19 gatesid x y z h s sdg t tdg sx sxdg rx ry rz u1 p u2 u3 u | one R pulse, then one VZ |
| two-qubit | 7 gatescx cz cy ch swap cu1 cp | cx is one MS(π/2) between four R pulses; the others are cx with single-qubit gates around it |
| three-qubit | 1 gatesccx | the standard decomposition into six CNOTs and single-qubit gates |
| non-unitary | 3 gatesmeasure reset barrier | readout and preparation, in a trap equipped for them; a barrier only orders, and costs nothing |
OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0],q[1];
measure q -> c;How a circuit becomes a machine programme
In short: read the circuit, rewrite every gate as the machine's operations, decide which ion plays which qubit, carry ions so that the pairs that must interact end up in the same trap, write out the instructions, add cooling where the ions would be too hot to gate — then check the result, twice. The nine steps below are that in full.
- Read the circuitthe operations, and the order between themthe circuit becomes a list of operations, each with its qubits and its angles. Between them the compiler keeps the dependency graph: an arrow from each operation to the next one that uses the same qubit. An operation may run only after everything with a path of arrows to it; two operations with no path between them may run in either order, or at the same time.
- Rewritenative operations for each gateevery gate becomes the machine's operations by the two identities above: a single-qubit gate is one
Rand oneVZ, a CNOT oneMSbetween fourRpulses, and a gate on three qubits (a Toffoli) is first unfolded into one- and two-qubit gates. - Placewhich ion is which qubit, and where it startseach qubit is given an ion, and each ion a starting trap, so that qubits that gate together start close together (how, in §3).
- Route and schedulethe moves, in layersoperations run in layers of the dependency graph, and each qubit's operations keep the circuit's order exactly, even where two of them would commute. Before a two-qubit gate, its two ions are carried to one trap that can gate: one hop at a time on most devices, or, on a ring more than about half full, by turning the whole ring at once. This is this website's compiler. The papers on Reproduce use their own compilers, with their own ways of routing ions; there, each paper's schedules are replayed as its own code wrote them, and ours are set beside them under the same rules.
- Write outthe programme, and its certificatethe programme is one instruction per step, each marked with the operation of the circuit it carries out. Beside it the compiler writes a certificate: which ion is which qubit, where each ion starts, every move, and one witness per gate. A witness is the compiler's claim about one gate of the circuit: it happens at instruction k, in trap T, on ions a and b. The checks below test every claim instead of trusting it.
- Coolcooling where it is neededthe programme is replayed with the device's heating model, and a cooling operation is added wherever a gate would otherwise start on ions too hot to gate (R7).
- Check the rulesevery rule of the rule setthe cooled programme is replayed and every rule of the rule set is evaluated on it, exactly as on the Rules page: the standard rule set, unless the compiler was given another.
- Check what it computesR10, in two halvesO1, where every gate happens: the certificate's moves are replayed from the starting positions; every witness must name exactly the ions its gate's qubits are mapped to and find them together in a trap that can gate, every move must be one the device allows, and every gate of the circuit must be witnessed once, in the circuit's order on each of its qubits. O1 is decided by a checker whose correctness is proved, and which reads the device from its description, not from the compiler. O2, what the gates compute: the pulses are read out of the programme, composed through the qubit-to-ion map, and compared with the circuit as written, each measurement and reset in its place. A circuit of Clifford gates (H, S, CNOT and the Pauli gates, with measurement) is compared as a stabilizer tableau, whose size grows only with the square of the number of qubits, so circuits of any size are checked. Outside them (a T gate, an arbitrary angle) the exact matrices are compared, and those grow as 4n: up to 10 qubits, counting one more for each measurement in the middle of the circuit. Beyond that O2 is reported as not checked, never as passing. O2 is computed, not proved; it is the half that says which gates the programme applies.
- Drawthe pagethe page joins the programme and the circuit through the marks on the instructions, after checking each witness against the instruction it names; a disagreement refuses to draw.
The ion mapping, verified
For the Bell pair, compiled here onto the four-site register, each qubit is given an ion and a starting trap. The CNOT needs both ions in one trap, and that happens in two steps: one ion is carried along the register until its trap sits right beside the other — the ion waiting there does not move — and then the two traps are merged into one. The waiting ion shifts by a couple of micrometres as the merge completes, against the hundreds it would move if it were the one being carried. The check recomputes every position from the starting positions and the list of moves, and checks that each gate's ions are where its witness says.
| qubit | ion | starts | ends |
| q0 | q0 | C1 | C0 |
| q1 | q1 | C0 | C0 |
moves recorded: q0 C1→C0
#0 init q0@C1, q1@C0
#1 cool all
#2 gate R q0 @C1 ← op 0 h
#3 gate VZ q0 @C1 ← op 0 h
#4 shuttle q0 C1→C0 ← op 1 cx
#5 gate R q0 @C0 ← op 1 cx
#6 gate MS q0,q1 @C0 ← op 1 cx
#7 gate R q0 @C0 ← op 1 cx
#8 gate R q1 @C0 ← op 1 cx
#9 gate R q0 @C0 ← op 1 cx
#10 measure q0,q1 ← op 2 measure, 3 measureThe pulse sequence, matched to the gate
Each witness names the instruction that completes the gate, the trap, the ions and the operations, in the order they happen. Two checks meet here: the identities above say these operations are this gate, and O2 composes the operations the programme actually fires back into the circuit, so an operation that fires without a witness, or a witness without its operation, is caught.
op 0 (h) at C1, instruction #3: R(1.5708,-1.5708)@q0, VZ(3.14159)@q0op 1 (cx) at C0, instruction #9: R(1.5708,1.5708)@q0, MS(1.5708)@q0,q1, R(-1.5708,0)@q0, R(-1.5708,0)@q1, R(-1.5708,1.5708)@q0Verdict for the Bell pair: 28 rules hold, R7 fail; R10 holds — O1 accepted by the proved checker; O2 by stabilizer tableau, composed from the emitted pulses, against the circuit as written.
The compiled Bell pair on the four-site register: press Play, or step it. The full page shows the circuit stepping beside the programme.
open the pageEvery basic gate, compiled and verified
One circuit per gate, each on one of four small devices named on its card, through the same steps: the input, the programme it became, the ion mapping, the operations witnessed, and the verdicts of the rules and of R10's two halves. The two-qubit gates show the transport that brings the ions together; the gates outside the Clifford set (t, and the rotations by an arbitrary angle) are compared as exact matrices.
h q[0]; a half turn about the diagonal axis: one turn about z, then one pulse
device: chain4, a four-site linear register C0–C3, every site a trap, no junctions
h q[0];| qubit | ion | starts | ends |
| q0 | q0 | C1 | C1 |
| q1 | q1 | C0 | C0 |
op 0 at C1: R(1.5708,-1.5708)@q0, VZ(3.14159)@q0#0 init q0@C1, q1@C0
#1 cool all
#2 gate R q0 @C1 ← op 0 h
#3 gate VZ q0 @C1 ← op 0 hx q[0]; a bit flip: 0 and 1 swap over. One pulse
device: race8, an eight-site racetrack S0–S7: one loop of trap sites, no junctions
x q[0];| qubit | ion | starts | ends |
| q0 | q0 | S0 | S0 |
| q1 | q1 | S1 | S1 |
op 0 at S0: R(3.14159,-1.5708)@q0, VZ(3.14159)@q0#0 init q0@S0, q1@S1
#1 cool all
#2 gate R q0 @S0 ← op 0 x
#3 gate VZ q0 @S0 ← op 0 xy q[0]; a bit flip with a phase: one pulse, about a different axis
device: grid2x3, a 2×3 lattice: T-junctions and corners, one trap on every wire
y q[0];| qubit | ion | starts | ends |
| q0 | q0 | T0_1h | T0_1h |
| q1 | q1 | T0_0h | T0_0h |
op 0 at T0_1h: R(3.14159,0)@q0, VZ(3.14159)@q0#0 init q0@T0_1h, q1@T0_0h
#1 cool all
#2 gate R q0 @T0_1h ← op 0 y
#3 gate VZ q0 @T0_1h ← op 0 yz q[0]; a phase flip: a half turn about z. Free on some machines, three pulses on this one
device: ring6d, the six-site ring with two dock spurs
z q[0];| qubit | ion | starts | ends |
| q0 | q0 | A0 | A0 |
| q1 | q1 | A3 | A3 |
op 0 at A0: R(0,-1.5708)@q0, VZ(3.14159)@q0#0 init q0@A0, q1@A3
#1 cool all
#2 gate R q0 @A0 ← op 0 z
#3 gate VZ q0 @A0 ← op 0 zs q[0]; a quarter turn about z: three pulses here, for the same reason as z
device: chain4, a four-site linear register C0–C3, every site a trap, no junctions
s q[0];| qubit | ion | starts | ends |
| q0 | q0 | C1 | C1 |
| q1 | q1 | C0 | C0 |
op 0 at C1: R(0,0)@q0, VZ(1.5708)@q0#0 init q0@C1, q1@C0
#1 cool all
#2 gate R q0 @C1 ← op 0 s
#3 gate VZ q0 @C1 ← op 0 st q[0]; an eighth of a turn about z. The check for this one compares the exact rotation, not a shortcut
device: race8, an eight-site racetrack S0–S7: one loop of trap sites, no junctions
t q[0];| qubit | ion | starts | ends |
| q0 | q0 | S0 | S0 |
| q1 | q1 | S1 | S1 |
op 0 at S0: R(0,0.785398)@q0, VZ(0.785398)@q0#0 init q0@S0, q1@S1
#1 cool all
#2 gate R q0 @S0 ← op 0 t
#3 gate VZ q0 @S0 ← op 0 trx(0.5) q[0]; any angle at all, about x: one pulse
device: grid2x3, a 2×3 lattice: T-junctions and corners, one trap on every wire
rx(0.5) q[0];| qubit | ion | starts | ends |
| q0 | q0 | T0_1h | T0_1h |
| q1 | q1 | T0_0h | T0_0h |
op 0 at T0_1h: R(0.5,0)@q0, VZ(0)@q0#0 init q0@T0_1h, q1@T0_0h
#1 cool all
#2 gate R q0 @T0_1h ← op 0 rx
#3 gate VZ q0 @T0_1h ← op 0 rxry(0.5) q[0]; any angle at all, about y: one pulse
device: ring6d, the six-site ring with two dock spurs
ry(0.5) q[0];| qubit | ion | starts | ends |
| q0 | q0 | A0 | A0 |
| q1 | q1 | A3 | A3 |
op 0 at A0: R(0.5,1.5708)@q0, VZ(0)@q0#0 init q0@A0, q1@A3
#1 cool all
#2 gate R q0 @A0 ← op 0 ry
#3 gate VZ q0 @A0 ← op 0 ryrz(0.7854) q[0]; any angle about z, which this machine pays for in pulses
device: chain4, a four-site linear register C0–C3, every site a trap, no junctions
rz(0.7854) q[0];| qubit | ion | starts | ends |
| q0 | q0 | C1 | C1 |
| q1 | q1 | C0 | C0 |
op 0 at C1: R(0,0.785396)@q0, VZ(0.7854)@q0#0 init q0@C1, q1@C0
#1 cool all
#2 gate R q0 @C1 ← op 0 rz
#3 gate VZ q0 @C1 ← op 0 rzcx q[0],q[1]; the entangler: carry one ion to the other, then one two-ion pulse with four single-ion pulses around it
device: grid2x3, a 2×3 lattice: T-junctions and corners, one trap on every wire
cx q[0],q[1];| qubit | ion | starts | ends |
| q0 | q0 | T0_1h | T0_1h |
| q1 | q1 | T0_0v | T0_0v |
op 0 at T0_1h: R(1.5708,1.5708)@q0, MS(1.5708)@q0,q1, R(-1.5708,0)@q0, R(-1.5708,0)@q1, R(-1.5708,1.5708)@q0#0 init q0@T0_1h, q1@T0_0v
#1 cool all
#2 shuttle q1 T0_0v→T0_1h ← op 0 cx
#3 gate R q0 @T0_1h ← op 0 cx
#9 cool all
#4 gate MS q0,q1 @T0_1h ← op 0 cx
#5 gate R q0 @T0_1h ← op 0 cx
#6 gate R q1 @T0_1h ← op 0 cx
#7 gate R q0 @T0_1h ← op 0 cx
#8 shuttle q1 T0_1h→T0_0v ← op 0 cxcz q[0],q[1]; a CNOT with two more pulses around it, on the same pair of ions
device: race8, an eight-site racetrack S0–S7: one loop of trap sites, no junctions
cz q[0],q[1];| qubit | ion | starts | ends |
| q0 | q0 | S0 | S0 |
| q1 | q1 | S1 | S1 |
op 0 at S0: R(1.5708,-1.5708)@q1, VZ(3.14159)@q1, R(1.5708,1.5708)@q0, MS(1.5708)@q0,q1, R(-1.5708,0)@q0, R(-1.5708,0)@q1, R(-1.5708,1.5708)@q0, R(1.5708,-1.5708)@q1, VZ(3.14159)@q1#0 init q0@S0, q1@S1
#1 cool all
#2 shuttle q1 S1→S0 ← op 0 cz
#3 gate R q1 @S0 ← op 0 cz
#4 gate VZ q1 @S0 ← op 0 cz
#5 gate R q0 @S0 ← op 0 cz
#6 gate MS q0,q1 @S0 ← op 0 cz
#7 gate R q0 @S0 ← op 0 cz
#8 gate R q1 @S0 ← op 0 cz
#9 gate R q0 @S0 ← op 0 cz
#10 gate R q1 @S0 ← op 0 cz
#11 gate VZ q1 @S0 ← op 0 cz
#12 shuttle q1 S0→S1 ← op 0 czswap q[0],q[1]; three CNOTs in a row, so three two-ion pulses at one trap
device: ring6d, the six-site ring with two dock spurs
swap q[0],q[1];| qubit | ion | starts | ends |
| q0 | q0 | A0 | A0 |
| q1 | q1 | A3 | A3 |
op 0 at A0: R(1.5708,1.5708)@q0, MS(1.5708)@q0,q1, R(-1.5708,0)@q0, R(-1.5708,0)@q1, R(-1.5708,1.5708)@q0, R(1.5708,1.5708)@q1, MS(1.5708)@q1,q0, R(-1.5708,0)@q1, R(-1.5708,0)@q0, R(-1.5708,1.5708)@q1, R(1.5708,1.5708)@q0, MS(1.5708)@q0,q1, R(-1.5708,0)@q0, R(-1.5708,0)@q1, R(-1.5708,1.5708)@q0#0 init q0@A0, q1@A3
#1 cool all
#2 shuttle q1 A3→S4 ← op 0 swap
#3 shuttle q1 S4→S5 ← op 0 swap
#4 shuttle q1 S5→A0 ← op 0 swap
#5 gate R q0 @A0 ← op 0 swap
#23 cool all
#6 gate MS q0,q1 @A0 ← op 0 swap
#7 gate R q0 @A0 ← op 0 swap
#8 gate R q1 @A0 ← op 0 swap
#9 gate R q0 @A0 ← op 0 swap
#10 gate R q1 @A0 ← op 0 swap
#24 cool all
#11 gate MS q1,q0 @A0 ← op 0 swap
#12 gate R q1 @A0 ← op 0 swap
#13 gate R q0 @A0 ← op 0 swap
#14 gate R q1 @A0 ← op 0 swap
#15 gate R q0 @A0 ← op 0 swap
#25 cool all
#16 gate MS q0,q1 @A0 ← op 0 swap
#17 gate R q0 @A0 ← op 0 swap
#18 gate R q1 @A0 ← op 0 swap
#19 gate R q0 @A0 ← op 0 swap
#20 shuttle q1 A0→S5 ← op 0 swap
#21 shuttle q1 S5→S4 ← op 0 swap
#22 shuttle q1 S4→A3 ← op 0 swapmeasure q[0] -> c[0]; reading the qubit out, in a trap that can do it: a laser asks the ion whether it is 0 or 1
device: chain4, a four-site linear register C0–C3, every site a trap, no junctions
measure q[0] -> c[0];| qubit | ion | starts | ends |
| q0 | q0 | C1 | C1 |
| q1 | q1 | C0 | C0 |
#0 init q0@C1, q1@C0
#1 cool all
#2 measure q0 ← op 0 measurereset q[0]; putting the qubit back to 0, with a laser, in the same kind of trap
device: race8, an eight-site racetrack S0–S7: one loop of trap sites, no junctions
reset q[0];| qubit | ion | starts | ends |
| q0 | q0 | S0 | S0 |
| q1 | q1 | S1 | S1 |
#0 init q0@S0, q1@S1
#1 cool all
#2 reset q0 ← op 0 resetThe algorithm
The pipeline above says what happens to a circuit, and the cards show the result for every basic gate. This section states the problem each pass solves, the algorithm that solves it, and the proposition the checker decides afterwards, for the compiler that produced every programme on this page and the leaderboard entries.
1. Setting and problem statement
In words. The device is a graph. Some nodes are traps, where ions can sit (up to a capacity) and, in some of them, be gated or measured; the other nodes are junctions, where rails cross; the edges are the rails. Some rails form named loops that the control system can turn as a whole. This document is the same one the studio draws, and it is all the compiler ever reads about the hardware.
In words. A hop is what one machine cycle can do to an ion: carry it from a trap to a neighbouring trap, passing through junctions on the way without stopping, because an ion never rests on a junction (R2). The compiler plans on the graph of traps and hops, not on the raw rails. The distance between two traps is the fewest hops between them.
In words. Two operations must keep their order only if they touch a common qubit (or classical bit); otherwise they are independent. Drawing an arrow from each operation to the next one on each of its wires gives the dependency graph. The interaction graph forgets the order and only counts how many two-qubit gates each pair of qubits shares.
h q[0]; h q[2]; cx q[0],q[1]; cx q[2],q[3]; cx q[1],q[2]; measure q -> c;. Its dependency graph, laid out so that each column is one layer of §4: an arrow means "must come after". The two Hadamards depend on nothing; the third CNOT waits for both of the first two; each measurement waits for the last gate on its qubit.Its interaction graph is a path: three pairs, one CNOT each. Circuit 2 has the same interaction graph but a very different dependency graph, a single chain, because every CNOT shares a qubit with the next.
In words. Besides the programme, the compiler hands over a certificate: which ion plays which qubit, where each ion starts, every move it will make and when, and for every gate a claim of the form "this gate happened at this instruction, in this trap, on these ions". Replaying the moves from the start tells you where every ion is at every cycle, and each claim can be checked against that.
In words. Produce a programme the machine can run, a certificate that places every gate of the circuit once, in order, in a trap where its ions are together, and pulses that compute the right thing; and make it short. Hops are the cost that matters physically: each hop heats its ion, and a hot ion gates worse (R7, R16), so a programme that moves ions further is not only slower but less accurate.
Conditions (i)–(iii) are decided after the fact by checkers that share no code with the compiler (§9); the objective is pursued heuristically, because its two sub-problems are NP-hard: placement is a quadratic assignment problem and routing is multi-agent path finding under capacity constraints. The pipeline is therefore untrusted heuristics followed by a trusted decision procedure. At a glance:
| pass | problem | algorithm | cost | discharged by |
|---|---|---|---|---|
| §2 lowering | arity ≤ 2 | rewrite table | linear | §9 (iii), tableau route only |
| §3 placement | QAP on W, d | greedy + spectral, 2-swap descent | O(n²|W|) per sweep | none (objective only) |
| §4 layering | DAG scheduling | ASAP levels, round emission | linear | R12 by construction, §9 (ii) |
| §5 site selection | meeting trap | argmin over T | O(|T|) per gate | R6, R6b, R1 |
| §6 routing | MAPF with capacities and waveforms | prioritised space-time A* | O(|T|·H log) per ion | R1–R5, R8, R11, R22 |
| §7 conveyor | bipartite contacts on a loop | readiness batching, greedy sweep | linear in contacts | as §6, plus R4d |
| §8 cooling | R7 feasibility | replay and insert | one pass | R7, R7c |
2. Lowering
Every operation with |q(o)| ≥ 3 is replaced, before placement, by a sequence of one- and two-qubit operations from a composite table, and the DAG is rebuilt from the rewritten list. All later passes see the lowered circuit C′. The rewrite is checked wherever condition (iii) is checked, because (iii) compares the programme with the original C: by the stabilizer tableau for a Clifford circuit, and for a Toffoli, which is not Clifford, as exact matrices, the Toffoli at its own defining matrix. An incorrect table entry would therefore show as a mismatch.
Each of those is then rewritten into pulses (Theorem 1). The tool's own count for the whole Toffoli is 6 two-ion pulses, 33 single-ion pulses and 9 frame updates. Because the T gates are not Clifford, this circuit is checked against the exact 8×8 unitary; its card in §11 says so.
3. Placement
In words. Give every qubit a starting trap so that qubits which will gate together start close together. The score of a layout adds up, over every pair of qubits, "how many gates they share" times "how many hops apart they start". Lower is better. Single-qubit gates do not count: where they happen is decided later, and on a device where every trap gates they cost no transport at all.
Usable traps. Let T1 ⊇ T2 ⊇ … be the tiers {gate-capable, non-junction} ⊆ {non-junction} ⊆ {gate-capable} ⊆ T, each restricted to traps of positive capacity. Tu is the first tier whose total capacity ∑ cap(t) is at least n. The start limit is c(t) = 1 if |Tu| ≥ n, otherwise c(t) = cap(t). In words: prefer traps that can gate and are not junctions (a junction holds one ion, and an ion parked on one blocks every route through it for a whole layer); start one ion per trap when there are enough traps, and only pack two into a trap on a device that is tight, which the compiler then reports.
seed a₀ ← argmaxa ∑b w(a,b); π(a₀) ← argmint ∈ Tu ecc(t) (the most central trap) repeat n − 1 times a ← argmaxa unplaced ∑b placed w(a,b) π(a) ← argmint free ∑b placed w(a,b) · d(t, π(b))A trap is free while it holds fewer than c(t) placed qubits. Ties: the seed is the lowest such qubit, the next qubit the highest-index one among equals, the trap the first in document order. Running time O(n · |Tu| · n).
In words. Start with the busiest qubit in the middle of the device. Then, again and again, take the unplaced qubit with the most gates to qubits already placed, and put it in the free trap closest to its partners.
On the register the same rule goes wrong. After q1 is seeded at C1, q2 is placed before q0 (the tie rule prefers the higher index), and it takes C0, the first free trap next to C1. That leaves q0 the trap on the other side, C2, and then q3 has to go three hops from its partner q2. Score 5, exactly the score the compiler reports for its greedy layout. Greedy commits one qubit at a time and never reconsiders; the next two algorithms exist for this case.
In words. Instead of placing qubits one at a time, spread all of them along a line at once, so that qubits sharing many gates land next to each other (the Fiedler vector is the best such line, in the least-squares sense). Then walk the device outward from its centre, and hand the traps out along that walk, in order.
π ← argmin { Φ(πgreedy), Φ(πspectral) }
for at most 40 sweeps, while some swap improved in the last sweep
for each pair a < b: if Φ(π ∘ (a b)) < Φ(π) then π ← π ∘ (a b)
return ⟨π, πgreedy, πspectral⟩ (a ranked list)
Φ is blind to routability, so the compiler tries the ranked candidates in turn and keeps the first that routes (§6).In words. Take whichever of the two layouts scores better, then keep swapping pairs of qubits whenever a swap lowers the score, until no swap does. Keep the other two layouts as spares: a layout can score well and still leave an ion somewhere the router cannot get past later.
the compiler on circuit 1seeded q1 (weight 2) at T0_1h
candidates: greedy 3, spectral 4 -> greedy
weighted interaction distance 3 over 3 distinct pairsthe compiler on circuit 2seeded q1 (weight 2) at C1
candidates: greedy 5, spectral 4 -> spectral
hill-climb 4 -> 3 in 2 rounds
weighted interaction distance 3 over 3 distinct pairs4. Layering and round emission
In words. Every operation goes into the earliest layer it can: one layer after the latest operation it depends on. Layers run one after another; inside a layer, nothing depends on anything else, so everything in it may happen at the same time, as far as the hardware allows.
Within a layer, each gate g is decomposed into its pulse sequence pg,1, …, pg,ℓ(g) from the pulse table built on the identities of Theorem 1 (one beam and one frame update for a single-qubit gate; four beams around one two-ion pulse for a CNOT). Pulses are emitted in rounds: round k is the instruction set {pg,k : k ≤ ℓ(g)}, one instruction per pulse kind, all in one machine cycle.
In words. Gates in the same layer fire in lock-step: the first pulse of every gate together, then the second pulse of every gate, and so on. Because each gate is in its own trap, this never asks one trap to do two things in a cycle, so a layer of many gates takes as long as one gate.
The same happens in layer 0, where the two Hadamards share one beam instruction and one frame instruction (#2, #3), and in layer 2, where the two measurements share one readout instruction (#17), since measurements do not claim traps:
#2 gate R q0,q2 @T0_0v,T0_1v ← op 0 h, 1 h
#3 gate VZ q0,q2 @T0_0v,T0_1v ← op 0 h, 1 h
#5 gate R q0,q2 @T0_0h,T0_1h ← op 2 cx, 3 cx
#6 gate MS q0,q1,q2,q3 @T0_0h,T0_1h ← op 2 cx, 3 cx
#7 gate R q0,q2 @T0_0h,T0_1h ← op 2 cx, 3 cx
#8 gate R q1,q3 @T0_0h,T0_1h ← op 2 cx, 3 cx
#9 gate R q0,q2 @T0_0h,T0_1h ← op 2 cx, 3 cx
#17 measure q0,q3 ← op 5 measure, 8 measureMeasurements and resets do not claim traps (R12 bounds gates), so a layer emits one readout instruction naming every ion it measures; a barrier orders and costs nothing. The scheme forgoes pipelining across layers: transport for the next layer starts only after the pulses of this one. §10 reports what that costs against an exact solver.
5. Site selection
Let pos be the current positions, K the traps already claimed in this layer, and occ(t) = |pos−1(t)| the number of ions in a trap.
In words. A two-qubit gate happens in the trap that can gate, is not already taken by another gate of this layer, has room for both ions once the ions already parked in it are counted, and is closest to the pair, counting both ions' journeys. Among equals, the first in the document wins.
cx q1,q2, at the start of layer 2. After layer 1, q0 and q1 both stand at T0_1h and q2, q3 at T0_0h; nobody went home, because every ion is used again in layer 2 (Definition 7). The two traps the operands stand in are nearest by distance but are full: two ions each, which is their capacity, and only one of the two is an operand, so they are struck out. Among the rest, the smallest total is two hops, reached by T0_0v and T1_0v; T0_0v comes first in the document. So the pair meets in the trap between them, one hop each.#10 shuttle q1 T0_1h→T0_0v ← op 4 cx
#11 shuttle q2 T0_0h→T0_0v ← op 4 cx
#12 gate R q1 @T0_0v ← op 4 cx
#13 gate MS q1,q2 @T0_0v ← op 4 cxIn words. When a layer is done, every ion that gated in it and is not needed by the very next layer is sent back to where it started. That keeps the few gate-capable traps of a device free for the gates still to come, and the one-layer lookahead stops the rule from sending an ion home only to fetch it straight back.
cx q0,q1 at C2, q1 is wanted by cx q1,q2 and q0 by its measurement, so nobody moves back, and likewise at every layer. The whole circuit costs three hops, one per CNOT. Without the lookahead q1 would have gone back to C2 and set out again.The swap card above shows the other case: on the ring q1 rides 3 hops to the dock A0, the three CNOTs of the swap fire, and since nothing follows, q1 is returned along the same 3 hops to its starting trap.
6. Routing within a layer
In words. Some ions must get from where they are to the trap their gate was assigned; every other ion stands still and is in the way. Find each mover a route, one hop per cycle with waiting allowed, so that no rule is broken at any cycle, and finish as early as possible. This is multi-agent path finding, with the twist that ions share traps up to a capacity and that, on a broadcast-wired device, everything moving in one cycle must move the same way.
The solver is prioritised planning with a space-time reservation table (cooperative A*): movers are planned one at a time in a priority order; each plan is found by A* over states (t, τ) with actions wait and hop, cost 1 per cycle and the admissible heuristic h(t) = d(t, goal); a finished plan reserves what it uses, and later movers plan around it. A hop h departing t at cycle τ is admissible iff all of the following hold, each of which is one rule of the Rules page:
occ(t′, τ+1) < cap(t′) R1 the destination has room
∀ j ∈ junc(h): transits(j, τ) < 1 R2 one transit per junction per cycle
∀ e ∈ via(h): load(e, τ) < cap(e) R3 segment capacity
(t′, t, τ) not reserved R5 no head-on exchange on a segment
one action per ion per cycle R8
act(h) = (ℓ, δ) ⇒ act(ℓ, τ) ∈ {⊥, δ} R4d, R11 one signed direction per loop per cycle
wave(τ) ∈ {⊥, sig(h)} (broadcast devices only) R22 one waveform per cycle
The waveform signature sig(h) is the movement class followed by one label per segment crossed: along a named loop the signed unit step on that loop; across a spur, inward or outward; otherwise the direction of the lab-frame displacement. It is computed by the same function the verifier uses for R22, so the two agree by construction. The first mover to reserve a cycle fixes its waveform; any other mover whose hop has a different signature waits. Arrival is not sufficient: an ion parks at its goal for the rest of the layer, so the goal must have room at every later cycle too.
Layer 2 is the instructive case. q1 and q2 both head for T0_0v, both one hop away, and the trap has room for both. But q1 turns left then down, and q2 turns left then up: two different waveforms. q1 is planned first and fixes the waveform of cycle 0, so q2 waits a cycle and hops in cycle 1. Every priority order gives two cycles here, so all four are tried and the first is kept, instructions #10 and #11. Nothing physical prevents the two hops sharing a cycle; the cost is R22, one waveform per cycle on a broadcast-wired machine.
#4 shuttle q0 T0_1v→T0_1h, q2 T0_0v→T0_0h ← op 2 cx, 3 cx
#10 shuttle q1 T0_1h→T0_0v ← op 4 cx
#11 shuttle q2 T0_0h→T0_0v ← op 4 cxLB ← maxi ∈ M d(pos(i), τ(i)); H ← 2·ecc(GT) + 8
for rung in ⟨(uniform, strict), (¬uniform, strict), (¬uniform, tolerant)⟩
for H′ in ⟨H, 2H⟩ (the third rung tries H only)
best ← ⊥
for order in ⟨farthest first, nearest first, program order, its reverse⟩
reserve every stationary ion at its trap for cycles 0..H′
for i in order: plan i by A*; if none, next order; reserve its walk and its parking
lay the hops out by departure cycle; if ¬uniform, split each cycle by signature
replay the emitted cycles against R1; if strict and a trap overflows, next order
if |cycles| < |best| then best ← cycles; if |best| ≤ LB then return best
if best ≠ ⊥ then return best
raise Unroutable
Rungs 1 and 2 guarantee R1 on what is emitted; rung 3 exists so that a layer no arrangement can make both uniform and legal still yields a programme, for the verifier to report.In words. Try four different orders of planning the movers and keep the plan with the fewest cycles, stopping early if a plan is provably as short as possible. If nothing routes within the search horizon, double it once. If the strict one-waveform search fails, relax it in two steps. Before anything is emitted, replay it and refuse a plan that would overfill a trap.
Failure is a result. When Algorithm 4 raises, or §5 leaves an operation unrealised, the compiler tries again with the next placement of Algorithm 3; when all three fail on a device with a closed loop and docks, §7 is tried; otherwise the compiler declines with the reason. No branch emits a programme that violates a rule it knows about.
7. The conveyor pass
In words. Think of the loop as a conveyor belt with a few workstations (the docks) beside it. Ions riding the belt keep their places on it; one instruction advances the whole belt by any number of slots, and it needs no empty slot to do so, because everything moves together.
In words. Two ions on the belt can never meet, so every gate must pair a rider with a docked ion. That works exactly when the qubits split into two groups with all gates running between the groups, one group small enough for the docks: the shape of a syndrome-extraction round, ancillas docked and data riding. It is also why the general router's limit, about half occupancy on a loop, does not apply here.
cx a,b; cx b,c; cx c,a, fails the first condition: whichever two ride the belt can never meet, and the pass says which.Layout. Docks are assigned to QD in order and riders spread at stride ⌊N/|QL|⌋, unless a layout is supplied from outside, as the code-aware leaderboard entries do; a supplied layout is validated (each dock exists, no slot or dock named twice, the partition respected) and otherwise treated as data.
Schedule. Operations are emitted by readiness: o is ready when every earlier o′ sharing a qubit with it is emitted, commuting or not. In words: every qubit sees its own operations in the circuit's order, and only operations on different qubits move relative to each other, which is what lets contacts of different ancillas share one batch. The order of a qubit's gates is the circuit author's to choose, so the compiler keeps it even where two CNOTs commute: one that shares only its control, or only its target, with another would give the same unitary in either order, which is exactly why no semantic check could tell, and why the order conjunct of §9 has no exemption for it.
while operations remain drain: emit every ready measurement, reset and single-qubit gate on a docked ion (no rotation needed) for each ready contact c = (rider i, dock Dc): θc ← rail(Dc) − σ(i) (mod N) θ* ← the θc with the largest batch (ties: nearest, either way) [monotone variant: nearest ahead] B ← a set of ready contacts at θ*, at most one per dock and one per rider emit rotate(θ* − θ, the shorter way); dock(B); the CNOT rounds of B together; undock(B)Invariant: the loop never turns while a dock is occupied. In the certificate a rotation is one event, and the checker's replay applies it to every ion on the loop and to no other.
In words. First do everything that needs no turn: measure, reset and single-qubit gates on docked ions. Then work out, for each gate that is ready, how far the belt would have to turn to bring its rider beside its dock, turn to the position where the most ready gates line up (the nearest, either way, when it is a tie), and do every ready gate there: pull the riders into their docks, fire, push them back out. The belt never turns while a rider is docked, since a docked ion is off the belt and would come back beside the wrong slot. Since every qubit's gates stay in the circuit's order, an ancilla has one gate ready at a time, and turning the shorter way to it costs fewer turns and fewer hops than always turning forward, which would lap the belt for each one; the forward-only rule is still there as an option.
cx q0,q2 with a turn of −2; that turn carries q3 from slot 4 to slot 2, so cx q0,q3 needs −2 more: two turns of two, four hops in all, three contacts, exactly as the compiler's note reads. Taking cx q0,q3 first is not an option: the order of q0's gates is the circuit's.| step | ready | turn | emitted |
|---|---|---|---|
| drain | h q0 (q0 is docked) | — | beam and frame update, #2–#3 |
| 1 | cx q0,q1 | none: q1 is already beside the dock | dock q1, five rounds, undock: #4–#10 |
| 2 | cx q0,q2 (needs −2) | −2 | rotate (#11), dock q2, rounds, undock: #12–#18 |
| 3 | cx q0,q3 (now needs −2) | −2 more | rotate (#19), dock q3, rounds, undock: #20–#26 |
| drain | h q0, measure q0 | — | #27–#29 |
#4 dock q1 S0→A0 ← op 1 cx
#6 gate MS q0,q1 @A0 ← op 1 cx
#10 undock q1 A0→S0 ← op 1 cx
#11 rotate_ccw rotate L0 by -2 ← op 2 cx
#12 dock q2 S0→A0 ← op 2 cx
#14 gate MS q0,q2 @A0 ← op 2 cx
#18 undock q2 A0→S0 ← op 2 cx
#19 rotate_ccw rotate L0 by -2 ← op 3 cx
#20 dock q3 S0→A0 ← op 3 cx
#22 gate MS q0,q3 @A0 ← op 3 cx
#26 undock q3 A0→S0 ← op 3 cx8. Cooling insertion
Let n̄i(t) be the motional quanta of ion i at cycle t under the heating model (each hop, split and merge adds a table value; a global cool sets every n̄i to zero). R7 requires, for every two-qubit gate g at cycle t, maxi ∈ g n̄i(t) ≤ budget. The pass replays P, inserts a global cool immediately before each violating gate, and replays once more.
In words. Moving an ion warms it up, and a warm ion makes a worse two-qubit gate. The pass walks through the programme with a thermometer, and wherever a two-qubit gate would fire too hot it inserts a cooling step just before it. Cooling is global, so one step cools every ion; that is why one walk is enough, and the pass checks the result by walking through again.
9. Correctness
The compiler is outside the trusted base. Conditions (i)–(iii) of the Problem are decided by three independent checkers, each reading only (A, C, P, κ). The checker for (ii) is proved correct (Theorem 2); the checkers for (i) and (iii) are executable and not proved (Checks 1 and 2). The gate rewrite rests on proved identities.
In words. Any single-qubit gate is one laser pulse plus a bookkeeping change of phase that costs nothing; a CNOT is one two-ion pulse with four single-ion pulses around it. Both facts are theorems, checked by a proof assistant, and the table is also tested numerically. The global phase is kept because it becomes visible once the gate is controlled, and a wrong phase convention is exactly the kind of error that hides until then.
In words. The same rule checker the studio runs on any hand-written programme is run on the compiled one, and it does not know or care how the programme was made. A router bug shows up as a failed rule on this page, not as a programme a machine would refuse.
- unrealised(κ) = ∅;
- μ is injective and total on Q;
- the events are sorted by cycle, so the replay is well defined;
- every rotation names a loop in loopsA;
- ∀ m ∈ moves: (m.src, m.dst) ∈ HA and posm.t(m.ion) = m.src;
- ∀ g ∈ gates: g.site ∈ gateA and ∀ i ∈ g.ions: posg.t(i) = g.site;
- ∀ g ∈ gates: the ions g names are, in some order, μ of the qubits of the operation it names;
- every operation of C′ other than measure, reset and barrier has exactly one witness;
- every witness names an operation of C′;
- for operations o before o′ sharing a qubit, the witness cycle of o precedes that of o′, whether or not the two commute.
In words. Nothing was left out; each qubit has its own ion; the moves can be replayed in order; every rotation is of a real loop; no ion ever teleports (every move is a real hop, starting from where the ion actually is); every claim names exactly the ions its operation's qubits live on, and finds them together in a trap that can gate; every gate of the circuit is claimed exactly once, and every claim names an operation of the circuit; and gates on a common qubit happen in the order written. A claim names an operation, never the gate applied there, so a claim on a barrier, a measurement or a reset passes too, and which gate fires is for Check 2 to decide.
In words. The checker is nothing but a decision procedure for Definition 9, and a machine-checked proof says that whenever it answers yes, the definition really holds. So the whole claim lives in the definition, which a reader can judge. The facts about the device that the definition refers to (which traps gate, which pairs are one hop apart, how each loop is ordered) are read out of the document by code the compiler never runs, so the compiler cannot make the device bigger by saying so; that is what makes the guarantee hold for any device.
In words. Finally, does the programme compute the right thing? The checker reads the pulses back out of the programme and works out what they do to the qubits, then compares with what the circuit does. For Clifford circuits this is done with stabilizer tableaux, which scale; otherwise the full matrix is compared, up to ten qubits. A wrong angle, a dropped frame update, a swapped control and target, or one gate compiled as another all change the answer. It is the only check that sees which gate the pulses make.
Together: Check 1 gives (i), Theorem 2 gives (ii), Check 2 gives (iii), and Theorem 1 is why the compiler's pulse table can be right in the first place; that the pulses of P are the gates of C is what Check 2 establishes. The page's drawing is derived from the same certificate: the studio joins the programme to the circuit through the per-instruction stamps and refuses to draw if a witness disagrees with the stamp on the instruction it names.
10. Limitations and measured gaps
Optimality. Nothing above certifies minimality. The router's layer instances were re-solved exactly by a SAT encoding of the same problem on the same trap graph; the heuristic was optimal on every instance of the lattice and cyclone devices and lost on a racetrack, where a single priority order had cost 43 cycles against 5, which is the origin of the four orders in Algorithm 4. The placement relaxation of Algorithm 2 was predicted to dominate Algorithm 1 and did not; the 2-swap descent on Φ is what won, by up to 12 %.
Scope. Routing is planned within a layer; cross-layer pipelining is not attempted. R10 is reported partial for a non-Clifford circuit of more than ten qubits, where neither a tableau nor a dense unitary is available. Operations on three or more qubits are lowered, never executed as such. The general router runs out at about 46 % loop occupancy, and the conveyor pass covers only bipartite circuits. Whether the source circuit is the intended one (for a syndrome round, whether it measures the intended stabilizers) is outside R10 and is tested upstream. The physical model behind R7 and R16 is the subject of the Physics page.
Background.
- Quadratic assignment and its hardness: Sahni and Gonzalez, 1976. Spectral ordering by the second Laplacian eigenvector: Fiedler, 1973.
- Prioritised planning with space-time reservations (cooperative A*): Silver, 2005. Hardness of multi-agent path finding: Yu and LaValle, 2013.
- The Mølmer–Sørensen gate and the CNOT-from-MS identity in the trapped-ion literature; the identity is re-proved here under one fixed phase convention.
11. The four circuits, compiled and verified
The examples quoted above, through the same pipeline and the same checks as every gate: the input, the programme it became, the ion mapping, the pulses witnessed, and the verdicts. Press Play, or step the machine.
Circuit 1: two Bell pairs, then joined four layers: two Hadamards fire in one instruction, two CNOTs run side by side in two traps, then one CNOT joins the pairs
device: grid2x3, a 2×3 lattice: T-junctions and corners, one trap on every wire
h q[0];
h q[2];
cx q[0],q[1];
cx q[2],q[3];
cx q[1],q[2];
measure q -> c;| qubit | ion | starts | ends |
| q0 | q0 | T0_1v | T0_1h |
| q1 | q1 | T0_1h | T0_0v |
| q2 | q2 | T0_0v | T0_0v |
| q3 | q3 | T0_0h | T0_0h |
op 0 at T0_1v: R(1.5708,-1.5708)@q0, VZ(3.14159)@q0op 1 at T0_0v: R(1.5708,-1.5708)@q2, VZ(3.14159)@q2op 2 at T0_1h: R(1.5708,1.5708)@q0, MS(1.5708)@q0,q1, R(-1.5708,0)@q0, R(-1.5708,0)@q1, R(-1.5708,1.5708)@q0op 3 at T0_0h: R(1.5708,1.5708)@q2, MS(1.5708)@q2,q3, R(-1.5708,0)@q2, R(-1.5708,0)@q3, R(-1.5708,1.5708)@q2op 4 at T0_0v: R(1.5708,1.5708)@q1, MS(1.5708)@q1,q2, R(-1.5708,0)@q1, R(-1.5708,0)@q2, R(-1.5708,1.5708)@q1#0 init q0@T0_1v, q1@T0_1h, q2@T0_0v, q3@T0_0h
#1 cool all
#2 gate R q0,q2 @T0_0v,T0_1v ← op 0 h, 1 h
#3 gate VZ q0,q2 @T0_0v,T0_1v ← op 0 h, 1 h
#4 shuttle q0 T0_1v→T0_1h, q2 T0_0v→T0_0h ← op 2 cx, 3 cx
#5 gate R q0,q2 @T0_0h,T0_1h ← op 2 cx, 3 cx
#19 cool all
#6 gate MS q0,q1,q2,q3 @T0_0h,T0_1h ← op 2 cx, 3 cx
#7 gate R q0,q2 @T0_0h,T0_1h ← op 2 cx, 3 cx
#8 gate R q1,q3 @T0_0h,T0_1h ← op 2 cx, 3 cx
#9 gate R q0,q2 @T0_0h,T0_1h ← op 2 cx, 3 cx
#10 shuttle q1 T0_1h→T0_0v ← op 4 cx
#11 shuttle q2 T0_0h→T0_0v ← op 4 cx
#12 gate R q1 @T0_0v ← op 4 cx
#20 cool all
#13 gate MS q1,q2 @T0_0v ← op 4 cx
#14 gate R q1 @T0_0v ← op 4 cx
#15 gate R q2 @T0_0v ← op 4 cx
#16 gate R q1 @T0_0v ← op 4 cx
#17 measure q0,q3 ← op 5 measure, 8 measure
#18 measure q1,q2 ← op 6 measure, 7 measureCircuit 2: a GHZ chain every CNOT shares a qubit with the next: the placer lays the chain along the register, and no ion is sent home while the next gate still needs it
device: chain4, a four-site linear register C0–C3, every site a trap, no junctions
h q[0];
cx q[0],q[1];
cx q[1],q[2];
cx q[2],q[3];
measure q -> c;| qubit | ion | starts | ends |
| q0 | q0 | C3 | C2 |
| q1 | q1 | C2 | C1 |
| q2 | q2 | C1 | C0 |
| q3 | q3 | C0 | C0 |
op 0 at C3: R(1.5708,-1.5708)@q0, VZ(3.14159)@q0op 1 at C2: R(1.5708,1.5708)@q0, MS(1.5708)@q0,q1, R(-1.5708,0)@q0, R(-1.5708,0)@q1, R(-1.5708,1.5708)@q0op 2 at C1: R(1.5708,1.5708)@q1, MS(1.5708)@q1,q2, R(-1.5708,0)@q1, R(-1.5708,0)@q2, R(-1.5708,1.5708)@q1op 3 at C0: R(1.5708,1.5708)@q2, MS(1.5708)@q2,q3, R(-1.5708,0)@q2, R(-1.5708,0)@q3, R(-1.5708,1.5708)@q2#0 init q0@C3, q1@C2, q2@C1, q3@C0
#1 cool all
#2 gate R q0 @C3 ← op 0 h
#3 gate VZ q0 @C3 ← op 0 h
#4 shuttle q0 C3→C2 ← op 1 cx
#5 gate R q0 @C2 ← op 1 cx
#6 gate MS q0,q1 @C2 ← op 1 cx
#7 gate R q0 @C2 ← op 1 cx
#8 gate R q1 @C2 ← op 1 cx
#9 gate R q0 @C2 ← op 1 cx
#10 shuttle q1 C2→C1 ← op 2 cx
#11 gate R q1 @C1 ← op 2 cx
#12 gate MS q1,q2 @C1 ← op 2 cx
#13 gate R q1 @C1 ← op 2 cx
#14 gate R q2 @C1 ← op 2 cx
#15 gate R q1 @C1 ← op 2 cx
#16 measure q0 ← op 4 measure
#17 shuttle q2 C1→C0 ← op 3 cx
#18 gate R q2 @C0 ← op 3 cx
#19 gate MS q2,q3 @C0 ← op 3 cx
#20 gate R q2 @C0 ← op 3 cx
#21 gate R q3 @C0 ← op 3 cx
#22 gate R q2 @C0 ← op 3 cx
#23 measure q1 ← op 5 measure
#24 measure q2,q3 ← op 6 measure, 7 measureCircuit 3: a parity check, by rotation the ancilla q0 sits at a dock, the data ride the loop; the loop turns twice and every CNOT is a contact at the dock
device: ring6d, the six-site ring with two dock spurs
h q[0];
cx q[0],q[1];
cx q[0],q[2];
cx q[0],q[3];
h q[0];
measure q[0] -> c[0];| qubit | ion | starts | ends |
| q0 | q0 | A0 | A0 |
| q1 | q1 | S0 | S0 |
| q2 | q2 | S2 | S0 |
| q3 | q3 | S4 | S0 |
op 0 at A0: witnessed by instruction #3, pulses in the programmeop 1 at A0: witnessed by instruction #9, pulses in the programmeop 2 at A0: witnessed by instruction #17, pulses in the programmeop 3 at A0: witnessed by instruction #25, pulses in the programmeop 4 at A0: witnessed by instruction #28, pulses in the programme#0 init q0@A0, q1@S0, q2@S2, q3@S4
#1 cool all
#2 gate R q0 @ ← op 0 h
#3 gate VZ q0 @ ← op 0 h
#4 dock q1 S0→A0 ← op 1 cx
#5 gate R q0 @A0 ← op 1 cx
#30 cool all
#6 gate MS q0,q1 @A0 ← op 1 cx
#7 gate R q0 @A0 ← op 1 cx
#8 gate R q1 @A0 ← op 1 cx
#9 gate R q0 @A0 ← op 1 cx
#10 undock q1 A0→S0 ← op 1 cx
#11 rotate_ccw rotate L0 by -2 ← op 2 cx
#12 dock q2 S0→A0 ← op 2 cx
#13 gate R q0 @A0 ← op 2 cx
#31 cool all
#14 gate MS q0,q2 @A0 ← op 2 cx
#15 gate R q0 @A0 ← op 2 cx
#16 gate R q2 @A0 ← op 2 cx
#17 gate R q0 @A0 ← op 2 cx
#18 undock q2 A0→S0 ← op 2 cx
#19 rotate_ccw rotate L0 by -2 ← op 3 cx
#20 dock q3 S0→A0 ← op 3 cx
#21 gate R q0 @A0 ← op 3 cx
#32 cool all
#22 gate MS q0,q3 @A0 ← op 3 cx
#23 gate R q0 @A0 ← op 3 cx
#24 gate R q3 @A0 ← op 3 cx
#25 gate R q0 @A0 ← op 3 cx
#26 undock q3 A0→S0 ← op 3 cx
#27 gate R q0 @ ← op 4 h
#28 gate VZ q0 @ ← op 4 h
#29 measure q0 ← op 5 measureA Toffoli, lowered one three-qubit gate becomes six CNOTs and nine single-qubit gates before placement; R10 is decided against the exact unitary
device: grid2x3, a 2×3 lattice: T-junctions and corners, one trap on every wire
ccx q[0],q[1],q[2];| qubit | ion | starts | ends |
| q0 | q0 | T0_1h | T0_1h |
| q1 | q1 | T0_1v | T0_1v |
| q2 | q2 | T0_0v | T0_1v |
op 0 at T0_0v: R(1.5708,-1.5708)@q2, VZ(3.14159)@q2op 1 at T0_0v: R(1.5708,1.5708)@q1, MS(1.5708)@q1,q2, R(-1.5708,0)@q1, R(-1.5708,0)@q2, R(-1.5708,1.5708)@q1op 2 at T0_0v: R(0,2.35619)@q2, VZ(-0.785398)@q2op 3 at T0_1h: R(1.5708,1.5708)@q0, MS(1.5708)@q0,q2, R(-1.5708,0)@q0, R(-1.5708,0)@q2, R(-1.5708,1.5708)@q0op 4 at T0_1h: R(0,0.785398)@q2, VZ(0.785398)@q2op 5 at T0_1v: R(1.5708,1.5708)@q1, MS(1.5708)@q1,q2, R(-1.5708,0)@q1, R(-1.5708,0)@q2, R(-1.5708,1.5708)@q1op 6 at T0_1v: R(0,2.35619)@q2, VZ(-0.785398)@q2op 8 at T0_1h: R(0,0.785398)@q1, VZ(0.785398)@q1op 7 at T0_1v: R(1.5708,1.5708)@q0, MS(1.5708)@q0,q2, R(-1.5708,0)@q0, R(-1.5708,0)@q2, R(-1.5708,1.5708)@q0op 9 at T0_1v: R(0,0.785398)@q2, VZ(0.785398)@q2op 11 at T0_1h: R(1.5708,1.5708)@q0, MS(1.5708)@q0,q1, R(-1.5708,0)@q0, R(-1.5708,0)@q1, R(-1.5708,1.5708)@q0op 10 at T0_1v: R(1.5708,-1.5708)@q2, VZ(3.14159)@q2op 12 at T0_1h: R(0,0.785398)@q0, VZ(0.785398)@q0op 13 at T0_0v: R(0,2.35619)@q1, VZ(-0.785398)@q1op 14 at T0_1h: R(1.5708,1.5708)@q0, MS(1.5708)@q0,q1, R(-1.5708,0)@q0, R(-1.5708,0)@q1, R(-1.5708,1.5708)@q0#0 init q0@T0_1h, q1@T0_1v, q2@T0_0v
#1 cool all
#2 gate R q2 @T0_0v ← op 0 h
#3 gate VZ q2 @T0_0v ← op 0 h
#4 shuttle q1 T0_1v→T0_0v ← op 1 cx
#5 gate R q1 @T0_0v ← op 1 cx
#53 cool all
#6 gate MS q1,q2 @T0_0v ← op 1 cx
#7 gate R q1 @T0_0v ← op 1 cx
#8 gate R q2 @T0_0v ← op 1 cx
#9 gate R q1 @T0_0v ← op 1 cx
#10 shuttle q1 T0_0v→T0_1v ← op 1 cx
#11 gate R q2 @T0_0v ← op 2 tdg
#12 gate VZ q2 @T0_0v ← op 2 tdg
#13 shuttle q2 T0_0v→T0_1h ← op 3 cx
#14 gate R q0 @T0_1h ← op 3 cx
#54 cool all
#15 gate MS q0,q2 @T0_1h ← op 3 cx
#16 gate R q0 @T0_1h ← op 3 cx
#17 gate R q2 @T0_1h ← op 3 cx
#18 gate R q0 @T0_1h ← op 3 cx
#19 gate R q2 @T0_1h ← op 4 t
#20 gate VZ q2 @T0_1h ← op 4 t
#21 shuttle q2 T0_1h→T0_1v ← op 5 cx
#22 gate R q1 @T0_1v ← op 5 cx
#55 cool all
#23 gate MS q1,q2 @T0_1v ← op 5 cx
#24 gate R q1 @T0_1v ← op 5 cx
#25 gate R q2 @T0_1v ← op 5 cx
#26 gate R q1 @T0_1v ← op 5 cx
#27 shuttle q1 T0_1v→T0_1h ← op 8 t
#28 gate R q2,q1 @T0_1h,T0_1v ← op 6 tdg, 8 t
#29 gate VZ q2,q1 @T0_1h,T0_1v ← op 6 tdg, 8 t
#30 shuttle q0 T0_1h→T0_1v ← op 7 cx
#31 gate R q0 @T0_1v ← op 7 cx
#56 cool all
#32 gate MS q0,q2 @T0_1v ← op 7 cx
#33 gate R q0 @T0_1v ← op 7 cx
#34 gate R q2 @T0_1v ← op 7 cx
#35 gate R q0 @T0_1v ← op 7 cx
#36 shuttle q0 T0_1v→T0_1h ← op 11 cx
#37 gate R q2,q0 @T0_1h,T0_1v ← op 9 t, 11 cx
#38 gate VZ q2 @T0_1v ← op 9 t
#57 cool all
#39 gate MS q0,q1 @T0_1h ← op 11 cx
#40 gate R q0 @T0_1h ← op 11 cx
#41 gate R q1 @T0_1h ← op 11 cx
#42 gate R q0 @T0_1h ← op 11 cx
#43 shuttle q1 T0_1h→T0_0v ← op 13 tdg
#44 gate R q2,q0,q1 @T0_0v,T0_1h,T0_1v ← op 10 h, 12 t, 13 tdg
#45 gate VZ q2,q0,q1 @T0_0v,T0_1h,T0_1v ← op 10 h, 12 t, 13 tdg
#46 shuttle q1 T0_0v→T0_1h ← op 14 cx
#47 gate R q0 @T0_1h ← op 14 cx
#58 cool all
#48 gate MS q0,q1 @T0_1h ← op 14 cx
#49 gate R q0 @T0_1h ← op 14 cx
#50 gate R q1 @T0_1h ← op 14 cx
#51 gate R q0 @T0_1h ← op 14 cx
#52 shuttle q1 T0_1h→T0_1v ← op 14 cx