Skip to content

Commit 0111a6e

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent ddbc78d commit 0111a6e

File tree

1 file changed

+69
-62
lines changed

1 file changed

+69
-62
lines changed

src/qibo/transpiler/router.py

+69-62
Original file line numberDiff line numberDiff line change
@@ -176,24 +176,26 @@ def __init__(
176176
initial_layout: dict,
177177
circuit: Optional[Circuit] = None,
178178
blocks: Optional[CircuitBlocks] = None,
179-
temp: Optional[bool] = False, #2# for temporary circuit
179+
temp: Optional[bool] = False, # 2# for temporary circuit
180180
):
181181
self.initial_layout = dict(sorted(initial_layout.items()))
182182

183-
#1# bidirectional mapping
184-
#1# self._p2l: physical qubit number i -> logical qubit number _p2l[i]
185-
#1# self._l2p: logical qubit number i -> physical qubit number _l2p[i]
186-
self._l2p, self._p2l = [0] * len(self.initial_layout), [0] * len(self.initial_layout)
183+
# 1# bidirectional mapping
184+
# 1# self._p2l: physical qubit number i -> logical qubit number _p2l[i]
185+
# 1# self._l2p: logical qubit number i -> physical qubit number _l2p[i]
186+
self._l2p, self._p2l = [0] * len(self.initial_layout), [0] * len(
187+
self.initial_layout
188+
)
187189
for mapping in self.initial_layout.items():
188190
physical_qubit, logical_qubit = int(mapping[0][1:]), mapping[1]
189191
self._l2p[logical_qubit] = physical_qubit
190192
self._p2l[physical_qubit] = logical_qubit
191193

192194
self._temporary = temp
193-
if self._temporary: #2# if temporary circuit, no need to store the blocks
195+
if self._temporary: # 2# if temporary circuit, no need to store the blocks
194196
return
195197

196-
self._nqubits = circuit.nqubits #1# number of qubits
198+
self._nqubits = circuit.nqubits # 1# number of qubits
197199
if circuit is None:
198200
raise_error(ValueError, "Circuit must be provided.")
199201

@@ -205,7 +207,7 @@ def __init__(
205207
self._routed_blocks = CircuitBlocks(Circuit(circuit.nqubits))
206208
self._swaps = 0
207209

208-
#1# previous: set_circuit_logical
210+
# 1# previous: set_circuit_logical
209211
def set_p2l(self, p2l_map: list):
210212
"""Sets the current physical to logical qubit mapping.
211213
@@ -214,8 +216,8 @@ def set_p2l(self, p2l_map: list):
214216
Args:
215217
p2l_map (list): physical to logical mapping.
216218
"""
217-
#1# update bidirectional mapping
218-
#4# use shallow copy
219+
# 1# update bidirectional mapping
220+
# 4# use shallow copy
219221
self._p2l = p2l_map.copy()
220222
self._l2p = [0] * len(self._p2l)
221223
for i, l in enumerate(self._p2l):
@@ -234,9 +236,7 @@ def execute_block(self, block: Block):
234236
Args:
235237
block (:class:`qibo.transpiler.blocks.Block`): block to be removed.
236238
"""
237-
self._routed_blocks.add_block(
238-
block.on_qubits(self.get_physical_qubits(block))
239-
)
239+
self._routed_blocks.add_block(block.on_qubits(self.get_physical_qubits(block)))
240240
self.circuit_blocks.remove_block(block)
241241

242242
def routed_circuit(self, circuit_kwargs: Optional[dict] = None):
@@ -253,11 +253,8 @@ def routed_circuit(self, circuit_kwargs: Optional[dict] = None):
253253
def final_layout(self):
254254
"""Returns the final physical-logical qubits mapping."""
255255

256-
#1# return {"q0": lq_num0, "q1": lq_num1, ...}
257-
unsorted_dict = {
258-
"q" + str(i): self._p2l[i]
259-
for i in range(self._nqubits)
260-
}
256+
# 1# return {"q0": lq_num0, "q1": lq_num1, ...}
257+
unsorted_dict = {"q" + str(i): self._p2l[i] for i in range(self._nqubits)}
261258

262259
return dict(sorted(unsorted_dict.items()))
263260

@@ -273,14 +270,14 @@ def update(self, swap_l: tuple):
273270

274271
swap_p = self.logical_pair_to_physical(swap_l)
275272

276-
#2# add the real SWAP gate, not a temporary circuit
273+
# 2# add the real SWAP gate, not a temporary circuit
277274
if not self._temporary:
278275
self._routed_blocks.add_block(
279276
Block(qubits=swap_p, gates=[gates.SWAP(*swap_p)])
280277
)
281278
self._swaps += 1
282279

283-
#1# update the bidirectional mapping
280+
# 1# update the bidirectional mapping
284281
p1, p2 = swap_p
285282
l1, l2 = swap_l
286283
self._p2l[p1], self._p2l[p2] = l2, l1
@@ -294,7 +291,7 @@ def undo(self):
294291
self._routed_blocks.remove_block(last_swap_block)
295292
self._swaps -= 1
296293

297-
#1# update the bidirectional mapping
294+
# 1# update the bidirectional mapping
298295
p1, p2 = swap_p
299296
l1, l2 = swap_l
300297
self._p2l[p1], self._p2l[p2] = l2, l1
@@ -314,7 +311,7 @@ def get_physical_qubits(self, block: Union[int, Block]):
314311

315312
return tuple(self._l2p[q] for q in block.qubits)
316313

317-
#1# logical_to_physical -> logical_pair_to_physical
314+
# 1# logical_to_physical -> logical_pair_to_physical
318315
def logical_pair_to_physical(self, logical_qubits: tuple):
319316
"""Returns the physical qubits associated to the logical qubit pair.
320317
@@ -324,10 +321,11 @@ def logical_pair_to_physical(self, logical_qubits: tuple):
324321
Returns:
325322
tuple: physical qubit numbers associated to the logical qubit pair.
326323
"""
327-
#1# return physical qubit numbers corresponding to the logical qubit pair
324+
# 1# return physical qubit numbers corresponding to the logical qubit pair
328325
return self._l2p[logical_qubits[0]], self._l2p[logical_qubits[1]]
329326

330-
#1# circuit_to_logical(), circuit_to_physical() removed
327+
# 1# circuit_to_logical(), circuit_to_physical() removed
328+
331329

332330
class ShortestPaths(Router):
333331
"""A class to perform initial qubit mapping and connectivity matching.
@@ -382,9 +380,12 @@ def __call__(self, circuit: Circuit, initial_layout: dict):
382380
routed_circuit=routed_circuit
383381
)
384382

385-
#1# final layout is reverted to the original labeling
383+
# 1# final layout is reverted to the original labeling
386384
final_layout = self.circuit.final_layout()
387-
final_layout_restored = {"q" + str(self.node_mapping_inv[int(k[1:])]): v for k, v in final_layout.items()}
385+
final_layout_restored = {
386+
"q" + str(self.node_mapping_inv[int(k[1:])]): v
387+
for k, v in final_layout.items()
388+
}
388389
return routed_circuit, final_layout_restored
389390

390391
def _find_new_mapping(self):
@@ -434,15 +435,14 @@ def _add_swaps(candidate: tuple, circuitmap: CircuitMap):
434435
"""
435436
path = candidate[0]
436437
meeting_point = candidate[1]
437-
forward = path[0 : meeting_point + 1] #1# physical qubits
438+
forward = path[0 : meeting_point + 1] # 1# physical qubits
438439
backward = list(reversed(path[meeting_point + 1 :]))
439-
#1# apply logical swaps
440+
# 1# apply logical swaps
440441
for f in forward[1:]:
441442
circuitmap.update((circuitmap._p2l[f], circuitmap._p2l[forward[0]]))
442443
for b in backward[1:]:
443444
circuitmap.update((circuitmap._p2l[b], circuitmap._p2l[backward[0]]))
444445

445-
446446
def _compute_cost(self, candidate: tuple):
447447
"""Greedy algorithm that decides which path to take and how qubits should be walked.
448448
@@ -454,14 +454,14 @@ def _compute_cost(self, candidate: tuple):
454454
Returns:
455455
(list, int): best path to move qubits and qubit meeting point in the path.
456456
"""
457-
#2# CircuitMap might be used
457+
# 2# CircuitMap might be used
458458
temporary_circuit = CircuitMap(
459459
initial_layout=self.circuit.initial_layout,
460460
circuit=Circuit(len(self.circuit.initial_layout)),
461461
blocks=deepcopy(self.circuit.circuit_blocks),
462462
)
463463

464-
#1# use set_p2l
464+
# 1# use set_p2l
465465
temporary_circuit.set_p2l(self.circuit._p2l)
466466
self._add_swaps(candidate, temporary_circuit)
467467
temporary_dag = deepcopy(self._dag)
@@ -476,7 +476,7 @@ def _compute_cost(self, candidate: tuple):
476476
all_executed = True
477477
for block in temporary_front_layer:
478478
if (
479-
#3# might be changed to use _get_dag_layer(qubits=True) to avoid using get_physical_qubits(block_num)
479+
# 3# might be changed to use _get_dag_layer(qubits=True) to avoid using get_physical_qubits(block_num)
480480
temporary_circuit.get_physical_qubits(block)
481481
in self.connectivity.edges
482482
or not temporary_circuit.circuit_blocks.search_by_index(
@@ -504,7 +504,7 @@ def _check_execution(self):
504504
executable_blocks = []
505505
for block in self._front_layer:
506506
if (
507-
#3# might be changed to use _get_dag_layer(qubits=True) to avoid using get_physical_qubits(block_num)
507+
# 3# might be changed to use _get_dag_layer(qubits=True) to avoid using get_physical_qubits(block_num)
508508
self.circuit.get_physical_qubits(block) in self.connectivity.edges
509509
or not self.circuit.circuit_blocks.search_by_index(block).entangled
510510
):
@@ -554,7 +554,7 @@ def _preprocessing(self, circuit: Circuit, initial_layout: dict):
554554
initial_layout (dict): initial physical-to-logical qubit mapping.
555555
"""
556556

557-
#1# To simplify routing, some data is relabeled before routing begins.
557+
# 1# To simplify routing, some data is relabeled before routing begins.
558558
node_mapping, new_initial_layout = {}, {}
559559
for i, node in enumerate(self.connectivity.nodes):
560560
node_mapping[node] = i
@@ -596,8 +596,9 @@ def _append_final_measurements(self, routed_circuit: Circuit):
596596
for measurement in self._final_measurements:
597597
original_qubits = measurement.qubits
598598
routed_qubits = list(
599-
#1# use l2p to get physical qubit numbers
600-
self.circuit._l2p[qubit] for qubit in original_qubits
599+
# 1# use l2p to get physical qubit numbers
600+
self.circuit._l2p[qubit]
601+
for qubit in original_qubits
601602
)
602603
routed_circuit.add(
603604
measurement.on_qubits(dict(zip(original_qubits, routed_qubits)))
@@ -643,7 +644,7 @@ def __init__(
643644
seed: Optional[int] = None,
644645
):
645646
self.connectivity = connectivity
646-
#1# map to revert the final layout to the original labeling
647+
# 1# map to revert the final layout to the original labeling
647648
self.node_mapping_inv = None
648649
self.lookahead = lookahead
649650
self.decay = decay_lookahead
@@ -698,9 +699,12 @@ def __call__(self, circuit: Circuit, initial_layout: dict):
698699
routed_circuit=routed_circuit
699700
)
700701

701-
#1# final layout is reverted to the original labeling
702+
# 1# final layout is reverted to the original labeling
702703
final_layout = self.circuit.final_layout()
703-
final_layout_restored = {"q" + str(self.node_mapping_inv[int(k[1:])]): v for k, v in final_layout.items()}
704+
final_layout_restored = {
705+
"q" + str(self.node_mapping_inv[int(k[1:])]): v
706+
for k, v in final_layout.items()
707+
}
704708
return routed_circuit, final_layout_restored
705709

706710
@property
@@ -724,8 +728,8 @@ def _preprocessing(self, circuit: Circuit, initial_layout: dict):
724728
initial_layout (dict): initial physical-to-logical qubit mapping.
725729
"""
726730

727-
#1# To simplify routing, some data is relabeled before routing begins.
728-
#1# physical qubit is reassigned to a range from 0 to len(self.connectivity.nodes) - 1.
731+
# 1# To simplify routing, some data is relabeled before routing begins.
732+
# 1# physical qubit is reassigned to a range from 0 to len(self.connectivity.nodes) - 1.
729733
node_mapping, new_initial_layout = {}, {}
730734
for i, node in enumerate(self.connectivity.nodes):
731735
node_mapping[node] = i
@@ -769,8 +773,9 @@ def _append_final_measurements(self, routed_circuit: Circuit):
769773
for measurement in self._final_measurements:
770774
original_qubits = measurement.qubits
771775
routed_qubits = list(
772-
#1# use l2p to get physical qubit numbers
773-
self.circuit._l2p[qubit] for qubit in original_qubits
776+
# 1# use l2p to get physical qubit numbers
777+
self.circuit._l2p[qubit]
778+
for qubit in original_qubits
774779
)
775780
routed_circuit.add(
776781
measurement.on_qubits(dict(zip(original_qubits, routed_qubits)))
@@ -799,8 +804,8 @@ def _get_dag_layer(self, n_layer, qubits=False):
799804
Otherwise, return the block numbers.
800805
"""
801806

802-
#3# depend on the 'qubits' flag, return the block number or target qubits
803-
#3# return target qubits -> to avoid using get_physical_qubits(block_num)
807+
# 3# depend on the 'qubits' flag, return the block number or target qubits
808+
# 3# return target qubits -> to avoid using get_physical_qubits(block_num)
804809
if qubits:
805810
layer_qubits = []
806811
nodes = self._dag.nodes(data=True)
@@ -816,7 +821,7 @@ def _find_new_mapping(self):
816821
"""Find the new best mapping by adding one swap."""
817822
candidates_evaluation = {}
818823

819-
#4# use shallow copy
824+
# 4# use shallow copy
820825
self._memory_map.append(self.circuit._p2l.copy())
821826
for candidate in self._swap_candidates():
822827
candidates_evaluation[candidate] = self._compute_cost(candidate)
@@ -835,31 +840,31 @@ def _find_new_mapping(self):
835840
def _compute_cost(self, candidate: int):
836841
"""Compute the cost associated to a possible SWAP candidate."""
837842

838-
#2# use CircuitMap for temporary circuit to save time
839-
#2# no gates, no block decomposition, no Circuit object
840-
#2# just logical-physical mapping
843+
# 2# use CircuitMap for temporary circuit to save time
844+
# 2# no gates, no block decomposition, no Circuit object
845+
# 2# just logical-physical mapping
841846
temporary_circuit = CircuitMap(
842847
initial_layout=self.circuit.initial_layout,
843848
temp=True,
844849
)
845850

846-
#1# use set_p2l
851+
# 1# use set_p2l
847852
temporary_circuit.set_p2l(self.circuit._p2l)
848853
temporary_circuit.update(candidate)
849854

850-
#1# use p2l to check if the mapping is already in the memory
855+
# 1# use p2l to check if the mapping is already in the memory
851856
if temporary_circuit._p2l in self._memory_map:
852857
return float("inf")
853858

854859
tot_distance = 0.0
855860
weight = 1.0
856861
for layer in range(self.lookahead + 1):
857-
#3# return gates' target qubit pairs in the layer
858-
#3# to avoid using get_physical_qubits(block_num)
862+
# 3# return gates' target qubit pairs in the layer
863+
# 3# to avoid using get_physical_qubits(block_num)
859864
layer_gates = self._get_dag_layer(layer, qubits=True)
860865
avg_layer_distance = 0.0
861866
for lq_pair in layer_gates:
862-
#3# logical qubit pairs to node numbers (physical qubit pairs) in the connectivity graph
867+
# 3# logical qubit pairs to node numbers (physical qubit pairs) in the connectivity graph
863868
qubits = temporary_circuit.logical_pair_to_physical(lq_pair)
864869
avg_layer_distance += (
865870
max(self._delta_register[i] for i in qubits)
@@ -881,7 +886,7 @@ def _swap_candidates(self):
881886
(list): list of candidates.
882887
"""
883888
candidates = []
884-
#3# might be changed to use _get_dag_layer(qubits=True) to avoid using get_physical_qubits(block_num)
889+
# 3# might be changed to use _get_dag_layer(qubits=True) to avoid using get_physical_qubits(block_num)
885890
for block in self._front_layer:
886891
for qubit in self.circuit.get_physical_qubits(block):
887892
for connected in self.connectivity.neighbors(qubit):
@@ -907,7 +912,7 @@ def _check_execution(self):
907912
executable_blocks = []
908913
for block in self._front_layer:
909914
if (
910-
#3# might be changed to use _get_dag_layer(qubits=True) to avoid using get_physical_qubits(block_num)
915+
# 3# might be changed to use _get_dag_layer(qubits=True) to avoid using get_physical_qubits(block_num)
911916
self.circuit.get_physical_qubits(block) in self.connectivity.edges
912917
or not self.circuit.circuit_blocks.search_by_index(block).entangled
913918
):
@@ -950,8 +955,8 @@ def _shortest_path_routing(self):
950955
shortest_path_qubits = None
951956

952957
for block in self._front_layer:
953-
#3# return node numbers (physical qubits) in the connectivity graph
954-
#3# might be changed to use _get_dag_layer(qubits=True) to avoid using get_physical_qubits(block_num)
958+
# 3# return node numbers (physical qubits) in the connectivity graph
959+
# 3# might be changed to use _get_dag_layer(qubits=True) to avoid using get_physical_qubits(block_num)
955960
q1, q2 = self.circuit.get_physical_qubits(block)
956961
distance = self._dist_matrix[q1, q2]
957962

@@ -964,11 +969,12 @@ def _shortest_path_routing(self):
964969
)
965970

966971
# move q1
967-
#1# qubit moving algorithm is changed
972+
# 1# qubit moving algorithm is changed
968973
q1 = self.circuit._p2l[shortest_path[0]]
969974
for q2 in shortest_path[1:-1]:
970975
self.circuit.update((q1, self.circuit._p2l[q2]))
971976

977+
972978
def _create_dag(gates_qubits_pairs: list):
973979
"""Helper method for :meth:`qibo.transpiler.router.Sabre`.
974980
@@ -984,7 +990,7 @@ def _create_dag(gates_qubits_pairs: list):
984990
dag = nx.DiGraph()
985991
dag.add_nodes_from(range(len(gates_qubits_pairs)))
986992

987-
#3# additionally store target qubits of the gates
993+
# 3# additionally store target qubits of the gates
988994
for i in range(len(gates_qubits_pairs)):
989995
dag.nodes[i]["qubits"] = gates_qubits_pairs[i]
990996

@@ -1003,6 +1009,7 @@ def _create_dag(gates_qubits_pairs: list):
10031009

10041010
return _remove_redundant_connections(dag)
10051011

1012+
10061013
def _remove_redundant_connections(dag: nx.DiGraph):
10071014
"""Helper method for :func:`qibo.transpiler.router._create_dag`.
10081015
@@ -1015,9 +1022,9 @@ def _remove_redundant_connections(dag: nx.DiGraph):
10151022
(:class:`networkx.DiGraph`): reduced dag.
10161023
"""
10171024
new_dag = nx.DiGraph()
1018-
#3# add nodes with attributes
1025+
# 3# add nodes with attributes
10191026
new_dag.add_nodes_from(dag.nodes(data=True))
10201027
transitive_reduction = nx.transitive_reduction(dag)
10211028
new_dag.add_edges_from(transitive_reduction.edges)
10221029

1023-
return new_dag
1030+
return new_dag

0 commit comments

Comments
 (0)