diff --git a/cirq/contrib/routing/greedy.py b/cirq/contrib/routing/greedy.py index ff0447cbad4..5eed8a928b2 100644 --- a/cirq/contrib/routing/greedy.py +++ b/cirq/contrib/routing/greedy.py @@ -301,7 +301,12 @@ def apply_next_swaps(self, require_frontier_adjacency: bool = False): ] if len(candidate_swap_sets) == 1: self.apply_swap(*candidate_swap_sets[0]) - return + if list( + self.remaining_dag.findall_nodes_until_blocked( + self.acts_on_nonadjacent_qubits)): + return + else: + break self.apply_next_swaps(True) diff --git a/cirq/contrib/routing/greedy_test.py b/cirq/contrib/routing/greedy_test.py index b66d98d93d3..1776bcd76f2 100644 --- a/cirq/contrib/routing/greedy_test.py +++ b/cirq/contrib/routing/greedy_test.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from multiprocessing import Process + import pytest import cirq @@ -20,6 +22,7 @@ def test_bad_args(): + """Test zero valued arguments in greedy router.""" circuit = cirq.testing.random_circuit(4, 2, 0.5, random_state=5) device_graph = ccr.get_grid_device_graph(3, 2) with pytest.raises(ValueError): @@ -27,3 +30,39 @@ def test_bad_args(): with pytest.raises(ValueError): route_circuit_greedily(circuit, device_graph, max_num_empty_steps=0) + + +def create_circuit_and_device(): + """Construct a small circuit and a device with line connectivity + to test the greedy router. This instance hangs router in Cirq 8.2. + """ + num_qubits = 6 + gate_domain = {cirq.ops.CNOT: 2} + circuit = cirq.testing.random_circuit(num_qubits, + 15, + 0.5, + gate_domain, + random_state=37) + device_graph = ccr.get_linear_device_graph(num_qubits) + return circuit, device_graph + + +def create_hanging_routing_instance(circuit, device_graph): + """Create a test problem instance.""" + route_circuit_greedily(circuit, + device_graph, + max_search_radius=2, + random_state=1) + + +def test_router_hanging(): + """Run a separate process and check if greedy router hits timeout (5s).""" + circuit, device_graph = create_circuit_and_device() + process = Process(target=create_hanging_routing_instance, + args=[circuit, device_graph]) + process.start() + process.join(timeout=5) + try: + assert not process.is_alive(), "Greedy router timeout" + finally: + process.terminate()