|
40 | 40 | pytket = NotImplemented |
41 | 41 | else: |
42 | 42 | raise ImportError( |
43 | | - "Routing utilities don't exist in this version of Cirq and pytket is not installed." |
| 43 | + "Routing utilities don't exist in this version of Cirq and PyTket is not installed." |
44 | 44 | ) |
45 | 45 |
|
46 | 46 | import recirq |
@@ -116,27 +116,32 @@ def place_on_device(circuit: cirq.Circuit, |
116 | 116 | """ |
117 | 117 |
|
118 | 118 | if RouteCQC is NotImplemented: |
119 | | - # Use TKET for routing |
120 | | - tk_circuit = pytket.extensions.cirq.cirq_to_tk(circuit) |
121 | | - tk_device = _device_to_tket_device(device) |
122 | | - |
123 | | - unit = CompilationUnit(tk_circuit, [ConnectivityPredicate(tk_device)]) |
124 | | - passes = SequencePass([ |
125 | | - PlacementPass(GraphPlacement(tk_device)), |
126 | | - RoutingPass(tk_device)]) |
127 | | - passes.apply(unit) |
128 | | - valid = unit.check_all_predicates() |
129 | | - if not valid: |
130 | | - raise RuntimeError("Routing failed") |
131 | | - |
132 | | - initial_map = {tk_to_cirq_qubit(n1): tk_to_cirq_qubit(n2) |
133 | | - for n1, n2 in unit.initial_map.items()} |
134 | | - final_map = {tk_to_cirq_qubit(n1): tk_to_cirq_qubit(n2) |
135 | | - for n1, n2 in unit.final_map.items()} |
136 | | - routed_circuit = pytket.extensions.cirq.tk_to_cirq(unit.circuit) |
137 | | - |
138 | | - return routed_circuit, initial_map, final_map |
139 | | - |
| 119 | + # Use TKET for routing if it's available |
| 120 | + if pytket is NotImplemented: |
| 121 | + # This can happen in CI testing (see top of this file), in which case, the test code |
| 122 | + # will deal with this scenario. In other situations, this is a problem. |
| 123 | + raise RuntimeError("Routing utilities are not available") |
| 124 | + else: |
| 125 | + tk_circuit = pytket.extensions.cirq.cirq_to_tk(circuit) |
| 126 | + tk_device = _device_to_tket_device(device) |
| 127 | + |
| 128 | + unit = CompilationUnit(tk_circuit, [ConnectivityPredicate(tk_device)]) |
| 129 | + passes = SequencePass([ |
| 130 | + PlacementPass(GraphPlacement(tk_device)), |
| 131 | + RoutingPass(tk_device)]) |
| 132 | + passes.apply(unit) |
| 133 | + valid = unit.check_all_predicates() |
| 134 | + if not valid: |
| 135 | + raise RuntimeError("Routing failed") |
| 136 | + |
| 137 | + initial_map = {tk_to_cirq_qubit(n1): tk_to_cirq_qubit(n2) |
| 138 | + for n1, n2 in unit.initial_map.items()} |
| 139 | + final_map = {tk_to_cirq_qubit(n1): tk_to_cirq_qubit(n2) |
| 140 | + for n1, n2 in unit.final_map.items()} |
| 141 | + routed_circuit = pytket.extensions.cirq.tk_to_cirq(unit.circuit) |
| 142 | + |
| 143 | + return routed_circuit, initial_map, final_map |
| 144 | + |
140 | 145 | # Else use Cirq for routing |
141 | 146 | router = cirq.RouteCQC(device.metadata.nx_graph) |
142 | 147 | routed_circuit, initial_map, swap_map = router.route_circuit(circuit) |
@@ -636,9 +641,12 @@ def min_weight_simple_path_mixed_strategy( |
636 | 641 | paths_mst = min_weight_simple_paths_mst(graph) |
637 | 642 | start_path = paths_mst.get(n, None) |
638 | 643 | path_greedy = min_weight_simple_path_greedy(graph, n) |
639 | | - if weight_fun(graph, path_greedy) < weight_fun(graph, start_path): |
| 644 | + if path_greedy is not None and weight_fun(graph, path_greedy) < weight_fun(graph, start_path): |
640 | 645 | start_path = path_greedy |
641 | 646 |
|
| 647 | + if start_path is None: |
| 648 | + return None |
| 649 | + |
642 | 650 | best_path = start_path |
643 | 651 |
|
644 | 652 | for _ in range(num_restarts): |
|
0 commit comments