Skip to content

Spec

ArchSpec

ArchSpec(inner: ArchSpec)

Bases: RustWrapper[ArchSpec]


              flowchart TD
              bloqade.lanes.arch.spec.ArchSpec[ArchSpec]
              bloqade.lanes.bytecode._wrapper.RustWrapper[RustWrapper]

                              bloqade.lanes.bytecode._wrapper.RustWrapper --> bloqade.lanes.arch.spec.ArchSpec
                


              click bloqade.lanes.arch.spec.ArchSpec href "" "bloqade.lanes.arch.spec.ArchSpec"
              click bloqade.lanes.bytecode._wrapper.RustWrapper href "" "bloqade.lanes.bytecode._wrapper.RustWrapper"
            

Architecture specification for a quantum device.

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
36
37
38
def __init__(self, inner: _RustArchSpec):
    self._inner = inner
    self._inner.validate()

atom_reloading property

atom_reloading: bool

Whether the device supports reloading atoms after initial fill.

blockade_radius property

blockade_radius: float | None

Rydberg blockade radius (µm), or None if not provided.

This is metadata — when present, it indicates the radius associated with the architecture and is typically used to interpret the entangling pairs. It is not independently verified at the ArchSpec level; use :meth:ZoneBuilder.set_blockade_radius / :meth:ArchBuilder.set_blockade_radius if you want the pair list to be derived from and checked against a radius.

cz_zone_addresses cached property

cz_zone_addresses: frozenset[ZoneAddress]

Zones that host CZ entangling operations (have entangling_pairs).

feed_forward property

feed_forward: bool

Whether the device supports mid-circuit measurement with classical feedback.

home_sites cached property

home_sites: frozenset[LocationAddress]

All home LocationAddresses with correct zone_id per word.

A home site is (zone_id, word_id, site_id) where word_id is a home word (lower word_id in each entangling pair, or unpaired) and zone_id is the zone that word belongs to.

max_qubits property

max_qubits: int

Get the maximum number of qubits supported by this architecture.

paths cached property

paths: MappingProxyType[
    LaneAddress, tuple[tuple[float, float], ...]
]

Transport path waypoints keyed by LaneAddress.

Derived from the Rust ArchSpec.paths on first access.

site_buses cached property

site_buses: tuple[SiteBus, ...]

Aggregate all site buses across all zones.

Note: indices in this flat list do NOT correspond to per-zone bus_id values in LaneAddress. Prefer iterating zones directly via self.zones[i].site_buses.

sites_per_word property

sites_per_word: int

Get the number of sites per word.

word_buses cached property

word_buses: tuple[WordBus, ...]

Aggregate all word buses across all zones.

Note: indices in this flat list do NOT correspond to per-zone bus_id values in LaneAddress. Prefer iterating zones directly via self.zones[i].word_buses.

word_zone_map cached property

word_zone_map: dict[int, int]

Map each word_id to the zone_id it belongs to.

Delegates to Rust ArchSpec.word_zone_map().

words cached property

words: tuple[Word, ...]

Python Word wrappers, derived from the Rust ArchSpec.

check_lane_group

check_lane_group(
    lanes: Sequence[LaneAddress],
) -> Sequence[LaneGroupError]

Validate a group of lane addresses via Rust.

Checks individual lane validity, group consistency (direction, bus_id, move_type), bus membership, and AOD geometry constraints. Returns a list of LaneGroupError exceptions (empty if all valid).

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
362
363
364
365
366
367
368
369
370
371
372
def check_lane_group(
    self, lanes: Sequence[LaneAddress]
) -> Sequence[LaneGroupError]:
    """Validate a group of lane addresses via Rust.

    Checks individual lane validity, group consistency (direction, bus_id,
    move_type), bus membership, and AOD geometry constraints.
    Returns a list of LaneGroupError exceptions (empty if all valid).
    """
    rust_addrs = [lane._inner for lane in lanes]
    return self._inner.check_lanes(rust_addrs)

check_location_group

check_location_group(
    locations: Sequence[LocationAddress],
) -> Sequence[LocationGroupError]

Validate a group of location addresses via Rust.

Returns a list of LocationGroupError exceptions (empty if all valid).

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
352
353
354
355
356
357
358
359
360
def check_location_group(
    self, locations: Sequence[LocationAddress]
) -> Sequence[LocationGroupError]:
    """Validate a group of location addresses via Rust.

    Returns a list of LocationGroupError exceptions (empty if all valid).
    """
    rust_addrs = [loc._inner for loc in locations]
    return self._inner.check_locations(rust_addrs)

from_components classmethod

from_components(
    words: tuple[Word, ...],
    zones: tuple[Zone, ...],
    modes: Sequence[Mode],
    zone_buses: Sequence[ZoneBus] = (),
    paths: (
        dict[LaneAddress, tuple[tuple[float, float], ...]]
        | None
    ) = None,
    feed_forward: bool = False,
    atom_reloading: bool = False,
    blockade_radius: float | None = None,
) -> ArchSpec

Construct an ArchSpec from Python component types.

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
@classmethod
def from_components(
    cls,
    words: tuple[Word, ...],
    zones: tuple[_RustZone, ...],
    modes: Sequence[_RustMode],
    zone_buses: Sequence[ZoneBus] = (),
    paths: dict[LaneAddress, tuple[tuple[float, float], ...]] | None = None,
    feed_forward: bool = False,
    atom_reloading: bool = False,
    blockade_radius: float | None = None,
) -> ArchSpec:
    """Construct an ArchSpec from Python component types."""

    rust_paths = None
    if paths:
        rust_paths = [
            _RustTransportPath(
                lane=_RustLaneAddress(
                    lane.move_type,
                    lane.zone_id,
                    lane.word_id,
                    lane.site_id,
                    lane.bus_id,
                    lane.direction,
                ),
                waypoints=list(waypoints),
            )
            for lane, waypoints in paths.items()
        ]

    inner = _RustArchSpec(
        version=(2, 0),
        words=[w._inner for w in words],
        zones=list(zones),
        zone_buses=list(zone_buses),
        modes=list(modes),
        paths=rust_paths,
        feed_forward=feed_forward,
        atom_reloading=atom_reloading,
        blockade_radius=blockade_radius,
    )
    return cls(inner)

get_cz_partner

get_cz_partner(
    location: LocationAddress,
) -> LocationAddress | None

Get the CZ partner for a given location.

Uses Rust-side get_cz_partner which resolves via the zone's entangling_pairs.

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
414
415
416
417
418
419
420
421
422
423
def get_cz_partner(self, location: LocationAddress) -> LocationAddress | None:
    """Get the CZ partner for a given location.

    Uses Rust-side get_cz_partner which resolves via the zone's
    entangling_pairs.
    """
    result = self._inner.get_cz_partner(location._inner)
    if result is None:
        return None
    return LocationAddress.from_inner(result)

get_lane_address

get_lane_address(
    src: LocationAddress, dst: LocationAddress
) -> LaneAddress | None

Given an input tuple of locations, gets the lane (w/direction).

Delegates to Rust ArchSpec.lane_for_endpoints().

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
374
375
376
377
378
379
380
381
382
383
384
def get_lane_address(
    self, src: LocationAddress, dst: LocationAddress
) -> LaneAddress | None:
    """Given an input tuple of locations, gets the lane (w/direction).

    Delegates to Rust ``ArchSpec.lane_for_endpoints()``.
    """
    result = self._inner.lane_for_endpoints(src._inner, dst._inner)
    if result is None:
        return None
    return LaneAddress.from_inner(result)

get_zone_index

get_zone_index(
    loc_addr: LocationAddress, zone_id: ZoneAddress
) -> int | None

O(1) flat index of a location within a zone.

Delegates to Rust ArchSpec.zone_location_index().

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
318
319
320
321
322
323
324
325
326
327
def get_zone_index(
    self,
    loc_addr: LocationAddress,
    zone_id: ZoneAddress,
) -> int | None:
    """O(1) flat index of a location within a zone.

    Delegates to Rust ``ArchSpec.zone_location_index()``.
    """
    return self._inner.zone_location_index(loc_addr._inner, zone_id.zone_id)

is_home_position

is_home_position(addr: LocationAddress) -> bool

True if this address is at a home (non-CZ-staging) word.

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
125
126
127
def is_home_position(self, addr: LocationAddress) -> bool:
    """True if this address is at a home (non-CZ-staging) word."""
    return addr.word_id in self._home_words

iter_all_lanes

iter_all_lanes() -> Iterator[LaneAddress]

Yield every valid lane address in the architecture.

Enumerates site-bus, word-bus, and zone-bus lanes in both forward and backward directions. Used by :class:~bloqade.lanes.arch.metrics.MoveMetricCalculator to compute max-duration bounds. Prefer get_lane_address(src, dst) for single-pair lookups.

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def iter_all_lanes(self) -> Iterator[LaneAddress]:
    """Yield every valid lane address in the architecture.

    Enumerates site-bus, word-bus, and zone-bus lanes in both forward
    and backward directions. Used by
    :class:`~bloqade.lanes.arch.metrics.MoveMetricCalculator` to compute
    max-duration bounds. Prefer ``get_lane_address(src, dst)`` for
    single-pair lookups.
    """
    sites_per_word = self.sites_per_word

    # Intra-zone: site buses and word buses.
    for zone_id, zone in enumerate(self._inner.zones):
        for bus_id, bus in enumerate(zone.site_buses):
            for word_id in zone.words_with_site_buses:
                for i in range(len(bus.src)):
                    for direction in (Direction.FORWARD, Direction.BACKWARD):
                        yield LaneAddress(
                            MoveType.SITE,
                            word_id,
                            bus.src[i],
                            bus_id,
                            direction,
                            zone_id,
                        )
        for bus_id, bus in enumerate(zone.word_buses):
            for site_id in zone.sites_with_word_buses:
                for word_id in bus.src:
                    for direction in (Direction.FORWARD, Direction.BACKWARD):
                        yield LaneAddress(
                            MoveType.WORD,
                            word_id,
                            site_id,
                            bus_id,
                            direction,
                            zone_id,
                        )

    # Inter-zone: zone buses.
    for bus_id, zb in enumerate(self._inner.zone_buses):
        for (src_zone, src_word), (_dst_zone, _dst_word) in zip(zb.src, zb.dst):
            for site_id in range(sites_per_word):
                for direction in (Direction.FORWARD, Direction.BACKWARD):
                    yield LaneAddress(
                        MoveType.ZONE,
                        src_word,
                        site_id,
                        bus_id,
                        direction,
                        src_zone,
                    )

to_json

to_json() -> str

Serialize this architecture spec to a JSON string.

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
262
263
264
def to_json(self) -> str:
    """Serialize this architecture spec to a JSON string."""
    return self._inner.to_json()

try_get_endpoints

try_get_endpoints(
    lane_address: LaneAddress,
) -> tuple[LocationAddress, LocationAddress] | None

Resolve lane_address to its (src, dst) location pair, or None when the lane is not a valid lane in the architecture (matches the Rust lane_endpoints contract).

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
def try_get_endpoints(
    self, lane_address: LaneAddress
) -> tuple[LocationAddress, LocationAddress] | None:
    """Resolve ``lane_address`` to its (src, dst) location pair, or
    ``None`` when the lane is not a valid lane in the architecture
    (matches the Rust ``lane_endpoints`` contract).
    """
    result = self._inner.lane_endpoints(lane_address._inner)
    if result is None:
        return None
    rust_src, rust_dst = result
    return (
        LocationAddress.from_inner(rust_src),
        LocationAddress.from_inner(rust_dst),
    )

try_get_position

try_get_position(
    location: LocationAddress,
) -> tuple[float, float] | None

Resolve location to its physical (x, y) position, or None when location doesn't correspond to a valid site under the zone its zone_id selects (matches the Rust location_position contract).

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
344
345
346
347
348
349
350
def try_get_position(self, location: LocationAddress) -> tuple[float, float] | None:
    """Resolve ``location`` to its physical (x, y) position, or
    ``None`` when ``location`` doesn't correspond to a valid site
    under the zone its ``zone_id`` selects (matches the Rust
    ``location_position`` contract).
    """
    return self._inner.location_position(location._inner)

yield_zone_locations

yield_zone_locations(
    zone_address: ZoneAddress,
) -> Iterator[LocationAddress]

Yield LocationAddresses in the canonical zone-bitstring iteration order.

This is the layout that get_zone_index(loc, zone_address) numbers: every (word, site) pair in the architecture, tagged with zone_address, walked in word-major then site-major order. The iterator visits every word — zone_address is the tag stamped onto each yielded address (and the grid through which downstream calls like get_position interpret it), not a membership filter.

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/arch/spec.py
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
def yield_zone_locations(
    self, zone_address: ZoneAddress
) -> Iterator[LocationAddress]:
    """Yield ``LocationAddress``es in the canonical zone-bitstring iteration order.

    This is the layout that ``get_zone_index(loc, zone_address)``
    numbers: every ``(word, site)`` pair in the architecture, tagged
    with ``zone_address``, walked in word-major then site-major order.
    The iterator visits every word — ``zone_address`` is the tag
    stamped onto each yielded address (and the grid through which
    downstream calls like ``get_position`` interpret it), not a
    membership filter.
    """
    zone_id = zone_address.zone_id
    for word_id in range(len(self.words)):
        word = self.words[word_id]
        for site_id in range(len(word.site_indices)):
            yield LocationAddress(word_id, site_id, zone_id)