ArchSpec — Architecture Specification

The ArchSpec defines the physical topology and transport capabilities of a Bloqade quantum device. It is the input that the bytecode compiler and validator use to determine which instructions are legal for a given hardware configuration.

The formal JSON Schema is available at archspec-schema.json.

Top-Level Structure

{
  "version": "2.0",
  "words": [...],
  "zones": [...],
  "zone_buses": [...],
  "modes": [...],
  "paths": [...],                 // optional
  "feed_forward": false,          // optional, default false
  "atom_reloading": false,        // optional, default false
  "blockade_radius": 2.0          // optional
}
FieldTypeDescription
versionstringFormat version as "major.minor" (e.g. "2.0").
wordsWord[]Word definitions. A word's ID is its index in this array.
zonesZone[]Logical zones, each owning a coordinate grid and intra-zone buses.
zone_busesInterZoneBus[]Inter-zone word buses.
modesMode[]Named operational modes (zone subsets + measurement bitstring ordering).
pathsTransportPath[](optional) AOD transport paths for lanes.
feed_forwardbool(optional, default false) Whether the device supports mid-circuit measurement with classical feedback.
atom_reloadingbool(optional, default false) Whether the device supports reloading atoms after initial fill.
blockade_radiusfloat(optional) Rydberg blockade radius in micrometers — metadata for interpreting entangling pairs.

Words

A word is an independent register of atom trapping sites. It is the fundamental unit of the device topology. A word's ID is its index in the top-level words array (e.g., the first word is word 0).

"words": [
  { "sites": [[0, 0], [1, 0], [2, 0], [3, 0], [4, 0]] }
]
FieldTypeDescription
sites[x_idx, y_idx][]Site positions as index pairs into the owning zone grid's x and y coordinate arrays.

All words must have the same number of sites (sites_per_word is derived as the site count of the first word), and every site's [x, y] indices must lie within the zone grid.


Zones

A zone is a logical region owning a coordinate grid and the transport buses that operate within it. A zone's ID is its index in the zones array (e.g., the first zone is zone 0).

"zones": [
  {
    "name": "entangling",
    "grid": {
      "x_start": 1.0,
      "y_start": 2.5,
      "x_spacing": [2.0, 2.0, 2.0, 2.0],
      "y_spacing": [2.5]
    },
    "site_buses": [
      { "src": [0, 1], "dst": [3, 4] }
    ],
    "word_buses": [
      { "src": [0], "dst": [1] }
    ],
    "words_with_site_buses": [0, 1],
    "sites_with_word_buses": [0],
    "entangling_pairs": [[0, 1]]
  }
]
FieldTypeDescription
namestring(optional, default "") Human-readable zone name.
gridGridCoordinate grid for all words in this zone.
site_busesBus[]Site buses moving atoms between sites within words of this zone.
word_busesBus[]Word buses moving atoms between words within this zone.
words_with_site_busesinteger[]Word IDs with site-bus transport capability in this zone.
sites_with_word_busesinteger[]Site indices serving as landing pads for word-bus moves.
entangling_pairs[w_a, w_b][](optional, default []) Word pairs at blockade radius for CZ gates.

Grid

A grid defines the physical coordinate axes for a zone using a start position and spacing values. Positions are typically in micrometers (µm).

FieldTypeDescription
x_startfloatX-coordinate of the first grid point.
y_startfloatY-coordinate of the first grid point.
x_spacingfloat[]Spacing between consecutive x-coordinates. The number of x grid points is len(x_spacing) + 1.
y_spacingfloat[]Spacing between consecutive y-coordinates. The number of y grid points is len(y_spacing) + 1.

The x-coordinates are computed as [x_start, x_start + x_spacing[0], x_start + x_spacing[0] + x_spacing[1], ...] (cumulative sum of spacings from the start). Same for y. Sites reference grid positions by index: site [2, 1] is located at the 3rd x-coordinate and 2nd y-coordinate. Spacings must be non-negative.

All zones must have the same grid dimensions — i.e., the same number of x and y grid points (same x_spacing and y_spacing lengths). The actual coordinate values differ (zones are at different physical locations), and zone bounding boxes must not overlap in physical space.

Entangling Pairs

Each zone's entangling_pairs lists which word pairs within it can perform CZ (entangling) gates. Within a pair, sites at matching indices in w_a and w_b are within blockade radius. A zone with no entangling pairs is a storage/low-connectivity zone.


Buses

Buses are the physical transport channels that move atoms. Each bus defines a paired mapping via parallel arrays: the atom at src[i] moves to dst[i], and all pairs of one bus execute simultaneously as one AOD operation. There are three kinds:

Site Bus

A site bus moves atoms between sites within the same word. Entries are site indices. A site bus's ID is its index in the owning zone's site_buses array.

{ "src": [0, 1, 2, 3, 4], "dst": [5, 6, 7, 8, 9] }

This means the atom at site 0 moves to site 5, the atom at site 1 moves to site 6, and so on — all in a single transport operation. Only words listed in the zone's words_with_site_buses can execute site-bus moves.

Word Bus

A word bus moves atoms between different words within a zone. The src and dst arrays contain word IDs (not site indices). A word bus's ID is its index in the owning zone's word_buses array.

{ "src": [0], "dst": [1] }

The specific sites involved in inter-word transport are those listed in the zone's sites_with_word_buses — the "landing pad" positions within each word.

Zone Bus

A zone bus (top-level zone_buses) moves words across zone boundaries. Entries are zone-qualified word references, and every (src[i], dst[i]) pair must have different zone_ids.

{
  "src": [{ "zone_id": 0, "word_id": 0 }],
  "dst": [{ "zone_id": 1, "word_id": 0 }]
}

Bus Well-Formedness

For every bus kind, the srcdst relation must be well-formed: src entries unique, dst entries unique, and acyclic (no rotations, including self-loops) — a bus is a set of explicit transports, never a permutation. Overlapping-but-acyclic relations (conveyor chains such as 0→1, 1→2) are legal. See Validation Rules.


Modes

A mode is a named operational configuration: a subset of zones plus the bitstring ordering used for measurement results.

"modes": [
  { "name": "full", "zones": [0, 1], "bitstring_order": [] }
]
FieldTypeDescription
namestringHuman-readable mode name.
zonesinteger[]Zone IDs active in this mode.
bitstring_orderinteger[]Bit-to-location mapping for measurement results. Each entry is a LocationAddr encoded as a packed integer (layout [zone_id:8][word_id:16][site_id:16][pad:24], most-significant first).

Paths (Optional)

AOD (Acousto-Optic Deflector) transport paths. Each path identifies a transport lane and provides a sequence of [x, y] waypoints defining the physical trajectory atoms follow during transport.

The lane is identified by its encoded LaneAddr, serialized as a hex string. See Address Encoding for the LaneAddr bit layout.

"paths": [
  {
    "lane": "0x2000000000000000",                       // encoded LaneAddr (hex, 16-digit)
    "waypoints": [[0.0, 0.0], [0.0, 5.0], [2.0, 5.0]]   // physical trajectory
  }
]

Each TransportPath entry has:

FieldTypeDescription
lanestringEncoded LaneAddr as a "0x..." hex string.
waypoints[x, y][]Sequence of physical coordinate waypoints (at least 2, all finite).

To decode the lane hex string, parse it as a 64-bit unsigned integer. The low 32 bits (data0) contain [word_id:16][site_id:16] and the high 32 bits (data1) contain [dir:1][mt:2][zone_id:8][pad:5][bus_id:16]. For example, "0x2000000000000000" has data1 = 0x20000000: direction=Forward (bit 31 clear), move_type=WordBus (bits 30–29 = 01), zone=0, word=0, site=0, bus=0. In the lane address convention, word_id always encodes the forward-direction source word for that lane, so a Backward lane with the same address fields moves the atom from the bus destination back to that source.

This field is omitted from the JSON when not needed.


Capability Flags (Optional)

Two boolean flags describe device capabilities that affect bytecode validation:

FieldDefaultDescription
feed_forwardfalseMid-circuit measurement with classical feedback. When false, at most one measure instruction is allowed per program.
atom_reloadingfalseAtom reloading after initial fill. When false, no fill instruction is allowed (only initial_fill).

Both fields are optional in the JSON — existing arch spec files that omit them default to false, which is the most restrictive setting.

{
  "feed_forward": true,
  "atom_reloading": false
}

Validation Rules

The ArchSpec::validate() method checks all structural rules in a single pass, collecting every error rather than failing fast. Errors are grouped into coarse ArchSpecError categories, each carrying a descriptive message; the Error column below names the category (Rust enum variant). Through the Python bindings the categories map onto exception classes:

ArchSpecError variantPython exception
StructureArchSpecGeometryError
ZoneBus, InterZoneBus, CyclicBusArchSpecBusError
EntanglingPair, ModeArchSpecZoneError
PathArchSpecPathError

Structural Rules

RuleError
At least one zone and at least one word must existStructure
All grid spacings must be non-negativeStructure
All zones must have the same grid dimensions (same number of x and y positions)Structure
All words must have the same number of sitesStructure
Every word site's [x, y] indices must lie within the zone gridStructure
No two zones may have overlapping bounding boxes in physical (x, y) spaceStructure

Per-Zone Bus Rules

RuleError
Every ID in words_with_site_buses must be a valid word IDZoneBus
Every index in sites_with_word_buses must be < sites_per_wordZoneBus
Site bus src and dst must have equal lengthZoneBus
All site bus indices in src and dst must be < sites_per_wordZoneBus
Word bus src and dst must have equal lengthZoneBus
All word bus IDs in src and dst must be valid word IDsZoneBus

Inter-Zone Bus Rules

RuleError
Zone bus src and dst must have equal lengthInterZoneBus
All zone bus zone_id / word_id entries must be in rangeInterZoneBus
Every (src[i], dst[i]) pair must cross a zone boundaryInterZoneBus

Bus Well-Formedness Rules (all bus kinds)

A bus is a set of explicit edge transports executed simultaneously as one AOD operation — never a permutation. These rules apply to site buses, word buses, and zone buses alike:

RuleError
src entries must be unique (endpoint resolution is positional first-match, so a duplicated source silently shadows later pairs)ZoneBus / InterZoneBus
dst entries must be unique (two simultaneous transports into one site cannot both complete)ZoneBus / InterZoneBus
The srcdst relation must be acyclic, including self-loops — a cycle would rotate a fully-occupied set of atoms with no empty site, which AOD hardware cannot do. Overlapping-but-acyclic relations (conveyor chains such as 0→1, 1→2) are legal.CyclicBus

Entangling Pair Rules

RuleError
Both word IDs in every entangling_pairs entry must be valid word IDsEntanglingPair
A word must not be paired with itselfEntanglingPair
No duplicate pairs (order-insensitive: [a, b] duplicates [b, a])EntanglingPair

Mode Rules

RuleError
Every zone ID in a mode must reference a defined zoneMode
Every bitstring_order entry's zone_id, word_id, and site_id must be in rangeMode

Path Rules

RuleError
Waypoint coordinates must be finite (no NaN or Inf)Path
Every path's lane must have a valid zone_idPath
Every path must have at least 2 waypointsPath

Capability Rules (Bytecode Validation)

These rules are checked during bytecode validation (ValidationError, not ArchSpecError) when an ArchSpec is provided:

RuleError
If feed_forward = false, control flow and multiple measure instructions are rejectedControlFlowRequiresFeedForward, MultipleMeasuresRequireFeedForward
If atom_reloading = false, no fill instruction is allowed (initial_fill is a separate instruction and is always permitted)FillRequiresAtomReloading

Address Encoding

At the bytecode level, locations and lanes are encoded as bit-packed integers with 16-bit address fields. Each address type is packed into instruction data words (u32):

TypeWidthLayoutDescription
LocationAddr64 bits[zone_id:8][word_id:16][site_id:16][pad:24] (most-significant first)Identifies a specific site within a word of a zone.
LaneAddr64 bits (2 × u32)data0 (low): [word_id:16][site_id:16], data1 (high): [dir:1][mt:2][zone_id:8][pad:5][bus_id:16]Identifies a transport lane (direction + move type + zone + word/site + bus).
ZoneAddr32 bits (1 × u32)[pad:24][zone_id:8]Identifies a zone.

These packed addresses are used in 16-byte bytecode instructions (opcode + 3 data words) and are validated against the arch spec during program validation. In JSON, LaneAddr is represented as a 16-digit hex string (data0 | data1 << 32) and LocationAddr as a plain integer; in Python both are u64 values.


Examples

Minimal spec with one word, one zone, and one site bus (this is examples/arch/simple.json):

{
  "version": "2.0",
  "words": [
    { "sites": [[0, 0], [1, 0], [2, 0], [3, 0], [4, 0]] }
  ],
  "zones": [
    {
      "grid": {
        "x_start": 1.0,
        "y_start": 2.0,
        "x_spacing": [2.0, 2.0, 2.0, 2.0],
        "y_spacing": []
      },
      "site_buses": [
        { "src": [0, 1], "dst": [3, 4] }
      ],
      "word_buses": [],
      "words_with_site_buses": [0],
      "sites_with_word_buses": []
    }
  ],
  "zone_buses": [],
  "modes": [
    { "name": "default", "zones": [0], "bitstring_order": [] }
  ]
}

A fuller example with multiple words, CZ pairs, and word buses is available at examples/arch/full.json.