Skip to content

Movement

PhysicalPlacementStrategy dataclass

PhysicalPlacementStrategy(
    arch_spec: ArchSpec = get_physical_arch_spec(),
    traversal: RustPlacementTraversal = (
        lambda: RustPlacementTraversal(strategy="entropy")
    )(),
    target_generator: (
        TargetGeneratorABC | TargetGeneratorCallable | None
    ) = None,
)

Bases: PlacementStrategyABC


              flowchart TD
              bloqade.lanes.heuristics.physical.movement.PhysicalPlacementStrategy[PhysicalPlacementStrategy]
              bloqade.lanes.analysis.placement.strategy.PlacementStrategyABC[PlacementStrategyABC]

                              bloqade.lanes.analysis.placement.strategy.PlacementStrategyABC --> bloqade.lanes.heuristics.physical.movement.PhysicalPlacementStrategy
                


              click bloqade.lanes.heuristics.physical.movement.PhysicalPlacementStrategy href "" "bloqade.lanes.heuristics.physical.movement.PhysicalPlacementStrategy"
              click bloqade.lanes.analysis.placement.strategy.PlacementStrategyABC href "" "bloqade.lanes.analysis.placement.strategy.PlacementStrategyABC"
            

Physical placement strategy backed by the Rust MoveSolver.

rust_entropy_fallback_count property

rust_entropy_fallback_count: int

Number of solved Rust entropy stages that used sequential fallback.

rust_nodes_expanded_total property

rust_nodes_expanded_total: int

Total Rust solver node expansions for this strategy instance.

traced_blocked_locations property

traced_blocked_locations: tuple[LocationAddress, ...]

Spectator atom positions for the traced CZ layer (atoms not in the active placement).

traced_target property

traced_target: dict[int, LocationAddress]

First candidate target for the traced CZ layer (used by visualizers).

RustPlacementTraversal dataclass

RustPlacementTraversal(
    strategy: SearchStrategyName = "entropy",
    max_movesets_per_group: int = 3,
    max_goal_candidates: int = 3,
    max_expansions: int | None = 300,
    restarts: int = 1,
    lookahead: bool = False,
    collect_entropy_trace: bool = False,
)

Config for the Rust MoveSolver.

restarts and lookahead are now exposed and threaded into SolveOptions; per-strategy entropy knobs (max_movesets_per_group, max_goal_candidates, collect_entropy_trace) feed EntropyOptions via :func:solve_options_from_traversal.

Not yet exposed (Rust defaults used): weight, deadlock_policy, w_t. These will be threaded through once validated via Rust-only benchmarking.

convert_move_layers

convert_move_layers(
    raw_layers,
) -> tuple[tuple[LaneAddress, ...], ...]

Wrap Rust solver move_layers into Python LaneAddress tuples.

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/heuristics/physical/movement.py
48
49
50
51
52
53
54
def convert_move_layers(
    raw_layers,
) -> tuple[tuple[LaneAddress, ...], ...]:
    """Wrap Rust solver move_layers into Python ``LaneAddress`` tuples."""
    return tuple(
        tuple(LaneAddress.from_inner(lane) for lane in step) for step in raw_layers
    )

make_physical_placement_strategy

make_physical_placement_strategy(
    *,
    move_solutions_per_layer: int = 3,
    search_budget: int | None = 300,
    strategy: SearchStrategyName = "entropy",
    arch_spec: ArchSpec | None = None,
    return_moves: bool = True,
    target_generator: (
        TargetGeneratorABC | TargetGeneratorCallable | None
    ) = None
) -> PlacementStrategyABC

Build a physical placement strategy from user-facing search knobs.

move_solutions_per_layer maps to the Rust solver's max_goal_candidates. search_budget maps to the per-CZ-stage max_expansions budget shared across target candidates.

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/heuristics/physical/movement.py
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
def make_physical_placement_strategy(
    *,
    move_solutions_per_layer: int = 3,
    search_budget: int | None = 300,
    strategy: SearchStrategyName = "entropy",
    arch_spec: ArchSpec | None = None,
    return_moves: bool = True,
    target_generator: TargetGeneratorABC | TargetGeneratorCallable | None = None,
) -> PlacementStrategyABC:
    """Build a physical placement strategy from user-facing search knobs.

    ``move_solutions_per_layer`` maps to the Rust solver's
    ``max_goal_candidates``. ``search_budget`` maps to the per-CZ-stage
    ``max_expansions`` budget shared across target candidates.
    """
    if move_solutions_per_layer < 1:
        raise ValueError("move_solutions_per_layer must be >= 1")
    if search_budget is not None and search_budget < 1:
        raise ValueError("search_budget must be None or >= 1")

    inner = PhysicalPlacementStrategy(
        arch_spec=get_physical_arch_spec() if arch_spec is None else arch_spec,
        traversal=RustPlacementTraversal(
            strategy=strategy,
            max_goal_candidates=move_solutions_per_layer,
            max_expansions=search_budget,
        ),
        target_generator=target_generator,
    )

    return PalindromePlacementStrategy(inner=inner) if return_moves else inner

solve_options_from_traversal

solve_options_from_traversal(
    traversal: RustPlacementTraversal,
    *,
    collect_entropy_trace: bool | None = None
) -> tuple[_native.SolveOptions, _native.EntropyOptions]

Build (SolveOptions, EntropyOptions) from a RustPlacementTraversal.

Shared by PhysicalPlacementStrategy and move_synthesis so the two callsites cannot drift on default knob values. collect_entropy_trace overrides the traversal's flag when set; this is used by _cz_placements_rust to gate trace capture by stage.

Source code in .venv/lib/python3.12/site-packages/bloqade/lanes/heuristics/physical/movement.py
 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
def solve_options_from_traversal(
    traversal: RustPlacementTraversal,
    *,
    collect_entropy_trace: bool | None = None,
) -> tuple[_native.SolveOptions, _native.EntropyOptions]:
    """Build ``(SolveOptions, EntropyOptions)`` from a ``RustPlacementTraversal``.

    Shared by ``PhysicalPlacementStrategy`` and ``move_synthesis`` so the
    two callsites cannot drift on default knob values. ``collect_entropy_trace``
    overrides the traversal's flag when set; this is used by
    ``_cz_placements_rust`` to gate trace capture by stage.
    """
    opts = _native.SolveOptions(
        strategy=_STRATEGY_MAP[traversal.strategy],
        restarts=traversal.restarts,
        lookahead=traversal.lookahead,
    )
    entropy_opts = _native.EntropyOptions(
        max_movesets_per_group=traversal.max_movesets_per_group,
        max_goal_candidates=traversal.max_goal_candidates,
        collect_entropy_trace=(
            traversal.collect_entropy_trace
            if collect_entropy_trace is None
            else collect_entropy_trace
        ),
    )
    return opts, entropy_opts