From 5d77695ac6700f36d368b7e62b62ea32690ff133 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Mon, 20 Jun 2022 17:51:25 -0700 Subject: [PATCH 1/5] Remove XmonDevice. --- cirq-google/cirq_google/__init__.py | 1 - cirq-google/cirq_google/devices/__init__.py | 2 - .../cirq_google/devices/xmon_device.py | 223 ------------ .../cirq_google/devices/xmon_device_test.py | 318 ------------------ .../cirq_google/json_test_data/spec.py | 1 - .../optimizers/convert_to_xmon_gates.py | 17 +- 6 files changed, 15 insertions(+), 547 deletions(-) delete mode 100644 cirq-google/cirq_google/devices/xmon_device.py delete mode 100644 cirq-google/cirq_google/devices/xmon_device_test.py diff --git a/cirq-google/cirq_google/__init__.py b/cirq-google/cirq_google/__init__.py index 02d7e28294f..d177c7d6f37 100644 --- a/cirq-google/cirq_google/__init__.py +++ b/cirq-google/cirq_google/__init__.py @@ -62,7 +62,6 @@ SerializableDevice, Sycamore, Sycamore23, - XmonDevice, ) from cirq_google.engine import ( diff --git a/cirq-google/cirq_google/devices/__init__.py b/cirq-google/cirq_google/devices/__init__.py index 9e875c26703..c7a43cb2033 100644 --- a/cirq-google/cirq_google/devices/__init__.py +++ b/cirq-google/cirq_google/devices/__init__.py @@ -22,5 +22,3 @@ from cirq_google.devices.grid_device import GridDevice from cirq_google.devices.serializable_device import SerializableDevice - -from cirq_google.devices.xmon_device import XmonDevice diff --git a/cirq-google/cirq_google/devices/xmon_device.py b/cirq-google/cirq_google/devices/xmon_device.py deleted file mode 100644 index 9f257a81388..00000000000 --- a/cirq-google/cirq_google/devices/xmon_device.py +++ /dev/null @@ -1,223 +0,0 @@ -# Copyright 2018 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Any, cast, Iterable, List, Optional, Set, TYPE_CHECKING - -import cirq -from cirq import _compat - -if TYPE_CHECKING: - import cirq - - -@cirq.value_equality -class _XmonDeviceBase(cirq.Device): - """A device with qubits placed in a grid. Neighboring qubits can interact.""" - - def __init__( - self, - measurement_duration: cirq.DURATION_LIKE, - exp_w_duration: cirq.DURATION_LIKE, - exp_11_duration: cirq.DURATION_LIKE, - qubits: Iterable[cirq.GridQubit], - ) -> None: - """Initializes the description of an xmon device. - - Args: - measurement_duration: The maximum duration of a measurement. - exp_w_duration: The maximum duration of an ExpW operation. - exp_11_duration: The maximum duration of an ExpZ operation. - qubits: Qubits on the device, identified by their x, y location. - """ - self._measurement_duration = cirq.Duration(measurement_duration) - self._exp_w_duration = cirq.Duration(exp_w_duration) - self._exp_z_duration = cirq.Duration(exp_11_duration) - self.qubits = frozenset(qubits) - self._metadata = cirq.GridDeviceMetadata( - [(q0, q1) for q0 in self.qubits for q1 in self.qubits if q0.is_adjacent(q1)], - cirq.Gateset( - cirq.CZPowGate, - cirq.XPowGate, - cirq.YPowGate, - cirq.PhasedXPowGate, - cirq.PhasedXZGate, - cirq.MeasurementGate, - cirq.ZPowGate, - cirq.GlobalPhaseGate, - ), - None, - ) - - @property - def metadata(self) -> cirq.GridDeviceMetadata: - """Return the metadata for this device""" - return self._metadata - - def neighbors_of(self, qubit: cirq.GridQubit): - """Returns the qubits that the given qubit can interact with.""" - possibles = [ - cirq.GridQubit(qubit.row + 1, qubit.col), - cirq.GridQubit(qubit.row - 1, qubit.col), - cirq.GridQubit(qubit.row, qubit.col + 1), - cirq.GridQubit(qubit.row, qubit.col - 1), - ] - return [e for e in possibles if e in self.qubits] - - def duration_of(self, operation): - if isinstance(operation.gate, cirq.CZPowGate): - return self._exp_z_duration - if isinstance(operation.gate, cirq.MeasurementGate): - return self._measurement_duration - if isinstance(operation.gate, (cirq.XPowGate, cirq.YPowGate, cirq.PhasedXPowGate)): - return self._exp_w_duration - if isinstance(operation.gate, cirq.ZPowGate): - # Z gates are performed in the control software. - return cirq.Duration() - raise ValueError(f'Unsupported gate type: {operation!r}') - - @classmethod - def is_supported_gate(cls, gate: cirq.Gate): - """Returns true if the gate is allowed.""" - return isinstance( - gate, - ( - cirq.CZPowGate, - cirq.XPowGate, - cirq.YPowGate, - cirq.PhasedXPowGate, - cirq.PhasedXZGate, - cirq.MeasurementGate, - cirq.ZPowGate, - ), - ) - - def validate_gate(self, gate: cirq.Gate): - """Raises an error if the given gate isn't allowed. - - Raises: - ValueError: Unsupported gate. - """ - if not self.is_supported_gate(gate): - raise ValueError(f'Unsupported gate type: {gate!r}') - - def validate_operation(self, operation: cirq.Operation): - if operation.gate is None: - raise ValueError(f'Unsupported operation: {operation!r}') - - self.validate_gate(operation.gate) - - for q in operation.qubits: - if not isinstance(q, cirq.GridQubit): - raise ValueError(f'Unsupported qubit type: {q!r}') - if q not in self.qubits: - raise ValueError(f'Qubit not on device: {q!r}') - - if len(operation.qubits) == 2 and not isinstance(operation.gate, cirq.MeasurementGate): - p, q = operation.qubits - if not cast(cirq.GridQubit, p).is_adjacent(q): - raise ValueError(f'Non-local interaction: {operation!r}.') - - def _check_if_exp11_operation_interacts_with_any( - self, exp11_op: cirq.GateOperation, others: Iterable[cirq.GateOperation] - ) -> bool: - return any(self._check_if_exp11_operation_interacts(exp11_op, op) for op in others) - - def _check_if_exp11_operation_interacts( - self, exp11_op: cirq.GateOperation, other_op: cirq.GateOperation - ) -> bool: - if isinstance( - other_op.gate, - ( - cirq.XPowGate, - cirq.YPowGate, - cirq.PhasedXPowGate, - cirq.MeasurementGate, - cirq.ZPowGate, - ), - ): - return False - - return any( - cast(cirq.GridQubit, q).is_adjacent(cast(cirq.GridQubit, p)) - for q in exp11_op.qubits - for p in other_op.qubits - ) - - def validate_circuit(self, circuit: cirq.AbstractCircuit): - super().validate_circuit(circuit) - _verify_unique_measurement_keys(circuit.all_operations()) - - def validate_moment(self, moment: cirq.Moment): - super().validate_moment(moment) - for op in moment.operations: - if isinstance(op.gate, cirq.CZPowGate): - for other in moment.operations: - if other is not op and self._check_if_exp11_operation_interacts( - cast(cirq.GateOperation, op), cast(cirq.GateOperation, other) - ): - raise ValueError(f'Adjacent Exp11 operations: {moment}.') - - def at(self, row: int, col: int) -> Optional[cirq.GridQubit]: - """Returns the qubit at the given position, if there is one, else None.""" - q = cirq.GridQubit(row, col) - return q if q in self.qubits else None - - def row(self, row: int) -> List[cirq.GridQubit]: - """Returns the qubits in the given row, in ascending order.""" - return sorted(q for q in self.qubits if q.row == row) - - def col(self, col: int) -> List[cirq.GridQubit]: - """Returns the qubits in the given column, in ascending order.""" - return sorted(q for q in self.qubits if q.col == col) - - def __repr__(self) -> str: - return ( - 'XmonDevice(' - f'measurement_duration={self._measurement_duration!r}, ' - f'exp_w_duration={self._exp_w_duration!r}, ' - f'exp_11_duration={self._exp_z_duration!r} ' - f'qubits={sorted(self.qubits)!r})' - ) - - def __str__(self) -> str: - diagram = cirq.TextDiagramDrawer() - - for q in self.qubits: - diagram.write(q.col, q.row, str(q)) - for q2 in self.neighbors_of(q): - diagram.grid_line(q.col, q.row, q2.col, q2.row) - - return diagram.render(horizontal_spacing=3, vertical_spacing=2, use_unicode_characters=True) - - def _repr_pretty_(self, p: Any, cycle: bool): - p.text("cirq_google.XmonDevice(...)" if cycle else self.__str__()) - - def _value_equality_values_(self) -> Any: - return (self._measurement_duration, self._exp_w_duration, self._exp_z_duration, self.qubits) - - -def _verify_unique_measurement_keys(operations: Iterable[cirq.Operation]): - seen: Set[str] = set() - for op in operations: - if cirq.is_measurement(op): - key = cirq.measurement_key_name(op) - if key in seen: - raise ValueError(f'Measurement key {key} repeated') - seen.add(key) - - -@_compat.deprecated_class(deadline='v0.15', fix='XmonDevice will no longer be supported.') -class XmonDevice(_XmonDeviceBase): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) diff --git a/cirq-google/cirq_google/devices/xmon_device_test.py b/cirq-google/cirq_google/devices/xmon_device_test.py deleted file mode 100644 index 9c2ef8a1137..00000000000 --- a/cirq-google/cirq_google/devices/xmon_device_test.py +++ /dev/null @@ -1,318 +0,0 @@ -# Copyright 2018 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -from unittest import mock -import pytest -import cirq_google as cg -import cirq -import cirq.testing - - -def square_device(width: int, height: int, holes=()) -> cg.XmonDevice: - ns = cirq.Duration(nanos=1) - return cg.XmonDevice( - measurement_duration=ns, - exp_w_duration=2 * ns, - exp_11_duration=3 * ns, - qubits=[ - cirq.GridQubit(row, col) - for col in range(width) - for row in range(height) - if cirq.GridQubit(col, row) not in holes - ], - ) - - -class NotImplementedOperation(cirq.Operation): - def with_qubits(self, *new_qubits) -> 'NotImplementedOperation': - raise NotImplementedError() - - @property - def qubits(self): - raise NotImplementedError() - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_device_metadata(): - d = square_device(3, 3) - assert d.metadata.gateset == cirq.Gateset( - cirq.CZPowGate, - cirq.XPowGate, - cirq.YPowGate, - cirq.PhasedXPowGate, - cirq.PhasedXZGate, - cirq.MeasurementGate, - cirq.ZPowGate, - cirq.GlobalPhaseGate, - ) - assert d.metadata.qubit_pairs == frozenset( - { - frozenset((cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))), - frozenset((cirq.GridQubit(0, 1), cirq.GridQubit(1, 1))), - frozenset((cirq.GridQubit(2, 0), cirq.GridQubit(2, 1))), - frozenset((cirq.GridQubit(0, 0), cirq.GridQubit(1, 0))), - frozenset((cirq.GridQubit(0, 2), cirq.GridQubit(1, 2))), - frozenset((cirq.GridQubit(1, 0), cirq.GridQubit(2, 0))), - frozenset((cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))), - frozenset((cirq.GridQubit(1, 1), cirq.GridQubit(2, 1))), - frozenset((cirq.GridQubit(1, 1), cirq.GridQubit(1, 2))), - frozenset((cirq.GridQubit(0, 1), cirq.GridQubit(0, 2))), - frozenset((cirq.GridQubit(2, 1), cirq.GridQubit(2, 2))), - frozenset((cirq.GridQubit(1, 2), cirq.GridQubit(2, 2))), - } - ) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_init(): - d = square_device(2, 2, holes=[cirq.GridQubit(1, 1)]) - ns = cirq.Duration(nanos=1) - q00 = cirq.GridQubit(0, 0) - q01 = cirq.GridQubit(0, 1) - q10 = cirq.GridQubit(1, 0) - - assert d.qubits == {q00, q01, q10} - assert d.duration_of(cirq.Z(q00)) == 0 * ns - - assert d.duration_of(cirq.measure(q00)) == ns - assert d.duration_of(cirq.measure(q00, q01)) == ns - assert d.duration_of(cirq.X(q00)) == 2 * ns - assert d.duration_of(cirq.CZ(q00, q01)) == 3 * ns - with pytest.raises(ValueError): - _ = d.duration_of(cirq.testing.SingleQubitGate().on(q00)) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_init_timedelta(): - from datetime import timedelta - - timedelta_duration = timedelta(microseconds=1) - d = cg.XmonDevice( - measurement_duration=timedelta_duration, - exp_w_duration=2 * timedelta_duration, - exp_11_duration=3 * timedelta_duration, - qubits=[cirq.GridQubit(row, col) for col in range(2) for row in range(2)], - ) - microsecond = cirq.Duration(nanos=1000) - q00 = cirq.GridQubit(0, 0) - q01 = cirq.GridQubit(0, 1) - q10 = cirq.GridQubit(1, 0) - q11 = cirq.GridQubit(1, 1) - - assert d.qubits == {q00, q01, q10, q11} - - assert d.duration_of(cirq.Z(q00)) == 0 * microsecond - assert d.duration_of(cirq.measure(q00)) == microsecond - assert d.duration_of(cirq.measure(q00, q01)) == microsecond - assert d.duration_of(cirq.X(q00)) == 2 * microsecond - assert d.duration_of(cirq.CZ(q00, q01)) == 3 * microsecond - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_repr(): - d = square_device(2, 2, holes=[]) - - assert repr(d) == ( - "XmonDevice(" - "measurement_duration=cirq.Duration(nanos=1), " - "exp_w_duration=cirq.Duration(nanos=2), " - "exp_11_duration=cirq.Duration(nanos=3) " - "qubits=[cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), " - "cirq.GridQubit(1, 0), " - "cirq.GridQubit(1, 1)])" - ) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_validate_moment(): - - d = square_device(2, 2) - q00 = cirq.GridQubit(0, 0) - q01 = cirq.GridQubit(0, 1) - q10 = cirq.GridQubit(1, 0) - q11 = cirq.GridQubit(1, 1) - m = cirq.Moment([cirq.CZ(q00, q01), cirq.CZ(q10, q11)]) - with pytest.raises(ValueError): - d.validate_moment(m) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_validate_operation_adjacent_qubits(): - d = square_device(3, 3) - - d.validate_operation(cirq.GateOperation(cirq.CZ, (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)))) - - with pytest.raises(ValueError, match='Non-local interaction'): - d.validate_operation( - cirq.GateOperation(cirq.CZ, (cirq.GridQubit(0, 0), cirq.GridQubit(2, 0))) - ) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_validate_measurement_non_adjacent_qubits_ok(): - d = square_device(3, 3) - - d.validate_operation( - cirq.GateOperation( - cirq.MeasurementGate(2, 'a'), (cirq.GridQubit(0, 0), cirq.GridQubit(2, 0)) - ) - ) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_validate_operation_existing_qubits(): - d = square_device(3, 3, holes=[cirq.GridQubit(1, 1)]) - - d.validate_operation(cirq.GateOperation(cirq.CZ, (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)))) - d.validate_operation(cirq.Z(cirq.GridQubit(0, 0))) - - with pytest.raises(ValueError): - d.validate_operation(cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(-1, 0))) - with pytest.raises(ValueError): - d.validate_operation(cirq.Z(cirq.GridQubit(-1, 0))) - with pytest.raises(ValueError): - d.validate_operation(cirq.CZ(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))) - - -class MyGate(cirq.Gate): - def num_qubits(self): - return 1 - - -q = cirq.GridQubit.rect(1, 3) -matrix_gate = cirq.MatrixGate(cirq.testing.random_unitary(2)) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -@pytest.mark.parametrize( - 'op,is_valid', - [ - (cirq.Z(cirq.GridQubit(0, 0)), True), - (cirq.Z(cirq.GridQubit(0, 0)).with_tags('test_tag'), True), - ( - cirq.Z(cirq.GridQubit(0, 0)).with_tags('test_tag').controlled_by(cirq.GridQubit(0, 1)), - True, - ), - ( - cirq.Z(cirq.GridQubit(0, 0)).controlled_by(cirq.GridQubit(0, 1)).with_tags('test_tag'), - True, - ), - (NotImplementedOperation(), False), - (MyGate()(cirq.GridQubit(0, 0)), False), - ], -) -def test_validate_operation_supported_gate_deprecated(op, is_valid): - d = square_device(3, 3) - if is_valid: - d.validate_operation(op) - else: - with pytest.raises(ValueError): - - d.validate_operation(op) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_validate_circuit_repeat_measurement_keys(): - d = square_device(3, 3) - - circuit = cirq.Circuit() - circuit.append( - [cirq.measure(cirq.GridQubit(0, 0), key='a'), cirq.measure(cirq.GridQubit(0, 1), key='a')] - ) - - with pytest.raises(ValueError, match='Measurement key a repeated'): - - d.validate_circuit(circuit) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_xmon_device_eq(): - eq = cirq.testing.EqualsTester() - eq.make_equality_group(lambda: square_device(3, 3)) - eq.make_equality_group(lambda: square_device(3, 3, holes=[cirq.GridQubit(1, 1)])) - eq.make_equality_group( - lambda: cg.XmonDevice( - cirq.Duration(nanos=1), cirq.Duration(nanos=2), cirq.Duration(nanos=3), [] - ) - ) - eq.make_equality_group( - lambda: cg.XmonDevice( - cirq.Duration(nanos=1), cirq.Duration(nanos=1), cirq.Duration(nanos=1), [] - ) - ) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_xmon_device_str(): - assert ( - str(square_device(2, 2)).strip() - == """ -q(0, 0)───q(0, 1) -│ │ -│ │ -q(1, 0)───q(1, 1) - """.strip() - ) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_xmon_device_repr_pretty(): - cirq.testing.assert_repr_pretty( - square_device(2, 2), - """ -q(0, 0)───q(0, 1) -│ │ -│ │ -q(1, 0)───q(1, 1) - """.strip(), - ) - - cirq.testing.assert_repr_pretty(square_device(2, 2), "cirq_google.XmonDevice(...)", cycle=True) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_at(): - d = square_device(3, 3) - assert d.at(-1, -1) is None - assert d.at(0, 0) == cirq.GridQubit(0, 0) - - assert d.at(-1, 1) is None - - assert d.at(0, 1) == cirq.GridQubit(0, 1) - assert d.at(1, 1) == cirq.GridQubit(1, 1) - assert d.at(2, 1) == cirq.GridQubit(2, 1) - assert d.at(3, 1) is None - - assert d.at(1, -1) is None - assert d.at(1, 0) == cirq.GridQubit(1, 0) - assert d.at(1, 1) == cirq.GridQubit(1, 1) - assert d.at(1, 2) == cirq.GridQubit(1, 2) - assert d.at(1, 3) is None - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_row_and_col(): - d = square_device(2, 3) - assert d.col(-1) == [] - assert d.col(0) == [cirq.GridQubit(0, 0), cirq.GridQubit(1, 0), cirq.GridQubit(2, 0)] - assert d.col(1) == [cirq.GridQubit(0, 1), cirq.GridQubit(1, 1), cirq.GridQubit(2, 1)] - assert d.col(2) == [] - assert d.col(5000) == [] - - assert d.row(-1) == [] - assert d.row(0) == [cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)] - assert d.row(1) == [cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)] - assert d.row(2) == [cirq.GridQubit(2, 0), cirq.GridQubit(2, 1)] - assert d.row(3) == [] diff --git a/cirq-google/cirq_google/json_test_data/spec.py b/cirq-google/cirq_google/json_test_data/spec.py index 7ad06aa48a2..49522b62e43 100644 --- a/cirq-google/cirq_google/json_test_data/spec.py +++ b/cirq-google/cirq_google/json_test_data/spec.py @@ -20,7 +20,6 @@ 'SQRT_ISWAP_INV_PARAMETERS', 'ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION', 'WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION', - 'XmonDevice', 'XMON', ], should_not_be_serialized=[ diff --git a/cirq-google/cirq_google/optimizers/convert_to_xmon_gates.py b/cirq-google/cirq_google/optimizers/convert_to_xmon_gates.py index bf1eaa696a0..326f5a4f118 100644 --- a/cirq-google/cirq_google/optimizers/convert_to_xmon_gates.py +++ b/cirq-google/cirq_google/optimizers/convert_to_xmon_gates.py @@ -66,9 +66,22 @@ def _is_native_xmon_op(self, op: cirq.Operation) -> bool: Returns: True if the operation is native to the xmon, false otherwise. """ - from cirq_google.devices import XmonDevice - return op.gate is not None and XmonDevice.is_supported_gate(op.gate) + def _is_native_xmon_op(g): + return isinstance( + g, + ( + cirq.CZPowGate, + cirq.XPowGate, + cirq.YPowGate, + cirq.PhasedXPowGate, + cirq.PhasedXZGate, + cirq.MeasurementGate, + cirq.ZPowGate, + ), + ) + + return op.gate is not None and _is_native_xmon_op(op.gate) def convert(self, op: cirq.Operation) -> List[cirq.Operation]: def on_stuck_raise(bad): From ba707bbb7dc19fc4d3e1868188286f4a43aa72d6 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Mon, 20 Jun 2022 19:55:52 -0700 Subject: [PATCH 2/5] mypy. --- cirq-google/cirq_google/line/placement/place_strategy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cirq-google/cirq_google/line/placement/place_strategy.py b/cirq-google/cirq_google/line/placement/place_strategy.py index 5db0b99395c..79faf0f94c3 100644 --- a/cirq-google/cirq_google/line/placement/place_strategy.py +++ b/cirq-google/cirq_google/line/placement/place_strategy.py @@ -29,7 +29,7 @@ class LinePlacementStrategy(metaclass=abc.ABCMeta): """ @abc.abstractmethod - def place_line(self, device: 'cirq_google.XmonDevice', length: int) -> GridQubitLineTuple: + def place_line(self, device: 'cirq.Device', length: int) -> GridQubitLineTuple: """Runs line sequence search. Args: From 0708d019ff0f9f1924a60c80d699ca83a2909864 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Tue, 21 Jun 2022 01:53:53 -0700 Subject: [PATCH 3/5] more types. --- cirq-google/cirq_google/line/placement/anneal.py | 5 +++-- cirq-google/cirq_google/line/placement/chip.py | 3 ++- cirq-google/cirq_google/line/placement/greedy.py | 5 +++-- cirq-google/cirq_google/line/placement/line.py | 3 ++- cirq-google/cirq_google/line/placement/place_strategy.py | 1 + 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cirq-google/cirq_google/line/placement/anneal.py b/cirq-google/cirq_google/line/placement/anneal.py index 3e72785a158..d42425308e0 100644 --- a/cirq-google/cirq_google/line/placement/anneal.py +++ b/cirq-google/cirq_google/line/placement/anneal.py @@ -22,6 +22,7 @@ from cirq_google.line.placement.sequence import GridQubitLineTuple, LineSequence if TYPE_CHECKING: + import cirq import cirq_google _STATE = Tuple[List[List[cirq.GridQubit]], Set[EDGE]] @@ -30,7 +31,7 @@ class AnnealSequenceSearch: """Simulated annealing search heuristic.""" - def __init__(self, device: 'cirq_google.XmonDevice', seed=None) -> None: + def __init__(self, device: 'cirq.Device', seed=None) -> None: """Greedy sequence search constructor. Args: @@ -350,7 +351,7 @@ def __init__( self.trace_func = trace_func self.seed = seed - def place_line(self, device: 'cirq_google.XmonDevice', length: int) -> GridQubitLineTuple: + def place_line(self, device: 'cirq.Device', length: int) -> GridQubitLineTuple: """Runs line sequence search. Args: diff --git a/cirq-google/cirq_google/line/placement/chip.py b/cirq-google/cirq_google/line/placement/chip.py index 2766a2bd647..3969b77ef95 100644 --- a/cirq-google/cirq_google/line/placement/chip.py +++ b/cirq-google/cirq_google/line/placement/chip.py @@ -17,6 +17,7 @@ import cirq if TYPE_CHECKING: + import cirq import cirq_google @@ -72,7 +73,7 @@ def right_of(qubit: cirq.GridQubit) -> cirq.GridQubit: def chip_as_adjacency_list( - device: 'cirq_google.XmonDevice', + device: 'cirq.Device', ) -> Dict[cirq.GridQubit, List[cirq.GridQubit]]: """Gives adjacency list representation of a chip. diff --git a/cirq-google/cirq_google/line/placement/greedy.py b/cirq-google/cirq_google/line/placement/greedy.py index a841a8f4fcd..84c61bb2dda 100644 --- a/cirq-google/cirq_google/line/placement/greedy.py +++ b/cirq-google/cirq_google/line/placement/greedy.py @@ -24,6 +24,7 @@ if TYPE_CHECKING: from cirq_google.line.placement.sequence import LineSequence + import cirq import cirq_google @@ -34,7 +35,7 @@ class GreedySequenceSearch: method. """ - def __init__(self, device: 'cirq_google.XmonDevice', start: GridQubit) -> None: + def __init__(self, device: 'cirq.Device', start: GridQubit) -> None: """Greedy sequence search constructor. Args: @@ -286,7 +287,7 @@ def __init__(self, algorithm: str = 'best') -> None: """ self.algorithm = algorithm - def place_line(self, device: 'cirq_google.XmonDevice', length: int) -> GridQubitLineTuple: + def place_line(self, device: 'cirq.Device', length: int) -> GridQubitLineTuple: """Runs line sequence search. Args: diff --git a/cirq-google/cirq_google/line/placement/line.py b/cirq-google/cirq_google/line/placement/line.py index 5b9bf4b13e8..29a12603b98 100644 --- a/cirq-google/cirq_google/line/placement/line.py +++ b/cirq-google/cirq_google/line/placement/line.py @@ -18,11 +18,12 @@ from cirq_google.line.placement.sequence import GridQubitLineTuple if TYPE_CHECKING: + import cirq import cirq_google def line_on_device( - device: 'cirq_google.XmonDevice', + device: 'cirq.Device', length: int, method: LinePlacementStrategy = greedy.GreedySequenceSearchStrategy(), ) -> GridQubitLineTuple: diff --git a/cirq-google/cirq_google/line/placement/place_strategy.py b/cirq-google/cirq_google/line/placement/place_strategy.py index 79faf0f94c3..2d69d2d7972 100644 --- a/cirq-google/cirq_google/line/placement/place_strategy.py +++ b/cirq-google/cirq_google/line/placement/place_strategy.py @@ -18,6 +18,7 @@ from cirq_google.line.placement.sequence import GridQubitLineTuple if TYPE_CHECKING: + import cirq import cirq_google From 45c05fe28aff227ad3f0df434d19c2c5796c8c69 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Wed, 22 Jun 2022 00:39:09 -0700 Subject: [PATCH 4/5] more types. --- cirq-google/cirq_google/line/placement/anneal.py | 8 ++++---- .../cirq_google/line/placement/anneal_test.py | 4 ++++ cirq-google/cirq_google/line/placement/chip.py | 8 ++++---- .../cirq_google/line/placement/chip_test.py | 4 ++++ cirq-google/cirq_google/line/placement/greedy.py | 14 +++++++------- .../cirq_google/line/placement/greedy_test.py | 4 ++++ cirq-google/cirq_google/line/placement/line.py | 2 +- .../cirq_google/line/placement/place_strategy.py | 2 +- 8 files changed, 29 insertions(+), 17 deletions(-) diff --git a/cirq-google/cirq_google/line/placement/anneal.py b/cirq-google/cirq_google/line/placement/anneal.py index d42425308e0..d88864c62bd 100644 --- a/cirq-google/cirq_google/line/placement/anneal.py +++ b/cirq-google/cirq_google/line/placement/anneal.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Callable, List, Optional, Tuple, Set, Any, TYPE_CHECKING +from typing import cast, Callable, List, Optional, Tuple, Set, Any, TYPE_CHECKING import numpy as np @@ -31,14 +31,14 @@ class AnnealSequenceSearch: """Simulated annealing search heuristic.""" - def __init__(self, device: 'cirq.Device', seed=None) -> None: + def __init__(self, device: 'cirq_google.GridDevice', seed=None) -> None: """Greedy sequence search constructor. Args: device: Chip description. seed: Optional seed value for random number generator. """ - self._c = device.qubits + self._c = cast(Set[cirq.GridQubit], device.metadata.qubit_set) self._c_adj = chip_as_adjacency_list(device) self._rand = np.random.RandomState(seed) @@ -351,7 +351,7 @@ def __init__( self.trace_func = trace_func self.seed = seed - def place_line(self, device: 'cirq.Device', length: int) -> GridQubitLineTuple: + def place_line(self, device: 'cirq_google.GridDevice', length: int) -> GridQubitLineTuple: """Runs line sequence search. Args: diff --git a/cirq-google/cirq_google/line/placement/anneal_test.py b/cirq-google/cirq_google/line/placement/anneal_test.py index bf2d45c7ed4..af29957e691 100644 --- a/cirq-google/cirq_google/line/placement/anneal_test.py +++ b/cirq-google/cirq_google/line/placement/anneal_test.py @@ -32,6 +32,10 @@ class FakeDevice(cirq.Device): def __init__(self, qubits): self.qubits = qubits + @property + def metadata(self): + return cirq.DeviceMetadata(self.qubits, None) + def _create_device(qubits: Iterable[cirq.GridQubit]): return FakeDevice(qubits) diff --git a/cirq-google/cirq_google/line/placement/chip.py b/cirq-google/cirq_google/line/placement/chip.py index 3969b77ef95..8f3b694900b 100644 --- a/cirq-google/cirq_google/line/placement/chip.py +++ b/cirq-google/cirq_google/line/placement/chip.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, List, Tuple, TYPE_CHECKING +from typing import cast, Dict, List, Set, Tuple, TYPE_CHECKING import cirq @@ -73,7 +73,7 @@ def right_of(qubit: cirq.GridQubit) -> cirq.GridQubit: def chip_as_adjacency_list( - device: 'cirq.Device', + device: 'cirq_google.GridDevice', ) -> Dict[cirq.GridQubit, List[cirq.GridQubit]]: """Gives adjacency list representation of a chip. @@ -87,9 +87,9 @@ def chip_as_adjacency_list( Map from nodes to list of qubits which represent all the neighbours of given qubit. """ - c_set = set(device.qubits) + c_set = cast(Set[cirq.GridQubit], device.metadata.qubit_set) c_adj: Dict[cirq.GridQubit, List[cirq.GridQubit]] = {} - for n in device.qubits: + for n in c_set: c_adj[n] = [] for m in [above(n), left_of(n), below(n), right_of(n)]: if m in c_set: diff --git a/cirq-google/cirq_google/line/placement/chip_test.py b/cirq-google/cirq_google/line/placement/chip_test.py index af5fc32cc02..a314efd037c 100644 --- a/cirq-google/cirq_google/line/placement/chip_test.py +++ b/cirq-google/cirq_google/line/placement/chip_test.py @@ -46,6 +46,10 @@ class FakeDevice(cirq.Device): def __init__(self, qubits): self.qubits = qubits + @property + def metadata(self): + return cirq.DeviceMetadata(self.qubits, None) + def _create_device(qubits: Iterable[cirq.GridQubit]): return FakeDevice(qubits) diff --git a/cirq-google/cirq_google/line/placement/greedy.py b/cirq-google/cirq_google/line/placement/greedy.py index 84c61bb2dda..7a8b41a9c81 100644 --- a/cirq-google/cirq_google/line/placement/greedy.py +++ b/cirq-google/cirq_google/line/placement/greedy.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, List, Optional, Set, TYPE_CHECKING +from typing import cast, Dict, List, Optional, Set, TYPE_CHECKING import abc import collections @@ -35,7 +35,7 @@ class GreedySequenceSearch: method. """ - def __init__(self, device: 'cirq.Device', start: GridQubit) -> None: + def __init__(self, device: 'cirq_google.GridDevice', start: GridQubit) -> None: """Greedy sequence search constructor. Args: @@ -45,10 +45,10 @@ def __init__(self, device: 'cirq.Device', start: GridQubit) -> None: Raises: ValueError: When start qubit is not part of a chip. """ - if start not in device.qubits: + if start not in device.metadata.qubit_set: raise ValueError('Starting qubit must be a qubit on the chip') - self._c = device.qubits + self._c = device.metadata.qubit_set self._c_adj = chip_as_adjacency_list(device) self._start = start self._sequence: Optional[List[GridQubit]] = None @@ -287,7 +287,7 @@ def __init__(self, algorithm: str = 'best') -> None: """ self.algorithm = algorithm - def place_line(self, device: 'cirq.Device', length: int) -> GridQubitLineTuple: + def place_line(self, device: 'cirq_google.GridDevice', length: int) -> GridQubitLineTuple: """Runs line sequence search. Args: @@ -302,10 +302,10 @@ def place_line(self, device: 'cirq.Device', length: int) -> GridQubitLineTuple: recognized. """ - if not device.qubits: + if not device.metadata.qubit_set: return GridQubitLineTuple() - start: GridQubit = min(device.qubits) + start: GridQubit = cast(GridQubit, min(device.metadata.qubit_set)) sequences: List[LineSequence] = [] greedy_search: Dict[str, List[GreedySequenceSearch]] = { 'minimal_connectivity': [_PickFewestNeighbors(device, start)], diff --git a/cirq-google/cirq_google/line/placement/greedy_test.py b/cirq-google/cirq_google/line/placement/greedy_test.py index 1d9ac8d4106..e41d5d2b182 100644 --- a/cirq-google/cirq_google/line/placement/greedy_test.py +++ b/cirq-google/cirq_google/line/placement/greedy_test.py @@ -25,6 +25,10 @@ class FakeDevice(cirq.Device): def __init__(self, qubits): self.qubits = qubits + @property + def metadata(self): + return cirq.DeviceMetadata(self.qubits, None) + def _create_device(qubits: Iterable[cirq.GridQubit]): return FakeDevice(qubits) diff --git a/cirq-google/cirq_google/line/placement/line.py b/cirq-google/cirq_google/line/placement/line.py index 29a12603b98..3bca784c389 100644 --- a/cirq-google/cirq_google/line/placement/line.py +++ b/cirq-google/cirq_google/line/placement/line.py @@ -23,7 +23,7 @@ def line_on_device( - device: 'cirq.Device', + device: 'cirq_google.GridDevice', length: int, method: LinePlacementStrategy = greedy.GreedySequenceSearchStrategy(), ) -> GridQubitLineTuple: diff --git a/cirq-google/cirq_google/line/placement/place_strategy.py b/cirq-google/cirq_google/line/placement/place_strategy.py index 2d69d2d7972..5009329c124 100644 --- a/cirq-google/cirq_google/line/placement/place_strategy.py +++ b/cirq-google/cirq_google/line/placement/place_strategy.py @@ -30,7 +30,7 @@ class LinePlacementStrategy(metaclass=abc.ABCMeta): """ @abc.abstractmethod - def place_line(self, device: 'cirq.Device', length: int) -> GridQubitLineTuple: + def place_line(self, device: 'cirq_google.GridDevice', length: int) -> GridQubitLineTuple: """Runs line sequence search. Args: From 6c29fd7b1d5cd39d77ed96791a3c5c8a8324aae9 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Wed, 22 Jun 2022 14:50:34 -0700 Subject: [PATCH 5/5] Neeley feedback. --- cirq-google/cirq_google/line/placement/anneal.py | 1 - cirq-google/cirq_google/line/placement/chip.py | 1 - cirq-google/cirq_google/line/placement/greedy.py | 1 - cirq-google/cirq_google/line/placement/line.py | 1 - cirq-google/cirq_google/line/placement/place_strategy.py | 1 - 5 files changed, 5 deletions(-) diff --git a/cirq-google/cirq_google/line/placement/anneal.py b/cirq-google/cirq_google/line/placement/anneal.py index d88864c62bd..75b5ceefa6c 100644 --- a/cirq-google/cirq_google/line/placement/anneal.py +++ b/cirq-google/cirq_google/line/placement/anneal.py @@ -22,7 +22,6 @@ from cirq_google.line.placement.sequence import GridQubitLineTuple, LineSequence if TYPE_CHECKING: - import cirq import cirq_google _STATE = Tuple[List[List[cirq.GridQubit]], Set[EDGE]] diff --git a/cirq-google/cirq_google/line/placement/chip.py b/cirq-google/cirq_google/line/placement/chip.py index 8f3b694900b..8bf18d911d6 100644 --- a/cirq-google/cirq_google/line/placement/chip.py +++ b/cirq-google/cirq_google/line/placement/chip.py @@ -17,7 +17,6 @@ import cirq if TYPE_CHECKING: - import cirq import cirq_google diff --git a/cirq-google/cirq_google/line/placement/greedy.py b/cirq-google/cirq_google/line/placement/greedy.py index 7a8b41a9c81..cbd96df5c2c 100644 --- a/cirq-google/cirq_google/line/placement/greedy.py +++ b/cirq-google/cirq_google/line/placement/greedy.py @@ -24,7 +24,6 @@ if TYPE_CHECKING: from cirq_google.line.placement.sequence import LineSequence - import cirq import cirq_google diff --git a/cirq-google/cirq_google/line/placement/line.py b/cirq-google/cirq_google/line/placement/line.py index 3bca784c389..af6bce48ada 100644 --- a/cirq-google/cirq_google/line/placement/line.py +++ b/cirq-google/cirq_google/line/placement/line.py @@ -18,7 +18,6 @@ from cirq_google.line.placement.sequence import GridQubitLineTuple if TYPE_CHECKING: - import cirq import cirq_google diff --git a/cirq-google/cirq_google/line/placement/place_strategy.py b/cirq-google/cirq_google/line/placement/place_strategy.py index 5009329c124..a1b2ebe64f2 100644 --- a/cirq-google/cirq_google/line/placement/place_strategy.py +++ b/cirq-google/cirq_google/line/placement/place_strategy.py @@ -18,7 +18,6 @@ from cirq_google.line.placement.sequence import GridQubitLineTuple if TYPE_CHECKING: - import cirq import cirq_google