The hardware language
A programme is a list of statements over one device. Each statement is one instruction and one machine cycle: it says what moves where, or which ions a gate, a measurement or a cooling touches. It says nothing about cost. The replay computes the cost, the duration and the heating of every cycle from the device's own primitive tables, and the rules judge each cycle as a whole. The same text runs in the studio's Write pane and, unchanged, in Python through qccd.api.
Syntax
programme ::= { statement NEWLINE }
statement ::= "p." verb "(" [ arguments ] ")"
verb ::= "init" | "fill" | "move" | "shuttle" | "simd" | "rotate"
| "gate" | "cool" | "measure" | "reset" | "barrier" | "claim"
arguments ::= argument { "," argument }
argument ::= literal | name "=" literal (keywords after positionals)
literal ::= string | number | "True" | "False" | "None"
| "[" [ literal { "," literal } ] "]"
| "{" [ string ":" literal { "," string ":" literal } ] "}"
Statements are Python calls on a programme p; the literals are Python's. A statement may span lines while a bracket is open, which is Python's own rule and the only line-joining rule there is. Positional arguments come first, keywords after.
Semantics
The machine state is a map from ions to sites, a motional excitation n̄ per ion, and a clock. init and fill create the map; every other statement is a transition of it. Transport statements move ions along segments and through junctions; each crossing is priced from the device's curves and adds to n̄. Gates leave positions alone and read n̄ to evaluate their error. Cooling lowers n̄. Instructions execute in order, each atomically; the next starts when the previous ends. Every cycle is then judged by the rules, which is where a programme is refused.
Statements
p.init({ion: site, ...}, quanta=None)
Places the named ions on the named sites. The first statement of every programme: a device starts empty.
p.init({"d0": "S1", "d1": "A0"})p.fill(loop=None, prefix="d")
Places one ion on every slot of a loop, d0 on its first site and so on: the packed ring in one line.
- state
- position := every site of the loop, in order. Nothing moves.
- cost
- 0 hops, 0 µs.
- rules
- R1
- IR
init
p.fill()p.move(ion, src, dst, via=None, cls="shuttle")
One ion, one hop, in its own cycle: the shortest form of a transport instruction.
- state
- position(ion) := dst; the segment between src and dst, or the segments in via, is crossed once; n̄ grows by the primitives crossed.
- cost
- the segment's hop, plus a junction_cross priced by the degree of any junction transited; duration from the device's curves.
- rules
- R1, R2, R3, R4, R8
- IR
simd with one participant
p.init({"d0": "S1"})
p.move("d0", "S1", "S2")p.shuttle(ion, [site, site, ...], cls="shuttle")
Walks one ion along a path of site ids, one trap-to-trap step per cycle. Junctions on the way are transited, never rested on.
p.init({"d0": "S1"})
p.shuttle("d0", ["S1", "S0", "A0"])p.simd(cls, [[ion, from, to], [ion, from, to, via], ...], mode="inter")
Several ions in one cycle, driven together under one movement class. The rules judge the cycle as a whole: one waveform, one direction per loop, no exchanges.
p.init({"d0": "S1", "d1": "S4"})
p.simd("shuttle", [["d0", "S1", "S2"], ["d1", "S4", "S5"]])p.rotate(delta, loop=None)
Turns a closed loop: every ion on it moves delta slots forward (negative: back). One instruction, one movement template driven |delta| times.
p.fill()
p.rotate(2)p.gate(name, [[control, target], ...], sites=None)
A gate cycle. Two-qubit: every pair sits in one site whose zone allows gates, control first. Single-qubit: an empty pair list and the site named.
p.init({"d0": "A0", "d1": "A0"})
p.cool()
p.gate("CX", [["d0", "d1"]])p.cool(ions=None)
Cools ions back toward the motional ground state: all of them when no list is given (a broadcast), else the listed ones.
p.init({"d0": "S1"})
p.shuttle("d0", ["S1", "S0", "A0"])
p.cool()p.measure([ion, ...])
Reads the listed ions out. Each must sit in a zone with SPAM (state preparation and measurement).
- state
- positions unchanged.
- cost
- the measure primitive's duration.
- rules
- R6
- IR
measure
p.init({"d0": "A0"})
p.measure(["d0"])p.reset([ion, ...])
Puts the listed ions back to |0>. The same zone requirement as measuring.
- state
- positions unchanged.
- cost
- the reset primitive's duration.
- rules
- R6
- IR
reset
p.init({"d0": "A0"})
p.reset(["d0"])p.barrier()
A cycle in which nothing happens: an explicit synchronisation point, a marker between phases of a programme.
- state
- unchanged.
- cost
- 0 hops, 0 µs.
- rules
- –
- IR
barrier
p.init({"d0": "S1"})
p.move("d0", "S1", "S2")
p.barrier()
p.move("d0", "S2", "S3")p.claim(total_cost=..., total_steps=..., ...)
Annotates the programme with the totals its author claims. Claims are not content: the replay recomputes everything and R9 rejects any claim it cannot reproduce.
- state
- unchanged; the claim is recorded on the programme.
- cost
- none.
- rules
- R9
- IR
the programme's metrics
p.init({"d0": "S1"})
p.move("d0", "S1", "S2")
p.claim(total_cost=1, total_steps=1)Beneath the text: the IR
Every statement becomes one instruction of the control IR, the JSON the compiler emits and the verifier replays. The Write pane and the compiler meet there.
| statement | instruction type | carries |
|---|---|---|
init | init | placement, quanta |
fill | init | placement over a loop |
move / shuttle / simd | simd | class, mode, participants (ion, from, to, via) |
rotate | simd | class, a loop_shift template, holds |
gate | gate | gate, pairs, sites |
cool | cool | broadcast or ions |
measure / reset | measure / reset | ions |
barrier | barrier | nothing |
claim | metrics | claimed totals, checked by R9 |
The IR reference is docs/tsir; the device language the programmes run on is docs/adl.