mqt.ionshuttler.multi_shuttler.outside.scheduling

Module Contents

EXIT = True
ON_CYCLE = False
preprocess(graph: Graph, priority_queue: dict[int, str]) None[source]
get_edge_idc_by_pz_name(graph: Graph, pz_name: str) Edge[source]
pick_pz_for_2_q_gate(graph: Graph, ion0: int, ion1: int) str[source]
assign_gate_to_pz(graph: Graph, gate: GateRef) str[source]

Dispatch a gate ID or qubit tuple to the corresponding PZ assignment path.

create_priority_queue(graph: Graph, pz_executing_gate_order: list[str], max_length: int = 10) tuple[dict[int, str], dict[str, GateRef]][source]

Create a priority queue based on a given graph and sequence of gates. Also creates a dictionary of the next gate of each processing zone.

Parameters:
  • graph – The graph representing the QCCD architecture.

  • pz_executing_gate_order – The sequence of gates.

  • max_length – The maximum length of the priority queue. Defaults to 10.

Returns:

  • The priority queue

  • The next gate at each processing zone

get_partitioned_priority_queues(priority_queue: dict[int, str]) dict[str, list[int]][source]
create_gate_info_list(graph: Graph) dict[str, list[int]][source]
create_move_list(graph: Graph, partitioned_priority_queue: list[int], pz: ProcessingZone) list[int][source]

Create a move list based on a given graph and partitioned priority queue. Move list is specific to a processing zone.

That is also why the single processing zone logic can be implemented here (entry move has path_length 0, since it is the first ion in priority queue).

bfs_free_edge(graph: Graph, node: Node, other_next_edges: list[Edge]) Edge[source]
calculate_next_edges_for_moves(graph: Graph, move_list: list[int], pz: ProcessingZone) dict[int, tuple[Edge, Edge]][source]

Pre-calculate the next edges for hybrid cycle/path selection in find_movable_cycles().

MZ-only: compute the immediate next edge for each ion in move_list, but only if the ion is currently in the memory zone grid (trap edges).

For non-trap (entry/exit/PZ) positions, return (current_edge, current_edge).

create_cycles_for_moves(graph: Graph, move_list: list[int], cycle_or_paths: str, next_edges: dict[int, tuple[Edge, Edge]], pz: ProcessingZone) tuple[dict[int, list[Edge]], dict[int, Edge]][source]
split_ions_by_direction_on_move(move_edges: Sequence[Edge], next_edges: dict[int, tuple[Edge, Edge]]) tuple[list[int], list[int]][source]

Compare each ion’s planned step (current_edge -> next_edge) against a given move (path/cycle).

Returns:

(ions_same_direction, ions_opposite_direction)

  • “same direction”: (current_edge, next_edge) appears as consecutive edges in move_edges

  • “opposite direction”: (next_edge, current_edge) appears as consecutive edges in move_edges

  • ions not matching either are ignored

cost_function_hybrid(graph: Graph, cycle: Sequence[Edge], path: Sequence[Edge], next_edges: dict[int, tuple[Edge, Edge]]) int[source]

Cost function for hybrid approach. Decide based on cycle length and path length whether to use cycle or path.

update_entry_and_exit_cycles(graph: Graph, pz: ProcessingZone, all_cycles: dict[int, list[Edge]], in_and_into_exit_moves_pz: dict[int, Edge], out_of_entry_moves_pz: list[Edge] | None, prio_queue: list[int]) dict[int, list[Edge]][source]
find_movable_cycles(graph: Graph, all_cycles: dict[int, list[Edge]], priority_queue: dict[int, str], cycle_or_paths: str) list[int][source]
rotate(graph: Graph, ion: int, cycle_idcs: list[Edge]) None[source]
rotate_free_cycles(graph: Graph, all_cycles: dict[int, list[Edge]], free_cycles_idxs: list[int]) None[source]
find_out_of_entry_moves(graph: Graph, other_next_edges: list[Edge]) dict[ProcessingZone, list[Edge]][source]
classify_selected_move_kind(move_edges: Sequence[Edge]) str[source]

Classify a selected move as ‘cycle’, ‘path’, or ‘stop’.