diff --git a/cirq-google/cirq_google/devices/xmon_device.py b/cirq-google/cirq_google/devices/xmon_device.py index 4a7df5bfb77..87187789fe9 100644 --- a/cirq-google/cirq_google/devices/xmon_device.py +++ b/cirq-google/cirq_google/devices/xmon_device.py @@ -16,7 +16,6 @@ import cirq from cirq import _compat -from cirq_google.optimizers import convert_to_xmon_gates if TYPE_CHECKING: import cirq @@ -52,6 +51,7 @@ def __init__( cirq.XPowGate, cirq.YPowGate, cirq.PhasedXPowGate, + cirq.PhasedXZGate, cirq.MeasurementGate, cirq.ZPowGate, ), @@ -72,10 +72,17 @@ def qubit_set(self) -> FrozenSet[cirq.GridQubit]: @_compat.deprecated( deadline='v0.15', - fix='XmonDevice.decompose_operation is deperecated. Please use ConvertToXmonGates().', + fix='XmonDevice.decompose_operation is deprecated. ' + 'Please use cirq.optimize_for_target_gateset() and cirq.CZTargetGateset.', ) def decompose_operation(self, operation: cirq.Operation) -> cirq.OP_TREE: - return convert_to_xmon_gates.ConvertToXmonGates().convert(operation) + if operation.gate is not None and self.is_supported_gate(operation.gate): + return operation + return [ + cirq.optimize_for_target_gateset( + cirq.Circuit(operation), gateset=cirq.CZTargetGateset(allow_partial_czs=True) + ).all_operations() + ] def neighbors_of(self, qubit: cirq.GridQubit): """Returns the qubits that the given qubit can interact with.""" @@ -109,6 +116,7 @@ def is_supported_gate(cls, gate: cirq.Gate): cirq.XPowGate, cirq.YPowGate, cirq.PhasedXPowGate, + cirq.PhasedXZGate, cirq.MeasurementGate, cirq.ZPowGate, ), diff --git a/cirq-google/cirq_google/devices/xmon_device_test.py b/cirq-google/cirq_google/devices/xmon_device_test.py index b7110519434..21a656a9152 100644 --- a/cirq-google/cirq_google/devices/xmon_device_test.py +++ b/cirq-google/cirq_google/devices/xmon_device_test.py @@ -52,6 +52,7 @@ def test_device_metadata(): cirq.XPowGate, cirq.YPowGate, cirq.PhasedXPowGate, + cirq.PhasedXZGate, cirq.MeasurementGate, cirq.ZPowGate, ) 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 881be82e3dc..53d7113ef00 100644 --- a/cirq-google/cirq_google/optimizers/convert_to_xmon_gates.py +++ b/cirq-google/cirq_google/optimizers/convert_to_xmon_gates.py @@ -16,6 +16,10 @@ import cirq +@cirq._compat.deprecated_class( + deadline='v1.0', + fix='Use cirq.optimize_for_target_gateset and cirq.CZTargetGateset instead.', +) class ConvertToXmonGates(cirq.PointOptimizer): """Attempts to convert strange gates into XmonGates. diff --git a/cirq-google/cirq_google/optimizers/convert_to_xmon_gates_test.py b/cirq-google/cirq_google/optimizers/convert_to_xmon_gates_test.py index 93972c340cf..9a6477ed430 100644 --- a/cirq-google/cirq_google/optimizers/convert_to_xmon_gates_test.py +++ b/cirq-google/cirq_google/optimizers/convert_to_xmon_gates_test.py @@ -40,8 +40,10 @@ class NonNativeGate(cirq.SingleQubitGate): def test_avoids_infinite_cycle_when_matrix_available(): q = cirq.GridQubit(0, 0) c = cirq.Circuit(OtherX().on(q), OtherOtherX().on(q)) - cirq_google.ConvertToXmonGates().optimize_circuit(c) + with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): + cirq_google.ConvertToXmonGates().optimize_circuit(c) cirq.testing.assert_has_diagram(c, '(0, 0): ───PhX(1)───PhX(1)───') + cirq.protocols.decompose(c) @@ -52,7 +54,10 @@ def test_avoids_infinite_cycle_when_matrix_available(): def test_bad_operation(): c = cirq.Circuit(NonNativeGate().on(q[0])) with pytest.raises(TypeError): - cirq_google.ConvertToXmonGates().optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0' + ): + cirq_google.ConvertToXmonGates().optimize_circuit(c) @pytest.mark.parametrize( @@ -68,4 +73,5 @@ def test_bad_operation(): ) def test_supported_operation(op, is_valid): c = cirq.Circuit(op) - assert (cirq_google.ConvertToXmonGates().optimization_at(c, 0, op) is not None) == is_valid + with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): + assert (cirq_google.ConvertToXmonGates().optimization_at(c, 0, op) is not None) == is_valid diff --git a/cirq-google/cirq_google/optimizers/optimize_for_sycamore.py b/cirq-google/cirq_google/optimizers/optimize_for_sycamore.py index 41fd81cf5ba..cff37ae0843 100644 --- a/cirq-google/cirq_google/optimizers/optimize_for_sycamore.py +++ b/cirq-google/cirq_google/optimizers/optimize_for_sycamore.py @@ -13,49 +13,18 @@ # limitations under the License. """A combination of several optimizations targeting XmonDevice.""" from functools import lru_cache -from typing import Callable, cast, List, Optional, TYPE_CHECKING +from typing import Callable, cast, Optional, TYPE_CHECKING import numpy as np import cirq from cirq_google import ops as cg_ops -from cirq_google.optimizers import ( - convert_to_xmon_gates, -) from cirq_google.transformers.target_gatesets import sycamore_gateset if TYPE_CHECKING: import cirq_google -def _get_xmon_optimizers( - tolerance: float, tabulation: Optional[cirq.TwoQubitGateTabulation] -) -> List[Callable[[cirq.Circuit], None]]: - if tabulation is not None: - # coverage: ignore - raise ValueError("Gate tabulation not supported for xmon") - - return [ - convert_to_xmon_gates.ConvertToXmonGates().optimize_circuit, - ] - - -def _get_xmon_optimizers_part_cz( - tolerance: float, tabulation: Optional[cirq.TwoQubitGateTabulation] -) -> List[Callable[[cirq.Circuit], None]]: - if tabulation is not None: - # coverage: ignore - raise ValueError("Gate tabulation not supported for xmon") - return [ - convert_to_xmon_gates.ConvertToXmonGates().optimize_circuit, - ] - - -_OPTIMIZER_TYPES = { - 'xmon': _get_xmon_optimizers, - 'xmon_partial_cz': _get_xmon_optimizers_part_cz, -} - _TARGET_GATESETS = { 'sqrt_iswap': lambda atol, _: cirq.SqrtIswapTargetGateset(atol=atol), 'sycamore': lambda atol, tabulation: sycamore_gateset.SycamoreTargetGateset( @@ -122,10 +91,10 @@ def optimized_for_sycamore( ValueError: If the `optimizer_type` is not a supported type. """ copy = circuit.copy() - if optimizer_type not in _OPTIMIZER_TYPES and optimizer_type not in _TARGET_GATESETS: + if optimizer_type not in _TARGET_GATESETS: raise ValueError( f'{optimizer_type} is not an allowed type. Allowed ' - f'types are: {_OPTIMIZER_TYPES.keys()}' + f'types are: {_TARGET_GATESETS.keys()}' ) tabulation: Optional[cirq.TwoQubitGateTabulation] = None @@ -137,10 +106,6 @@ def optimized_for_sycamore( circuit, gateset=_TARGET_GATESETS[optimizer_type](tolerance, tabulation), ) - if optimizer_type in _OPTIMIZER_TYPES: - opts = _OPTIMIZER_TYPES[optimizer_type](tolerance=tolerance, tabulation=tabulation) - for optimizer in opts: - optimizer(copy) copy = cirq.merge_single_qubit_gates_to_phxz(copy, atol=tolerance) copy = cirq.eject_phased_paulis(copy, atol=tolerance) copy = cirq.eject_z(copy, atol=tolerance)