diff --git a/cirq-core/cirq/circuits/circuit.py b/cirq-core/cirq/circuits/circuit.py index a155ba261f2..9f4251ebdb7 100644 --- a/cirq-core/cirq/circuits/circuit.py +++ b/cirq-core/cirq/circuits/circuit.py @@ -24,7 +24,6 @@ import html import itertools import math -import re from collections import defaultdict from typing import ( AbstractSet, @@ -91,8 +90,6 @@ def foo(circuit: CIRCUIT_TYPE) -> CIRCUIT_TYPE: _INT_TYPE = Union[int, np.integer] -_DEVICE_DEP_MESSAGE = 'Attaching devices to circuits will no longer be supported.' - class Alignment(enum.Enum): # Stop when left ends are lined up. @@ -109,8 +106,7 @@ def __repr__(self) -> str: class AbstractCircuit(abc.ABC): """The base class for Circuit-like objects. - A circuit-like object must have a list of moments (which can be empty) and - a device (which may be `devices.UNCONSTRAINED_DEVICE`). + A circuit-like object must have a list of moments (which can be empty). These methods return information about the circuit, and can be called on either Circuit or FrozenCircuit objects: @@ -146,14 +142,6 @@ class AbstractCircuit(abc.ABC): def moments(self) -> Sequence['cirq.Moment']: pass - @property - @abc.abstractmethod - def device(self) -> 'cirq.Device': - pass - - # This is going away once device deprecation is finished. - _device = None # type: devices.Device - def freeze(self) -> 'cirq.FrozenCircuit': """Creates a FrozenCircuit from this circuit. @@ -164,9 +152,7 @@ def freeze(self) -> 'cirq.FrozenCircuit': if isinstance(self, FrozenCircuit): return self - if self._device == cirq.UNCONSTRAINED_DEVICE: - return FrozenCircuit(self, strategy=InsertStrategy.EARLIEST) - return FrozenCircuit(self, strategy=InsertStrategy.EARLIEST, device=self._device) + return FrozenCircuit(self, strategy=InsertStrategy.EARLIEST) def unfreeze(self, copy: bool = True) -> 'cirq.Circuit': """Creates a Circuit from this circuit. @@ -177,9 +163,7 @@ def unfreeze(self, copy: bool = True) -> 'cirq.Circuit': if isinstance(self, Circuit): return Circuit.copy(self) if copy else self - if self._device == cirq.UNCONSTRAINED_DEVICE: - return Circuit(self, strategy=InsertStrategy.EARLIEST) - return Circuit(self, strategy=InsertStrategy.EARLIEST, device=self._device) + return Circuit(self, strategy=InsertStrategy.EARLIEST) def __bool__(self): return bool(self.moments) @@ -187,16 +171,13 @@ def __bool__(self): def __eq__(self, other): if not isinstance(other, AbstractCircuit): return NotImplemented - return tuple(self.moments) == tuple(other.moments) and self._device == other._device + return tuple(self.moments) == tuple(other.moments) def _approx_eq_(self, other: Any, atol: Union[int, float]) -> bool: """See `cirq.protocols.SupportsApproximateEquality`.""" if not isinstance(other, AbstractCircuit): return NotImplemented - return ( - cirq.protocols.approx_eq(tuple(self.moments), tuple(other.moments), atol=atol) - and self._device == other._device - ) + return cirq.protocols.approx_eq(tuple(self.moments), tuple(other.moments), atol=atol) def __ne__(self, other) -> bool: return not self == other @@ -271,8 +252,6 @@ def __repr__(self) -> str: args = [] if self.moments: args.append(_list_repr_with_indented_item_lines(self.moments)) - if self._device != devices.UNCONSTRAINED_DEVICE: - args.append(f'device={self.device!r}') return f'cirq.{cls_name}({", ".join(args)})' def _repr_pretty_(self, p: Any, cycle: bool) -> None: @@ -1353,16 +1332,12 @@ def save_qasm( self._to_qasm_output(header, precision, qubit_order).save(file_path) def _json_dict_(self): - ret = protocols.obj_to_dict_helper(self, ['moments', '_device']) - ret['device'] = ret['_device'] - del ret['_device'] + ret = protocols.obj_to_dict_helper(self, ['moments']) return ret @classmethod - def _from_json_dict_(cls, moments, device, **kwargs): - if device == cirq.UNCONSTRAINED_DEVICE: - return cls(moments, strategy=InsertStrategy.EARLIEST) - return cls(moments, device=device, strategy=InsertStrategy.EARLIEST) + def _from_json_dict_(cls, moments, **kwargs): + return cls(moments, strategy=InsertStrategy.EARLIEST) def zip( *circuits: 'cirq.AbstractCircuit', align: Union['cirq.Alignment', str] = Alignment.LEFT @@ -1713,17 +1688,10 @@ class Circuit(AbstractCircuit): independent 'factors' of the original Circuit. """ - @_compat.deprecated_parameter( - deadline='v0.15', - fix=_DEVICE_DEP_MESSAGE, - parameter_desc='device', - match=lambda args, kwargs: 'device' in kwargs, - ) def __init__( self, *contents: 'cirq.OP_TREE', strategy: 'cirq.InsertStrategy' = InsertStrategy.EARLIEST, - device: 'cirq.Device' = devices.UNCONSTRAINED_DEVICE, ) -> None: """Initializes a circuit. @@ -1737,47 +1705,21 @@ def __init__( from `contents`, this determines how the operations are packed together. This option does not affect later insertions into the circuit. - device: Hardware that the circuit should be able to run on. """ self._moments: List['cirq.Moment'] = [] - self._device = device with _compat.block_overlapping_deprecation('.*'): self.append(contents, strategy=strategy) - @property # type: ignore - @_compat.deprecated( - deadline='v0.15', - fix=_DEVICE_DEP_MESSAGE, - ) - def device(self) -> devices.Device: - return self._device - - @device.setter # type: ignore - @_compat.deprecated( - deadline='v0.15', - fix=_DEVICE_DEP_MESSAGE, - ) - def device(self, new_device: 'cirq.Device') -> None: - new_device.validate_circuit(self) - self._device = new_device - def __copy__(self) -> 'cirq.Circuit': return self.copy() def copy(self) -> 'Circuit': - if self._device == cirq.UNCONSTRAINED_DEVICE: - copied_circuit = Circuit() - else: - copied_circuit = Circuit(device=self._device) + copied_circuit = Circuit() copied_circuit._moments = self._moments[:] return copied_circuit def _with_sliced_moments(self, moments: Iterable['cirq.Moment']) -> 'Circuit': - if self._device == cirq.UNCONSTRAINED_DEVICE: - new_circuit = Circuit() - else: - new_circuit = Circuit(device=self._device) - + new_circuit = Circuit() new_circuit._moments = list(moments) return new_circuit @@ -1794,14 +1736,11 @@ def __setitem__(self, key, value): if isinstance(key, int): if not isinstance(value, Moment): raise TypeError('Can only assign Moments into Circuits.') - self._device.validate_moment(value) if isinstance(key, slice): value = list(value) if any(not isinstance(v, Moment) for v in value): raise TypeError('Can only assign Moments into Circuits.') - for moment in value: - self._device.validate_moment(moment) self._moments[key] = value @@ -1815,13 +1754,7 @@ def __iadd__(self, other): return self def __add__(self, other): - if isinstance(other, type(self)): - if ( - devices.UNCONSTRAINED_DEVICE not in [self._device, other._device] - and self._device != other._device - ): - raise ValueError("Can't add circuits with incompatible devices.") - elif not isinstance(other, (ops.Operation, Iterable)): + if not isinstance(other, (ops.Operation, Iterable)): return NotImplemented result = self.copy() @@ -1834,7 +1767,6 @@ def __radd__(self, other): # Auto wrap OP_TREE inputs into a circuit. result = self.copy() result._moments[:0] = Circuit(other)._moments - result._device.validate_circuit(result) return result # Needed for numpy to handle multiplication by np.int64 correctly. @@ -1849,9 +1781,7 @@ def __imul__(self, repetitions: _INT_TYPE): def __mul__(self, repetitions: _INT_TYPE): if not isinstance(repetitions, (int, np.integer)): return NotImplemented - if self._device == cirq.UNCONSTRAINED_DEVICE: - return Circuit(self._moments * int(repetitions)) - return Circuit(self._moments * int(repetitions), device=self._device) + return Circuit(self._moments * int(repetitions)) def __rmul__(self, repetitions: _INT_TYPE): if not isinstance(repetitions, (int, np.integer)): @@ -1877,42 +1807,10 @@ def __pow__(self, exponent: int) -> 'cirq.Circuit': return NotImplemented inv_moments.append(inv_moment) - if self._device == cirq.UNCONSTRAINED_DEVICE: - return cirq.Circuit(inv_moments) - return cirq.Circuit(inv_moments, device=self._device) + return cirq.Circuit(inv_moments) __hash__ = None # type: ignore - @_compat.deprecated( - deadline='v0.15', - fix=_DEVICE_DEP_MESSAGE, - ) - def with_device( - self, - new_device: 'cirq.Device', - qubit_mapping: Callable[['cirq.Qid'], 'cirq.Qid'] = lambda e: e, - ) -> 'cirq.Circuit': - """Maps the current circuit onto a new device, and validates. - - Args: - new_device: The new device that the circuit should be on. - qubit_mapping: How to translate qubits from the old device into - qubits on the new device. - - Returns: - The translated circuit. - """ - with _compat.block_overlapping_deprecation(re.escape(_DEVICE_DEP_MESSAGE)): - return Circuit( - [ - Moment( - operation.transform_qubits(qubit_mapping) for operation in moment.operations - ) - for moment in self._moments - ], - device=new_device, - ) - def tetris_concat( *circuits: 'cirq.AbstractCircuit', align: Union['cirq.Alignment', str] = Alignment.LEFT ) -> 'cirq.Circuit': @@ -1927,30 +1825,19 @@ def zip( zip.__doc__ = AbstractCircuit.zip.__doc__ - @_compat.deprecated_parameter( - deadline='v0.15', - fix=_DEVICE_DEP_MESSAGE, - parameter_desc='new_device', - match=lambda args, kwargs: 'new_device' in kwargs, - ) def transform_qubits( self, qubit_map: Union[Dict['cirq.Qid', 'cirq.Qid'], Callable[['cirq.Qid'], 'cirq.Qid']], - *, - new_device: 'cirq.Device' = None, ) -> 'cirq.Circuit': """Returns the same circuit, but with different qubits. Args: qubit_map: A function or a dict mapping each current qubit into a desired new qubit. - new_device: The device to use for the new circuit, if different. - If this is not set, the new device defaults to the current - device. Returns: The receiving circuit but with qubits transformed by the given - function, and with an updated device (if specified). + function. Raises: TypeError: If `qubit_function` is not a function or a dict. @@ -1967,11 +1854,7 @@ def transform_qubits( for moment in self._moments ] - if new_device is None and self._device == devices.UNCONSTRAINED_DEVICE: - return Circuit(op_list) - - with _compat.block_overlapping_deprecation(re.escape(_DEVICE_DEP_MESSAGE)): - return Circuit(op_list, device=self._device if new_device is None else new_device) + return Circuit(op_list) def earliest_available_moment( self, op: 'cirq.Operation', *, end_moment_index: Optional[int] = None @@ -2062,10 +1945,7 @@ def _can_add_op_at(self, moment_index: int, operation: 'cirq.Operation') -> bool if not 0 <= moment_index < len(self._moments): return True - if self._device == cirq.UNCONSTRAINED_DEVICE: - return not self._moments[moment_index].operates_on(operation.qubits) - - return self._device.can_add_operation_into_moment(operation, self._moments[moment_index]) + return not self._moments[moment_index].operates_on(operation.qubits) def insert( self, @@ -2091,39 +1971,14 @@ def insert( Raises: ValueError: Bad insertion strategy. """ - if self._device == devices.UNCONSTRAINED_DEVICE: - moments_and_operations = list( - ops.flatten_to_ops_or_moments( - ops.transform_op_tree( - moment_or_operation_tree, - preserve_moments=True, - ), - ) - ) - else: - _compat._warn_or_error( - 'circuit.insert behavior relies on circuit.device.\n' - 'The ability to construct a circuit with a device\n' - 'will be removed in cirq v0.15. please update this use of\n' - 'insert.' + moments_and_operations = list( + ops.flatten_to_ops_or_moments( + ops.transform_op_tree( + moment_or_operation_tree, + preserve_moments=True, + ), ) - with _compat.block_overlapping_deprecation('decompose'): - moments_and_operations = list( - ops.flatten_to_ops_or_moments( - ops.transform_op_tree( - moment_or_operation_tree, - self._device.decompose_operation, - preserve_moments=True, - ), - ) - ) - - for moment_or_op in moments_and_operations: - if isinstance(moment_or_op, Moment): - self._device.validate_moment(cast(Moment, moment_or_op)) - else: - self._device.validate_operation(cast(ops.Operation, moment_or_op)) - + ) # limit index to 0..len(self._moments), also deal with indices smaller 0 k = max(min(index if index >= 0 else len(self._moments) + index, len(self._moments)), 0) for moment_or_op in moments_and_operations: @@ -2136,7 +1991,6 @@ def insert( while p >= len(self._moments): self._moments.append(Moment()) self._moments[p] = self._moments[p].with_operation(op) - self._device.validate_moment(self._moments[p]) k = max(k, p + 1) if strategy is InsertStrategy.NEW_THEN_INLINE: strategy = InsertStrategy.INLINE @@ -2164,34 +2018,23 @@ def insert_into_range(self, operations: 'cirq.OP_TREE', start: int, end: int) -> raise IndexError(f'Bad insert indices: [{start}, {end})') flat_ops = list(ops.flatten_to_ops(operations)) - for op in flat_ops: - self._device.validate_operation(op) i = start op_index = 0 - cannot_add_lambda = lambda a, b: b.operates_on(a.qubits) - if self._device != cirq.UNCONSTRAINED_DEVICE: - _compat._warn_or_error( - "In Cirq v0.15 device specific validation in " - "insert_into_range will no longer enforced." - ) - cannot_add_lambda = lambda a, b: not self._device.can_add_operation_into_moment(a, b) - - with _compat.block_overlapping_deprecation('(can_add_operation_into_moment|insert)'): - while op_index < len(flat_ops): - op = flat_ops[op_index] - while i < end and cannot_add_lambda(op, self._moments[i]): - i += 1 - if i >= end: - break + while op_index < len(flat_ops): + op = flat_ops[op_index] + while i < end and self._moments[i].operates_on(op.qubits): + i += 1 + if i >= end: + break - self._moments[i] = self._moments[i].with_operation(op) - op_index += 1 + self._moments[i] = self._moments[i].with_operation(op) + op_index += 1 - if op_index >= len(flat_ops): - return end + if op_index >= len(flat_ops): + return end - return self.insert(end, flat_ops[op_index:]) + return self.insert(end, flat_ops[op_index:]) def _push_frontier( self, @@ -2322,7 +2165,6 @@ def batch_remove(self, removals: Iterable[Tuple[int, 'cirq.Operation']]) -> None copy._moments[i] = Moment( old_op for old_op in copy._moments[i].operations if op != old_op ) - self._device.validate_circuit(copy) self._moments = copy._moments def batch_replace( @@ -2347,7 +2189,6 @@ def batch_replace( copy._moments[i] = Moment( old_op if old_op != op else new_op for old_op in copy._moments[i].operations ) - self._device.validate_circuit(copy) self._moments = copy._moments def batch_insert_into(self, insert_intos: Iterable[Tuple[int, 'cirq.OP_TREE']]) -> None: @@ -2369,7 +2210,6 @@ def batch_insert_into(self, insert_intos: Iterable[Tuple[int, 'cirq.OP_TREE']]) copy = self.copy() for i, insertions in insert_intos: copy._moments[i] = copy._moments[i].with_operations(insertions) - self._device.validate_circuit(copy) self._moments = copy._moments def batch_insert(self, insertions: Iterable[Tuple[int, 'cirq.OP_TREE']]) -> None: @@ -2444,10 +2284,8 @@ def _resolve_parameters_( resolved_operations = _resolve_operations(moment.operations, resolver, recursive) new_moment = Moment(resolved_operations) resolved_moments.append(new_moment) - if self._device == devices.UNCONSTRAINED_DEVICE: - return Circuit(resolved_moments) - with _compat.block_overlapping_deprecation(re.escape(_DEVICE_DEP_MESSAGE)): - return Circuit(resolved_moments, device=self._device) + + return Circuit(resolved_moments) @property def moments(self): diff --git a/cirq-core/cirq/circuits/circuit_dag.py b/cirq-core/cirq/circuits/circuit_dag.py index 4854d532539..fa021e87d6b 100644 --- a/cirq-core/cirq/circuits/circuit_dag.py +++ b/cirq-core/cirq/circuits/circuit_dag.py @@ -11,13 +11,12 @@ # 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 re from typing import Any, Callable, Dict, Generic, Iterator, TypeVar, cast, TYPE_CHECKING import functools import networkx -from cirq import _compat, ops, devices +from cirq import ops from cirq.circuits import circuit if TYPE_CHECKING: @@ -70,17 +69,10 @@ class CircuitDag(networkx.DiGraph): disjoint_qubits = staticmethod(_disjoint_qubits) - @_compat.deprecated_parameter( - deadline='v0.15', - fix=circuit._DEVICE_DEP_MESSAGE, - parameter_desc='device', - match=lambda args, kwargs: 'device' in kwargs or len(args) == 4, - ) def __init__( self, can_reorder: Callable[['cirq.Operation', 'cirq.Operation'], bool] = _disjoint_qubits, incoming_graph_data: Any = None, - device: 'cirq.Device' = devices.UNCONSTRAINED_DEVICE, ) -> None: """Initializes a CircuitDag. @@ -98,15 +90,6 @@ def __init__( """ super().__init__(incoming_graph_data) self.can_reorder = can_reorder - self._device = device - - @property # type: ignore - @_compat.deprecated( - deadline='v0.15', - fix=circuit._DEVICE_DEP_MESSAGE, - ) - def device(self) -> devices.Device: - return self._device @staticmethod def make_node(op: 'cirq.Operation') -> Unique: @@ -117,30 +100,14 @@ def from_circuit( circuit: circuit.Circuit, can_reorder: Callable[['cirq.Operation', 'cirq.Operation'], bool] = _disjoint_qubits, ) -> 'CircuitDag': - if circuit._device == devices.UNCONSTRAINED_DEVICE: - return CircuitDag.from_ops(circuit.all_operations(), can_reorder=can_reorder) - return CircuitDag.from_ops( - circuit.all_operations(), can_reorder=can_reorder, device=circuit._device - ) + return CircuitDag.from_ops(circuit.all_operations(), can_reorder=can_reorder) @staticmethod - @_compat.deprecated_parameter( - deadline='v0.15', - fix=circuit._DEVICE_DEP_MESSAGE, - parameter_desc='device', - match=lambda args, kwargs: 'device' in kwargs, - ) def from_ops( *operations: 'cirq.OP_TREE', can_reorder: Callable[['cirq.Operation', 'cirq.Operation'], bool] = _disjoint_qubits, - device: 'cirq.Device' = devices.UNCONSTRAINED_DEVICE, ) -> 'CircuitDag': - if device == devices.UNCONSTRAINED_DEVICE: - dag = CircuitDag(can_reorder=can_reorder) - else: - with _compat.block_overlapping_deprecation(re.escape(circuit._DEVICE_DEP_MESSAGE)): - dag = CircuitDag(can_reorder=can_reorder, device=device) - + dag = CircuitDag(can_reorder=can_reorder) for op in ops.flatten_op_tree(operations): dag.append(cast(ops.Operation, op)) return dag @@ -212,11 +179,7 @@ def all_qubits(self): return frozenset(q for node in self.nodes for q in node.val.qubits) def to_circuit(self) -> circuit.Circuit: - if self._device == devices.UNCONSTRAINED_DEVICE: - return circuit.Circuit(self.all_operations(), strategy=circuit.InsertStrategy.EARLIEST) - return circuit.Circuit( - self.all_operations(), strategy=circuit.InsertStrategy.EARLIEST, device=self._device - ) + return circuit.Circuit(self.all_operations(), strategy=circuit.InsertStrategy.EARLIEST) def findall_nodes_until_blocked( self, is_blocker: Callable[['cirq.Operation'], bool] diff --git a/cirq-core/cirq/circuits/circuit_dag_test.py b/cirq-core/cirq/circuits/circuit_dag_test.py index 8a17589ccf7..c4dd86ae797 100644 --- a/cirq-core/cirq/circuits/circuit_dag_test.py +++ b/cirq-core/cirq/circuits/circuit_dag_test.py @@ -70,21 +70,6 @@ def test_init(): assert list(dag.edges()) == [] -def test_init_device_deprecated(): - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - _ = cirq.CircuitDag(device=cirq.UNCONSTRAINED_DEVICE) - - -def test_device_deprecated(): - dag = cirq.CircuitDag() - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - _ = dag.device - - def test_append(): q0 = cirq.LineQubit(0) dag = cirq.CircuitDag() @@ -118,14 +103,6 @@ def test_from_ops(): assert [(n1.val, n2.val) for n1, n2 in dag.edges()] == [(cirq.X(q0), cirq.Y(q0))] -def test_from_ops_device_deprecated(): - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - q0 = cirq.LineQubit(0) - _ = cirq.CircuitDag.from_ops(cirq.X(q0), cirq.Y(q0), device=FakeDevice()) - - def test_from_circuit(): q0 = cirq.LineQubit(0) circuit = cirq.Circuit(cirq.X(q0), cirq.Y(q0)) @@ -136,16 +113,6 @@ def test_from_circuit(): assert sorted(circuit.all_qubits()) == sorted(dag.all_qubits()) -def test_from_circuit_deprecated(): - q0 = cirq.LineQubit(0) - circuit = cirq.Circuit(cirq.X(q0), cirq.Y(q0)) - circuit._device = FakeDevice() - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - _ = cirq.CircuitDag.from_circuit(circuit) - - def test_to_empty_circuit(): circuit = cirq.Circuit() dag = cirq.CircuitDag.from_circuit(circuit) @@ -167,18 +134,6 @@ def test_to_circuit(): ) -def test_to_circuit_device_deprecated(): - q0 = cirq.LineQubit(0) - circuit = cirq.Circuit(cirq.X(q0), cirq.Y(q0)) - dag = cirq.CircuitDag.from_circuit(circuit) - dag._device = FakeDevice() - - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - _ = dag.to_circuit() - - def test_equality(): q0, q1 = cirq.LineQubit.range(2) circuit1 = cirq.Circuit( diff --git a/cirq-core/cirq/circuits/circuit_test.py b/cirq-core/cirq/circuits/circuit_test.py index 5cfb226f645..f1d7c131a0f 100644 --- a/cirq-core/cirq/circuits/circuit_test.py +++ b/cirq-core/cirq/circuits/circuit_test.py @@ -16,7 +16,6 @@ from collections import defaultdict from random import randint, random, sample, randrange from typing import Iterator, Optional, Tuple, TYPE_CHECKING -from unittest import mock import numpy as np import pytest @@ -92,29 +91,6 @@ def test_alignment(): assert repr(cirq.Alignment.RIGHT) == 'cirq.Alignment.RIGHT' -def test_insert_moment_types_deprecated(): - x = cirq.NamedQubit('x') - - with pytest.raises(ValueError): - moment_and_op_type_validating_device.validate_operation(cirq.Moment()) - - with pytest.raises(ValueError): - moment_and_op_type_validating_device.validate_moment(cirq.X(x)) - - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - circuit = cirq.Circuit(device=moment_and_op_type_validating_device) - - moment_or_operation_tree = [cirq.X(x), cirq.Moment([cirq.Y(x)])] - with cirq.testing.assert_deprecated('insert', deadline='v0.15'): - circuit.insert(0, moment_or_operation_tree) - - moment_or_operation_tree = [[cirq.Moment([cirq.X(x)])]] - with cirq.testing.assert_deprecated('insert', deadline='v0.15'): - circuit.insert(0, moment_or_operation_tree) - - def test_setitem(): circuit = cirq.Circuit([cirq.Moment(), cirq.Moment()]) @@ -206,23 +182,6 @@ def test_approx_eq(circuit_cls): ) -@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) -def test_approx_eq_device_deprecated(circuit_cls): - class FakeDevice(cirq.Device): - def validate_operation(self, operation: cirq.Operation) -> None: - pass - - a = cirq.NamedQubit('a') - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - other_device = circuit_cls([cirq.Moment([cirq.X(a)])], device=FakeDevice()) - assert not cirq.approx_eq( - circuit_cls([cirq.Moment([cirq.X(a)])]), - other_device, - ) - - def test_append_single(): a = cirq.NamedQubit('a') @@ -425,21 +384,6 @@ def test_radd_op_tree(circuit_cls): ) -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) -def test_radd_op_tree_device_deprecated(circuit_cls): - # Preserves device. - c = circuit_cls(device=FOXY) - c2 = [] + c - assert c2.device is FOXY - assert c2 == c - - # Validates versus device. - c = circuit_cls(device=FOXY) - with pytest.raises(ValueError, match='Unsupported qubit'): - _ = [cirq.X(cirq.NamedQubit('a'))] + c - - def test_add_iadd_equivalence(): q0, q1 = cirq.LineQubit.range(2) iadd_circuit = cirq.Circuit(cirq.X(q0)) @@ -484,25 +428,6 @@ def test_repr(circuit_cls): ) -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) -def test_repr_device_deprecated(circuit_cls): - c = circuit_cls(device=FOXY) - cirq.testing.assert_equivalent_repr(c) - assert repr(c) == f'cirq.{circuit_cls.__name__}(device={repr(FOXY)})' - - c = circuit_cls(cirq.Z(cirq.GridQubit(0, 0)), device=FOXY) - cirq.testing.assert_equivalent_repr(c) - assert ( - repr(c) - == f"""cirq.{circuit_cls.__name__}([ - cirq.Moment( - cirq.Z(cirq.GridQubit(0, 0)), - ), -], device={repr(FOXY)})""" - ) - - @pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) def test_empty_moments(circuit_cls): # 1-qubit test @@ -712,79 +637,6 @@ def test_concatenate(): _ = c + 'a' -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_concatenate_with_device_deprecated(): - fox = cirq.Circuit(device=FOXY) - cone = cirq.Circuit(device=BCONE) - unr = cirq.Circuit() - - _ = cone + cone - _ = cone + unr - _ = unr + cone - cone += unr - with pytest.raises(ValueError): - _ = cone + fox - - unr.append(cirq.X(cirq.NamedQubit('not_allowed'))) - with pytest.raises(ValueError): - cone += unr - with pytest.raises(ValueError): - _ = cone + unr - assert len(cone) == 0 - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) -def test_with_device_logic_deprecated(circuit_cls): - - c = circuit_cls(cirq.X(cirq.LineQubit(0))) - c2 = c.with_device(FOXY, lambda e: cirq.GridQubit(e.x, 0)) - assert c2 == circuit_cls(cirq.X(cirq.GridQubit(0, 0)), device=FOXY) - - # Qubit type must be correct. - c = circuit_cls(cirq.X(cirq.LineQubit(0))) - with pytest.raises(ValueError, match='Unsupported qubit type'): - _ = c.with_device(FOXY) - - # Operations must be compatible from the start - c = circuit_cls(cirq.X(cirq.GridQubit(0, 0))) - _ = c.with_device(FOXY) - c = circuit_cls(cirq.H(cirq.GridQubit(0, 0))) - with pytest.raises(ValueError, match='Unsupported gate type'): - _ = c.with_device(FOXY) - - # Some qubits exist on multiple devices. - c = circuit_cls(cirq.X(cirq.GridQubit(0, 0)), device=FOXY) - with pytest.raises(ValueError): - _ = c.with_device(BCONE) - c = circuit_cls(cirq.X(cirq.GridQubit(0, 6)), device=FOXY) - _ = c.with_device(BCONE) - - -@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) -def test_with_device_deprecated(circuit_cls): - c = circuit_cls() - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - _ = c.with_device(FOXY) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_set_device_deprecated(): - c = cirq.Circuit(cirq.X(cirq.LineQubit(0))) - assert c.device is cirq.UNCONSTRAINED_DEVICE - - with pytest.raises(ValueError): - c.device = FOXY - assert c.device is cirq.UNCONSTRAINED_DEVICE - - c[:] = [] - c.append(cirq.X(cirq.GridQubit(0, 0))) - c.device = FOXY - assert c.device == FOXY - - @pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) def test_multiply(circuit_cls): a = cirq.NamedQubit('a') @@ -1003,18 +855,6 @@ def test_insert_moment(): assert c.operation_at(qubit, actual_index) == operation[0] -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_insert_validates_all_operations_before_inserting_deprecated(): - a, b = cirq.GridQubit(0, 0), cirq.GridQubit(1, 1) - c = cirq.Circuit(device=FOXY) - operations = [cirq.Z(a), cirq.CZ(a, b)] - - with pytest.raises(ValueError, match='Non-local interaction'): - c.insert(0, operations) - - assert len(c) == 0 - - def test_insert_inline_near_start(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') @@ -1178,14 +1018,6 @@ def optimization_at( ) -def test_insert_into_range_deprecated(): - with cirq.testing.assert_deprecated('insert_into_range', deadline='v0.15'): - x, y = cirq.GridQubit.rect(1, 2) - c = cirq.Circuit([cirq.Moment([cirq.X(x)])] * 4) - c._device = FOXY - c.insert_into_range([cirq.Z(x), cirq.CZ(x, y)], 2, 2) - - def test_insert_into_range(): x = cirq.NamedQubit('x') y = cirq.NamedQubit('y') @@ -3753,83 +3585,6 @@ def test_insert_operations_errors(): circuit._insert_operations(operations, insertion_indices) -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_validates_while_editing_deprecated(): - c = cirq.Circuit(device=FOXY) - - with pytest.raises(ValueError, match='Unsupported qubit type'): - # Wrong type of qubit. - c.append(cirq.Z(cirq.NamedQubit('q'))) - with pytest.raises(ValueError, match='Qubit not on device'): - # A qubit that's not on the device. - c[:] = [cirq.Moment([cirq.Z(cirq.GridQubit(-5, 100))])] - c.append(cirq.Z(cirq.GridQubit(0, 0))) - - with pytest.raises(ValueError, match='Non-local interaction'): - # Non-adjacent CZ. - c[0] = cirq.Moment([cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(1, 1))]) - - c.insert(0, cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(1, 0))) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_respects_additional_adjacency_constraints_deprecated(): - c = cirq.Circuit(device=FOXY) - c.append(cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))) - c.append( - cirq.CZ(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)), strategy=cirq.InsertStrategy.EARLIEST - ) - cirq.testing.assert_same_circuits( - c, - cirq.Circuit( - [ - cirq.Moment([cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))]), - cirq.Moment([cirq.CZ(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))]), - ], - device=FOXY, - ), - ) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_commutes_past_adjacency_constraints_deprecated(): - c = cirq.Circuit( - [ - cirq.Moment(), - cirq.Moment(), - cirq.Moment([cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))]), - ], - device=FOXY, - ) - c.append( - cirq.CZ(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)), strategy=cirq.InsertStrategy.EARLIEST - ) - cirq.testing.assert_same_circuits( - c, - cirq.Circuit( - [ - cirq.Moment([cirq.CZ(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))]), - cirq.Moment(), - cirq.Moment([cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))]), - ], - device=FOXY, - ), - ) - - -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_decomposes_while_appending_deprecated(): - c = cirq.Circuit(device=FOXY) - c.append(cirq.TOFFOLI(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), cirq.GridQubit(1, 0))) - cirq.testing.assert_allclose_up_to_global_phase( - c.unitary(), cirq.unitary(cirq.TOFFOLI), atol=1e-8 - ) - - # But you still have to respect adjacency constraints! - with pytest.raises(ValueError): - c.append(cirq.TOFFOLI(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), cirq.GridQubit(0, 6))) - - @pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) def test_to_qasm(circuit_cls): q0 = cirq.NamedQubit('q0') @@ -4250,26 +4005,6 @@ def test_pow_valid_only_for_minus_1(circuit_cls): cirq.pow(forward, -2.5) -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) -def test_device_propagates_deprecated(circuit_cls): - c = circuit_cls(device=moment_and_op_type_validating_device) - assert c[:].device is moment_and_op_type_validating_device - - -def test_device_get_set_deprecated(): - c = cirq.Circuit() - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - c.device = FOXY - - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - assert c.device is FOXY - - @pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) def test_moment_groups(circuit_cls): qubits = [cirq.GridQubit(x, y) for x in range(8) for y in range(8)] @@ -4325,18 +4060,9 @@ def test_json_dict(circuit_cls): moments = tuple(moments) assert c._json_dict_() == { 'moments': moments, - 'device': cirq.UNCONSTRAINED_DEVICE, } -def test_from_json_device_deprecated(): - q0, q1 = cirq.GridQubit.rect(1, 2) - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - _ = cirq.Circuit._from_json_dict_([cirq.CZ(q0, q1)], FOXY) - - def test_with_noise(): class Noise(cirq.NoiseModel): def noisy_operation(self, operation): @@ -4431,21 +4157,6 @@ def test_init_contents(circuit_cls): circuit_cls() -@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) -def test_init_deprecated(circuit_cls): - a, b = cirq.GridQubit.rect(1, 2) - - # Moments are not subject to insertion rules. - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - _ = circuit_cls( - cirq.Moment([cirq.X(a)]), - cirq.Moment([cirq.X(b)]), - device=FOXY, - ) - - def test_transform_qubits(): a, b, c = cirq.LineQubit.range(3) original = cirq.Circuit( @@ -4470,22 +4181,6 @@ def test_transform_qubits(): _ = original.transform_qubits('bad arg') -def test_transform_qubits_deprecated_device(): - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - original = cirq.Circuit(device=FOXY) - - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - assert original.transform_qubits(lambda q: q).device is FOXY - - with cirq.testing.assert_deprecated('new_device', deadline='v0.15', count=2): - # count one for new_device and count one for accessing .device. - assert original.transform_qubits(lambda q: q, new_device=BCONE).device is BCONE - - @pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit]) def test_indexing_by_pair(circuit_cls): # 0: ───H───@───X───@─── diff --git a/cirq-core/cirq/circuits/frozen_circuit.py b/cirq-core/cirq/circuits/frozen_circuit.py index 91a46c5fb6e..9f4b38017ca 100644 --- a/cirq-core/cirq/circuits/frozen_circuit.py +++ b/cirq-core/cirq/circuits/frozen_circuit.py @@ -15,7 +15,6 @@ from typing import ( TYPE_CHECKING, AbstractSet, - Callable, FrozenSet, Iterable, Iterator, @@ -24,7 +23,6 @@ Tuple, Union, ) -import re from cirq.circuits import AbstractCircuit, Alignment, Circuit from cirq.circuits.insert_strategy import InsertStrategy @@ -32,16 +30,13 @@ import numpy as np -from cirq import _compat, devices, ops, protocols +from cirq import ops, protocols if TYPE_CHECKING: import cirq -_DEVICE_DEP_MESSAGE = 'Attaching devices to circuits will no longer be supported.' - - class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey): """An immutable version of the Circuit data structure. @@ -50,17 +45,10 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey): the `freeze` and `unfreeze` methods from AbstractCircuit. """ - @_compat.deprecated_parameter( - deadline='v0.15', - fix=_DEVICE_DEP_MESSAGE, - parameter_desc='device', - match=lambda args, kwargs: 'device' in kwargs, - ) def __init__( self, *contents: 'cirq.OP_TREE', strategy: 'cirq.InsertStrategy' = InsertStrategy.EARLIEST, - device: 'cirq.Device' = devices.UNCONSTRAINED_DEVICE, ) -> None: """Initializes a frozen circuit. @@ -73,16 +61,9 @@ def __init__( strategy: When initializing the circuit with operations and moments from `contents`, this determines how the operations are packed together. - device: Hardware that the circuit should be able to run on. """ - if device == devices.UNCONSTRAINED_DEVICE: - base = Circuit(contents, strategy=strategy) - else: - with _compat.block_overlapping_deprecation(re.escape(_DEVICE_DEP_MESSAGE)): - base = Circuit(contents, strategy=strategy, device=device) - + base = Circuit(contents, strategy=strategy) self._moments = tuple(base.moments) - self._device = base._device # These variables are memoized when first requested. self._num_qubits: Optional[int] = None @@ -99,16 +80,8 @@ def __init__( def moments(self) -> Sequence['cirq.Moment']: return self._moments - @property # type: ignore - @_compat.deprecated( - deadline='v0.15', - fix=_DEVICE_DEP_MESSAGE, - ) - def device(self) -> devices.Device: - return self._device - def __hash__(self): - return hash((self.moments, self._device)) + return hash((self.moments,)) # Memoized methods for commonly-retrieved properties. @@ -196,25 +169,10 @@ def __pow__(self, other) -> 'cirq.FrozenCircuit': return NotImplemented def _with_sliced_moments(self, moments: Iterable['cirq.Moment']) -> 'FrozenCircuit': - if self._device == devices.UNCONSTRAINED_DEVICE: - new_circuit = FrozenCircuit() - else: - new_circuit = FrozenCircuit(device=self._device) + new_circuit = FrozenCircuit() new_circuit._moments = tuple(moments) return new_circuit - @_compat.deprecated( - deadline='v0.15', - fix=_DEVICE_DEP_MESSAGE, - ) - def with_device( - self, - new_device: 'cirq.Device', - qubit_mapping: Callable[['cirq.Qid'], 'cirq.Qid'] = lambda e: e, - ) -> 'FrozenCircuit': - with _compat.block_overlapping_deprecation(re.escape(_DEVICE_DEP_MESSAGE)): - return self.unfreeze().with_device(new_device, qubit_mapping).freeze() - def _resolve_parameters_( self, resolver: 'cirq.ParamResolver', recursive: bool ) -> 'cirq.FrozenCircuit': diff --git a/cirq-core/cirq/circuits/frozen_circuit_test.py b/cirq-core/cirq/circuits/frozen_circuit_test.py index 745094713ed..155e3420f65 100644 --- a/cirq-core/cirq/circuits/frozen_circuit_test.py +++ b/cirq-core/cirq/circuits/frozen_circuit_test.py @@ -47,39 +47,9 @@ def test_freeze_and_unfreeze(): assert fcc is not f -def test_init_device_deprecated(): - q = cirq.LineQubit(0) - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - _ = cirq.FrozenCircuit(cirq.X(q), device=cirq.UNCONSTRAINED_DEVICE) - - -def test_device_deprecated(): - q = cirq.LineQubit(0) - a = cirq.FrozenCircuit(cirq.X(q)) - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - _ = a.device - - -def test_with_device_deprecated(): - q = cirq.LineQubit(0) - a = cirq.FrozenCircuit(cirq.X(q)) - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - # one for frozencircuit.with_device and one for circuit.with_device. - _ = a.with_device(cirq.UNCONSTRAINED_DEVICE) - - def test_immutable(): q = cirq.LineQubit(0) c = cirq.FrozenCircuit(cirq.X(q), cirq.H(q)) with pytest.raises(AttributeError, match="can't set attribute"): c.moments = (cirq.Moment(cirq.H(q)), cirq.Moment(cirq.X(q))) - - with pytest.raises(AttributeError, match="can't set attribute"): - c.device = cirq.UNCONSTRAINED_DEVICE diff --git a/cirq-core/cirq/protocols/json_test_data/Circuit.json b/cirq-core/cirq/protocols/json_test_data/Circuit.json index ac467a20390..b6d3e24041a 100644 --- a/cirq-core/cirq/protocols/json_test_data/Circuit.json +++ b/cirq-core/cirq/protocols/json_test_data/Circuit.json @@ -113,10 +113,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] }, { "cirq_type": "Circuit", @@ -167,10 +164,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] }, { "cirq_type": "Circuit", @@ -197,9 +191,6 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } ] \ No newline at end of file diff --git a/cirq-core/cirq/protocols/json_test_data/Circuit.json_inward b/cirq-core/cirq/protocols/json_test_data/Circuit.json_inward new file mode 100644 index 00000000000..ac467a20390 --- /dev/null +++ b/cirq-core/cirq/protocols/json_test_data/Circuit.json_inward @@ -0,0 +1,205 @@ +[ + { + "cirq_type": "Circuit", + "moments": [ + { + "cirq_type": "Moment", + "operations": [ + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "HPowGate", + "exponent": 1, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 0 + } + ] + }, + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "HPowGate", + "exponent": 1, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 1 + } + ] + }, + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "HPowGate", + "exponent": 1, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 2 + } + ] + }, + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "HPowGate", + "exponent": 1, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 3 + } + ] + }, + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "HPowGate", + "exponent": 1, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 4 + } + ] + } + ] + }, + { + "cirq_type": "Moment", + "operations": [ + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "MeasurementGate", + "num_qubits": 5, + "key": "0,1,2,3,4", + "invert_mask": [] + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 0 + }, + { + "cirq_type": "LineQubit", + "x": 1 + }, + { + "cirq_type": "LineQubit", + "x": 2 + }, + { + "cirq_type": "LineQubit", + "x": 3 + }, + { + "cirq_type": "LineQubit", + "x": 4 + } + ] + } + ] + } + ], + "device": { + "cirq_type": "_UnconstrainedDevice" + } + }, + { + "cirq_type": "Circuit", + "moments": [ + { + "cirq_type": "Moment", + "operations": [ + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "CCXPowGate", + "exponent": 1, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 0 + }, + { + "cirq_type": "LineQubit", + "x": 1 + }, + { + "cirq_type": "LineQubit", + "x": 2 + } + ] + } + ] + }, + { + "cirq_type": "Moment", + "operations": [ + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "XPowGate", + "exponent": 0.123, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 0 + } + ] + } + ] + } + ], + "device": { + "cirq_type": "_UnconstrainedDevice" + } + }, + { + "cirq_type": "Circuit", + "moments": [ + { + "cirq_type": "Moment", + "operations": [ + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "XPowGate", + "exponent": { + "cirq_type": "sympy.Symbol", + "name": "theta" + }, + "global_shift": 0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 0 + } + ] + } + ] + } + ], + "device": { + "cirq_type": "_UnconstrainedDevice" + } + } +] \ No newline at end of file diff --git a/cirq-core/cirq/protocols/json_test_data/Circuit.repr_inward b/cirq-core/cirq/protocols/json_test_data/Circuit.repr_inward new file mode 100644 index 00000000000..b4bad10bee8 --- /dev/null +++ b/cirq-core/cirq/protocols/json_test_data/Circuit.repr_inward @@ -0,0 +1,23 @@ +[cirq.Circuit([ + cirq.Moment( + cirq.H(cirq.LineQubit(0)), + cirq.H(cirq.LineQubit(1)), + cirq.H(cirq.LineQubit(2)), + cirq.H(cirq.LineQubit(3)), + cirq.H(cirq.LineQubit(4)), + ), + cirq.Moment( + cirq.MeasurementGate(5, '0,1,2,3,4', ()).on(cirq.LineQubit(0), cirq.LineQubit(1), cirq.LineQubit(2), cirq.LineQubit(3), cirq.LineQubit(4)), + ), +]), cirq.Circuit([ + cirq.Moment( + cirq.TOFFOLI(cirq.LineQubit(0), cirq.LineQubit(1), cirq.LineQubit(2)), + ), + cirq.Moment( + (cirq.X**0.123).on(cirq.LineQubit(0)), + ), +]), cirq.Circuit([ + cirq.Moment( + (cirq.X**sympy.Symbol('theta')).on(cirq.LineQubit(0)), + ), +])] \ No newline at end of file diff --git a/cirq-core/cirq/protocols/json_test_data/CircuitOperation.json b/cirq-core/cirq/protocols/json_test_data/CircuitOperation.json index 7fbb4421dbe..9d188d195f8 100644 --- a/cirq-core/cirq/protocols/json_test_data/CircuitOperation.json +++ b/cirq-core/cirq/protocols/json_test_data/CircuitOperation.json @@ -118,10 +118,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } }, { @@ -149,10 +146,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } }, { @@ -183,10 +177,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } }, [ diff --git a/cirq-core/cirq/protocols/json_test_data/FrozenCircuit.json b/cirq-core/cirq/protocols/json_test_data/FrozenCircuit.json index 02e4cf78a6b..9e2f6722311 100644 --- a/cirq-core/cirq/protocols/json_test_data/FrozenCircuit.json +++ b/cirq-core/cirq/protocols/json_test_data/FrozenCircuit.json @@ -115,10 +115,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } }, { @@ -173,10 +170,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } }, { @@ -207,10 +201,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } }, [ diff --git a/cirq-core/cirq/protocols/json_test_data/FrozenCircuit.json_inward b/cirq-core/cirq/protocols/json_test_data/FrozenCircuit.json_inward new file mode 100644 index 00000000000..02e4cf78a6b --- /dev/null +++ b/cirq-core/cirq/protocols/json_test_data/FrozenCircuit.json_inward @@ -0,0 +1,231 @@ +{ + "cirq_type": "_ContextualSerialization", + "object_dag": [ + { + "cirq_type": "_SerializedContext", + "key": 1, + "obj": { + "cirq_type": "FrozenCircuit", + "moments": [ { "cirq_type": "Moment", + "operations": [ + { + "cirq_type": "GateOperation", + "gate": { "cirq_type": "HPowGate", + "exponent": 1.0, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 0 + } + ] + }, + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "HPowGate", + "exponent": 1.0, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 1 + } + ] + }, + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "HPowGate", + "exponent": 1.0, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 2 + } + ] + }, + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "HPowGate", + "exponent": 1.0, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 3 + } + ] + }, + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "HPowGate", + "exponent": 1.0, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 4 + } + ] + } + ] + }, + { + "cirq_type": "Moment", + "operations": [ + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "MeasurementGate", + "num_qubits": 5, + "key": "0,1,2,3,4", + "invert_mask": [] + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 0 + }, + { + "cirq_type": "LineQubit", + "x": 1 + }, + { + "cirq_type": "LineQubit", + "x": 2 + }, + { + "cirq_type": "LineQubit", + "x": 3 + }, + { + "cirq_type": "LineQubit", + "x": 4 + } + ] + } + ] + } + ], + "device": { + "cirq_type": "_UnconstrainedDevice" + } + } + }, + { + "cirq_type": "_SerializedContext", + "key": 2, + "obj": { + "cirq_type": "FrozenCircuit", + "moments": [ + { + "cirq_type": "Moment", + "operations": [ + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "CCXPowGate", + "exponent": 1.0, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 0 + }, + { + "cirq_type": "LineQubit", + "x": 1 + }, + { + "cirq_type": "LineQubit", + "x": 2 + } + ] + } + ] + }, + { + "cirq_type": "Moment", + "operations": [ + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "XPowGate", + "exponent": 0.123, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 0 + } + ] + } + ] + } + ], + "device": { + "cirq_type": "_UnconstrainedDevice" + } + } + }, + { + "cirq_type": "_SerializedContext", + "key": 3, + "obj": { + "cirq_type": "FrozenCircuit", + "moments": [ + { + "cirq_type": "Moment", + "operations": [ + { + "cirq_type": "GateOperation", + "gate": { + "cirq_type": "XPowGate", + "exponent": { + "cirq_type": "sympy.Symbol", + "name": "theta" + }, + "global_shift": 0.0 + }, + "qubits": [ + { + "cirq_type": "LineQubit", + "x": 0 + } + ] + } + ] + } + ], + "device": { + "cirq_type": "_UnconstrainedDevice" + } + } + }, + [ + { + "cirq_type": "_SerializedKey", + "key": 1 + }, + { + "cirq_type": "_SerializedKey", + "key": 2 + }, + { + "cirq_type": "_SerializedKey", + "key": 3 + } + ] + ] +} \ No newline at end of file diff --git a/cirq-core/cirq/protocols/json_test_data/FrozenCircuit.repr_inward b/cirq-core/cirq/protocols/json_test_data/FrozenCircuit.repr_inward new file mode 100644 index 00000000000..0bc98a8f705 --- /dev/null +++ b/cirq-core/cirq/protocols/json_test_data/FrozenCircuit.repr_inward @@ -0,0 +1,23 @@ +[cirq.FrozenCircuit([ + cirq.Moment( + cirq.H(cirq.LineQubit(0)), + cirq.H(cirq.LineQubit(1)), + cirq.H(cirq.LineQubit(2)), + cirq.H(cirq.LineQubit(3)), + cirq.H(cirq.LineQubit(4)), + ), + cirq.Moment( + cirq.MeasurementGate(5, '0,1,2,3,4', ()).on(cirq.LineQubit(0), cirq.LineQubit(1), cirq.LineQubit(2), cirq.LineQubit(3), cirq.LineQubit(4)), + ), +]), cirq.FrozenCircuit([ + cirq.Moment( + cirq.TOFFOLI(cirq.LineQubit(0), cirq.LineQubit(1), cirq.LineQubit(2)), + ), + cirq.Moment( + (cirq.X**0.123).on(cirq.LineQubit(0)), + ), +]), cirq.FrozenCircuit([ + cirq.Moment( + (cirq.X**sympy.Symbol('theta')).on(cirq.LineQubit(0)), + ), +])] \ No newline at end of file diff --git a/cirq-core/cirq/testing/devices_test.py b/cirq-core/cirq/testing/devices_test.py index 57f276f929d..2de648b7e95 100644 --- a/cirq-core/cirq/testing/devices_test.py +++ b/cirq-core/cirq/testing/devices_test.py @@ -11,8 +11,6 @@ # 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 from cirq.testing.devices import ValidatingTestDevice @@ -63,48 +61,6 @@ def test_validating_locality(): ) -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_autodecompose_deprecated(): - dev = ValidatingTestDevice( - allowed_qubit_types=(cirq.LineQubit,), - allowed_gates=( - cirq.XPowGate, - cirq.ZPowGate, - cirq.CZPowGate, - cirq.YPowGate, - cirq.MeasurementGate, - ), - qubits=set(cirq.LineQubit.range(3)), - name='test', - validate_locality=False, - auto_decompose_gates=(cirq.CCXPowGate,), - ) - - a, b, c = cirq.LineQubit.range(3) - circuit = cirq.Circuit(cirq.CCX(a, b, c), device=dev) - decomposed = cirq.decompose(cirq.CCX(a, b, c)) - assert circuit.moments == cirq.Circuit(decomposed).moments - - with pytest.raises(ValueError, match="Unsupported gate type: cirq.TOFFOLI"): - dev = ValidatingTestDevice( - allowed_qubit_types=(cirq.LineQubit,), - allowed_gates=( - cirq.XPowGate, - cirq.ZPowGate, - cirq.CZPowGate, - cirq.YPowGate, - cirq.MeasurementGate, - ), - qubits=set(cirq.LineQubit.range(3)), - name='test', - validate_locality=False, - auto_decompose_gates=tuple(), - ) - - a, b, c = cirq.LineQubit.range(3) - cirq.Circuit(cirq.CCX(a, b, c), device=dev) - - def test_repr(): dev = ValidatingTestDevice( allowed_qubit_types=(cirq.GridQubit,), diff --git a/cirq-core/cirq/testing/sample_circuits.py b/cirq-core/cirq/testing/sample_circuits.py index f235858a7cc..a3105ea2bcc 100644 --- a/cirq-core/cirq/testing/sample_circuits.py +++ b/cirq-core/cirq/testing/sample_circuits.py @@ -13,24 +13,13 @@ # limitations under the License. from typing import TYPE_CHECKING -from cirq import _compat, ops, circuits, devices +from cirq import ops, circuits if TYPE_CHECKING: import cirq -@_compat.deprecated_parameter( - deadline='v0.15', - fix='The returned circuit will no longer include a device object.', - parameter_desc='device', - match=lambda args, kwargs: 'device' in kwargs or len(args) == 4, -) -def nonoptimal_toffoli_circuit( - q0: 'cirq.Qid', - q1: 'cirq.Qid', - q2: 'cirq.Qid', - device: devices.Device = devices.UNCONSTRAINED_DEVICE, -) -> circuits.Circuit: +def nonoptimal_toffoli_circuit(q0: 'cirq.Qid', q1: 'cirq.Qid', q2: 'cirq.Qid') -> circuits.Circuit: ret = circuits.Circuit( ops.Y(q2) ** 0.5, ops.X(q2), @@ -62,5 +51,4 @@ def nonoptimal_toffoli_circuit( ops.Y(q2) ** 0.5, ops.X(q2), ) - ret._device = device return ret diff --git a/cirq-core/cirq/testing/sample_circuits_test.py b/cirq-core/cirq/testing/sample_circuits_test.py index 052b4bbaaa7..b7f75ddcbf6 100644 --- a/cirq-core/cirq/testing/sample_circuits_test.py +++ b/cirq-core/cirq/testing/sample_circuits_test.py @@ -22,15 +22,3 @@ def test_nonoptimal_toffoli_circuit(): cirq.unitary(cirq.TOFFOLI(q0, q1, q2)), atol=1e-7, ) - - -def test_nonoptimal_toffoli_circuit_device_deprecated(): - q0, q1, q2 = cirq.LineQubit.range(3) - with cirq.testing.assert_deprecated('no longer include a device', deadline='v0.15'): - cirq.testing.assert_allclose_up_to_global_phase( - cirq.testing.nonoptimal_toffoli_circuit( - q0, q1, q2, cirq.UNCONSTRAINED_DEVICE - ).unitary(), - cirq.unitary(cirq.TOFFOLI(q0, q1, q2)), - atol=1e-7, - ) diff --git a/cirq-core/cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py b/cirq-core/cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py index d0542b17f59..8db240fabb0 100644 --- a/cirq-core/cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +++ b/cirq-core/cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py @@ -269,9 +269,13 @@ def assert_specific_sqrt_iswap_count(operations, count): ) def test_two_qubit_gates_with_symbols(gate: cirq.Gate): op = gate(*cirq.LineQubit.range(2)) - c_new_sqrt_iswap = cirq.Circuit(cirq.parameterized_2q_op_to_sqrt_iswap_operations(op)) + c_new_sqrt_iswap = cirq.Circuit( + cirq.parameterized_2q_op_to_sqrt_iswap_operations(op) # type: ignore + ) c_new_sqrt_iswap_inv = cirq.Circuit( - cirq.parameterized_2q_op_to_sqrt_iswap_operations(op, use_sqrt_iswap_inv=True) + cirq.parameterized_2q_op_to_sqrt_iswap_operations( + op, use_sqrt_iswap_inv=True + ) # type: ignore ) # Check if unitaries are the same for val in np.linspace(0, 2 * np.pi, 12): diff --git a/cirq-google/cirq_google/api/v1/programs.py b/cirq-google/cirq_google/api/v1/programs.py index 6ff037007b8..cb975b0d159 100644 --- a/cirq-google/cirq_google/api/v1/programs.py +++ b/cirq-google/cirq_google/api/v1/programs.py @@ -166,25 +166,13 @@ def circuit_as_schedule_to_protos(circuit: cirq.Circuit) -> Iterator[operations_ yield op_proto -@cirq._compat.deprecated_parameter( - deadline='v0.15', - fix=cirq.circuits.circuit._DEVICE_DEP_MESSAGE, - parameter_desc='device', - match=lambda args, kwargs: 'device' in kwargs or len(args) > 1, -) -def circuit_from_schedule_from_protos(*args) -> cirq.Circuit: +def circuit_from_schedule_from_protos(ops) -> cirq.Circuit: """Convert protos into a Circuit.""" - if len(args) == 2: - device, ops = args[0], args[1] - else: - ops = args[0] result = [] for op in ops: xmon_op = xmon_op_from_proto(op) result.append(xmon_op) ret = cirq.Circuit(result) - if len(args) == 2: - ret._device = device return ret diff --git a/cirq-google/cirq_google/api/v1/programs_test.py b/cirq-google/cirq_google/api/v1/programs_test.py index 52ab4bd58eb..7dab8d890c7 100644 --- a/cirq-google/cirq_google/api/v1/programs_test.py +++ b/cirq-google/cirq_google/api/v1/programs_test.py @@ -16,7 +16,6 @@ import sympy import cirq -import cirq_google as cg import cirq_google.api.v1.programs as programs from cirq_google.api.v1 import operations_pb2 @@ -43,23 +42,6 @@ def test_protobuf_round_trip(): assert s2 == circuit -def test_protobuf_round_trip_device_deprecated(): - with cirq.testing.assert_deprecated('Foxtail', deadline='v0.15'): - device = cg.Foxtail - circuit = cirq.Circuit( - [cirq.X(q) ** 0.5 for q in device.qubits], - [cirq.CZ(q, q2) for q in [cirq.GridQubit(0, 0)] for q2 in device.neighbors_of(q)], - ) - circuit._device = device - - protos = list(programs.circuit_as_schedule_to_protos(circuit)) - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - s2 = programs.circuit_from_schedule_from_protos(device, protos) - assert s2 == circuit - - def make_bytes(s: str) -> bytes: """Helper function to convert a string of digits into packed bytes. @@ -252,7 +234,7 @@ def test_z_proto_convert(): ) assert_proto_dict_convert(gate, proto, cirq.GridQubit(2, 3)) - gate = cirq.Z ** 0.5 + gate = cirq.Z**0.5 proto = operations_pb2.Operation( exp_z=operations_pb2.ExpZ( target=operations_pb2.Qubit(row=2, col=3), @@ -273,7 +255,7 @@ def test_cz_proto_convert(): ) assert_proto_dict_convert(gate, proto, cirq.GridQubit(2, 3), cirq.GridQubit(3, 4)) - gate = cirq.CZ ** 0.5 + gate = cirq.CZ**0.5 proto = operations_pb2.Operation( exp_11=operations_pb2.Exp11( target1=operations_pb2.Qubit(row=2, col=3), @@ -305,7 +287,7 @@ def test_w_to_proto(): ) assert_proto_dict_convert(gate, proto, cirq.GridQubit(2, 3)) - gate = cirq.X ** 0.25 + gate = cirq.X**0.25 proto = operations_pb2.Operation( exp_w=operations_pb2.ExpW( target=operations_pb2.Qubit(row=2, col=3), @@ -315,7 +297,7 @@ def test_w_to_proto(): ) assert_proto_dict_convert(gate, proto, cirq.GridQubit(2, 3)) - gate = cirq.Y ** 0.25 + gate = cirq.Y**0.25 proto = operations_pb2.Operation( exp_w=operations_pb2.ExpW( target=operations_pb2.Qubit(row=2, col=3), @@ -347,9 +329,9 @@ def test_unsupported_op(): def test_invalid_to_proto_dict_qubit_number(): with pytest.raises(ValueError, match='Wrong number of qubits'): - _ = programs.gate_to_proto(cirq.CZ ** 0.5, (cirq.GridQubit(2, 3),), delay=0) + _ = programs.gate_to_proto(cirq.CZ**0.5, (cirq.GridQubit(2, 3),), delay=0) with pytest.raises(ValueError, match='Wrong number of qubits'): - programs.gate_to_proto(cirq.Z ** 0.5, (cirq.GridQubit(2, 3), cirq.GridQubit(3, 4)), delay=0) + programs.gate_to_proto(cirq.Z**0.5, (cirq.GridQubit(2, 3), cirq.GridQubit(3, 4)), delay=0) with pytest.raises(ValueError, match='Wrong number of qubits'): programs.gate_to_proto( cirq.PhasedXPowGate(exponent=0.5, phase_exponent=0), @@ -398,10 +380,10 @@ def test_is_supported(): def test_is_native_xmon_gate(): assert programs.is_native_xmon_gate(cirq.CZ) - assert programs.is_native_xmon_gate(cirq.X ** 0.5) - assert programs.is_native_xmon_gate(cirq.Y ** 0.5) - assert programs.is_native_xmon_gate(cirq.Z ** 0.5) + assert programs.is_native_xmon_gate(cirq.X**0.5) + assert programs.is_native_xmon_gate(cirq.Y**0.5) + assert programs.is_native_xmon_gate(cirq.Z**0.5) assert programs.is_native_xmon_gate(cirq.PhasedXPowGate(phase_exponent=0.2) ** 0.5) - assert programs.is_native_xmon_gate(cirq.Z ** 1) + assert programs.is_native_xmon_gate(cirq.Z**1) assert not programs.is_native_xmon_gate(cirq.CCZ) assert not programs.is_native_xmon_gate(cirq.SWAP) diff --git a/cirq-google/cirq_google/json_test_data/CalibrationLayer.json b/cirq-google/cirq_google/json_test_data/CalibrationLayer.json index 44934e78477..e884d09d166 100644 --- a/cirq-google/cirq_google/json_test_data/CalibrationLayer.json +++ b/cirq-google/cirq_google/json_test_data/CalibrationLayer.json @@ -22,10 +22,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] }, "args": { "type": "full", diff --git a/cirq-google/cirq_google/json_test_data/cirq.google.QuantumExecutable.json b/cirq-google/cirq_google/json_test_data/cirq.google.QuantumExecutable.json index 5710d73d654..6ee36ec4696 100644 --- a/cirq-google/cirq_google/json_test_data/cirq.google.QuantumExecutable.json +++ b/cirq-google/cirq_google/json_test_data/cirq.google.QuantumExecutable.json @@ -839,10 +839,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } }, { diff --git a/cirq-google/cirq_google/json_test_data/cirq.google.QuantumExecutableGroup.json b/cirq-google/cirq_google/json_test_data/cirq.google.QuantumExecutableGroup.json index 7a01a7f9a47..577b2507e5d 100644 --- a/cirq-google/cirq_google/json_test_data/cirq.google.QuantumExecutableGroup.json +++ b/cirq-google/cirq_google/json_test_data/cirq.google.QuantumExecutableGroup.json @@ -881,10 +881,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } }, { @@ -1769,10 +1766,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } }, { @@ -2567,10 +2561,7 @@ } ] } - ], - "device": { - "cirq_type": "_UnconstrainedDevice" - } + ] } }, { diff --git a/cirq-google/cirq_google/optimizers/optimize_for_sycamore.py b/cirq-google/cirq_google/optimizers/optimize_for_sycamore.py index b641e74930f..51a0be9c820 100644 --- a/cirq-google/cirq_google/optimizers/optimize_for_sycamore.py +++ b/cirq-google/cirq_google/optimizers/optimize_for_sycamore.py @@ -48,16 +48,9 @@ def _gate_product_tabulation_cached( raise NotImplementedError(f"Two qubit gate tabulation not supported for {optimizer_type}") -@cirq._compat.deprecated_parameter( - deadline='v0.15', - fix=cirq.circuits.circuit._DEVICE_DEP_MESSAGE, - parameter_desc='new_device', - match=lambda args, kwargs: 'new_device' in kwargs, -) def optimized_for_sycamore( circuit: cirq.Circuit, *, - new_device: Optional['cirq_google.XmonDevice'] = None, qubit_map: Callable[[cirq.Qid], cirq.GridQubit] = lambda e: cast(cirq.GridQubit, e), optimizer_type: str = 'sqrt_iswap', tolerance: float = 1e-5, @@ -72,8 +65,6 @@ def optimized_for_sycamore( Args: circuit: The circuit to optimize. - new_device: The device the optimized circuit should be targeted at. If - set to None, the circuit's current device is used. qubit_map: Transforms the qubits (e.g. so that they are GridQubits). optimizer_type: A string defining the optimizations to apply. Possible values are 'xmon', 'xmon_partial_cz', 'sqrt_iswap', @@ -116,5 +107,4 @@ def optimized_for_sycamore( (op.transform_qubits(qubit_map) for op in copy.all_operations()), strategy=cirq.InsertStrategy.EARLIEST, ) - ret._device = new_device or copy._device return ret diff --git a/cirq-google/cirq_google/optimizers/optimize_for_sycamore_test.py b/cirq-google/cirq_google/optimizers/optimize_for_sycamore_test.py index f3af74fede9..b95e42cafaa 100644 --- a/cirq-google/cirq_google/optimizers/optimize_for_sycamore_test.py +++ b/cirq-google/cirq_google/optimizers/optimize_for_sycamore_test.py @@ -123,19 +123,6 @@ def test_one_q_matrix_gate(): assert cg.SQRT_ISWAP_GATESET.is_supported_operation(op) -def test_assert_new_device_deprecated(): - u = cirq.testing.random_special_unitary(2) - q = cirq.LineQubit(0) - circuit0 = cirq.Circuit(cirq.MatrixGate(u).on(q)) - _ = cg.optimized_for_sycamore(circuit0, optimizer_type='sqrt_iswap') - with cirq.testing.assert_deprecated( - cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15' - ): - _ = cg.optimized_for_sycamore( - circuit0, optimizer_type='sqrt_iswap', new_device=FakeDevice() - ) - - @pytest.mark.parametrize( 'optimizer_type, two_qubit_gate_type', [('sycamore', cg.SycamoreGate), ('sqrt_iswap', cirq.ISwapPowGate), ('xmon', cirq.CZPowGate)], diff --git a/cirq-google/cirq_google/optimizers/optimize_for_xmon.py b/cirq-google/cirq_google/optimizers/optimize_for_xmon.py index 5bd9430622a..0c91646b403 100644 --- a/cirq-google/cirq_google/optimizers/optimize_for_xmon.py +++ b/cirq-google/cirq_google/optimizers/optimize_for_xmon.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """A combination of several optimizations targeting XmonDevice.""" -from typing import Callable, cast, Optional, TYPE_CHECKING +from typing import Callable, cast, TYPE_CHECKING import cirq from cirq_google.optimizers import optimized_for_sycamore @@ -21,19 +21,11 @@ import cirq_google -@cirq._compat.deprecated_parameter( - deadline='v0.15', - fix=cirq.circuits.circuit._DEVICE_DEP_MESSAGE, - parameter_desc='new_device', - match=lambda args, kwargs: 'new_device' in kwargs, -) def optimized_for_xmon( circuit: cirq.Circuit, - new_device: Optional['cirq_google.XmonDevice'] = None, qubit_map: Callable[[cirq.Qid], cirq.GridQubit] = lambda e: cast(cirq.GridQubit, e), allow_partial_czs: bool = False, ) -> cirq.Circuit: optimizer_type = 'xmon_partial_cz' if allow_partial_czs else 'xmon' ret = optimized_for_sycamore(circuit, qubit_map=qubit_map, optimizer_type=optimizer_type) - ret._device = new_device or circuit._device return ret diff --git a/cirq-google/cirq_google/serialization/circuit_serializer.py b/cirq-google/cirq_google/serialization/circuit_serializer.py index 7452c69ce52..a2b6fa449b3 100644 --- a/cirq-google/cirq_google/serialization/circuit_serializer.py +++ b/cirq-google/cirq_google/serialization/circuit_serializer.py @@ -313,18 +313,14 @@ def _serialize_circuit_op( raw_constants=raw_constants, ) - def deserialize( - self, proto: v2.program_pb2.Program, device: Optional[cirq.Device] = None - ) -> cirq.Circuit: + def deserialize(self, proto: v2.program_pb2.Program) -> cirq.Circuit: """Deserialize a Circuit from a cirq_google.api.v2.Program. Args: proto: A dictionary representing a cirq_google.api.v2.Program proto. - device: If the proto is for a schedule, a device is required - Otherwise optional. Returns: - The deserialized Circuit, with a device if device was not None. + The deserialized Circuit Raises: ValueError: If the given proto has no language or the langauge gate set mismatches @@ -367,7 +363,7 @@ def deserialize( constants=proto.constants, deserialized_constants=deserialized_constants, ) - return circuit if device is None else circuit.with_device(device) + return circuit if which == 'schedule': raise ValueError('Deserializing a schedule is no longer supported.') diff --git a/cirq-google/cirq_google/serialization/circuit_serializer_test.py b/cirq-google/cirq_google/serialization/circuit_serializer_test.py index ce91b08708a..f1a994f8b9f 100644 --- a/cirq-google/cirq_google/serialization/circuit_serializer_test.py +++ b/cirq-google/cirq_google/serialization/circuit_serializer_test.py @@ -680,7 +680,7 @@ def test_deserialize_schedule_not_supported(): ), ) with pytest.raises(ValueError, match='no longer supported'): - serializer.deserialize(proto, FakeDevice()) + serializer.deserialize(proto) def test_deserialize_fsim_missing_parameters(): diff --git a/cirq-google/cirq_google/serialization/gate_sets_test.py b/cirq-google/cirq_google/serialization/gate_sets_test.py index 4533f160798..8173751faf9 100644 --- a/cirq-google/cirq_google/serialization/gate_sets_test.py +++ b/cirq-google/cirq_google/serialization/gate_sets_test.py @@ -11,9 +11,7 @@ # 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 typing import Dict -from unittest import mock import numpy as np import pytest import sympy @@ -356,36 +354,6 @@ def test_deserialize_circuit(): assert cg.XMON.deserialize(serialized) == circuit -@mock.patch.dict(os.environ, clear='CIRQ_TESTING') -def test_deserialize_schedule_device_deprecated(): - q0 = cirq.GridQubit(4, 4) - q1 = cirq.GridQubit(4, 5) - circuit = cirq.Circuit( - cirq.CZ(q0, q1), cirq.X(q0), cirq.Z(q1), cirq.measure(q0, key='a'), device=cg.Bristlecone - ) - serialized = v2.program_pb2.Program( - language=v2.program_pb2.Language(gate_set='xmon'), - schedule=v2.program_pb2.Schedule( - scheduled_operations=[ - v2.program_pb2.ScheduledOperation( - operation=cg.XMON.serialize_op(cirq.CZ(q0, q1)), start_time_picos=0 - ), - v2.program_pb2.ScheduledOperation( - operation=cg.XMON.serialize_op(cirq.X(q0)), start_time_picos=200000 - ), - v2.program_pb2.ScheduledOperation( - operation=cg.XMON.serialize_op(cirq.Z(q1)), start_time_picos=200000 - ), - v2.program_pb2.ScheduledOperation( - operation=cg.XMON.serialize_op(cirq.measure(q0, key='a')), - start_time_picos=400000, - ), - ] - ), - ) - assert cg.XMON.deserialize(serialized, cg.Bristlecone) == circuit - - def test_deserialize_schedule(): q0 = cirq.GridQubit(4, 4) q1 = cirq.GridQubit(4, 5) diff --git a/cirq-google/cirq_google/serialization/serializable_gate_set.py b/cirq-google/cirq_google/serialization/serializable_gate_set.py index 985098b4eaa..a7edacc4760 100644 --- a/cirq-google/cirq_google/serialization/serializable_gate_set.py +++ b/cirq-google/cirq_google/serialization/serializable_gate_set.py @@ -273,30 +273,18 @@ def serialize_circuit_op( return proto_msg raise ValueError(f'Cannot serialize CircuitOperation {op!r}') - @cirq._compat.deprecated_parameter( - deadline='v0.15', - fix=cirq.circuits.circuit._DEVICE_DEP_MESSAGE, - parameter_desc='device', - match=lambda args, kwargs: 'device' in kwargs or len(args) > 2, - ) - def deserialize( - self, proto: v2.program_pb2.Program, device: Optional[cirq.Device] = None - ) -> cirq.Circuit: + def deserialize(self, proto: v2.program_pb2.Program) -> cirq.Circuit: """Deserialize a Circuit from a cirq_google.api.v2.Program. Args: proto: A dictionary representing a cirq_google.api.v2.Program proto. - device: If the proto is for a schedule, a device is required - Otherwise optional. Returns: - The deserialized Circuit, with a device if device was - not None. + The deserialized Circuit. Raises: ValueError: If the given proto has no language specified or it mismatched the - name specified for this serializable gate set. In addition if the program - is a schedule and no device was specified. + name specified for this serializable gate set. NotImplementedError: If the program does not contain a circuit or schedule. """ if not proto.HasField('language') or not proto.language.gate_set: @@ -328,12 +316,10 @@ def deserialize( constants=proto.constants, deserialized_constants=deserialized_constants, ) - if device is not None: - circuit._device = device # coverage: ignore return circuit if which == 'schedule': return self._deserialize_schedule( - proto.schedule, device, arg_function_language=proto.language.arg_function_language + proto.schedule, arg_function_language=proto.language.arg_function_language ) raise NotImplementedError('Program proto does not contain a circuit.') @@ -503,7 +489,6 @@ def _deserialize_circuit( def _deserialize_schedule( self, schedule_proto: v2.program_pb2.Schedule, - device: Optional[cirq.Device], *, arg_function_language: str, ) -> cirq.Circuit: @@ -517,7 +502,4 @@ def _deserialize_schedule( ) ) ret = cirq.Circuit(result) - if device is None: - device = cirq.UNCONSTRAINED_DEVICE - ret._device = device return ret diff --git a/cirq-google/cirq_google/serialization/serializable_gate_set_test.py b/cirq-google/cirq_google/serialization/serializable_gate_set_test.py index a55a50bbca7..d5e8b896b6e 100644 --- a/cirq-google/cirq_google/serialization/serializable_gate_set_test.py +++ b/cirq-google/cirq_google/serialization/serializable_gate_set_test.py @@ -754,4 +754,4 @@ def test_deserialize_no_operation(): ), ) with pytest.raises(ValueError, match='operation'): - MY_GATE_SET.deserialize(proto, cg.Bristlecone) + MY_GATE_SET.deserialize(proto) diff --git a/cirq-google/cirq_google/serialization/serializer.py b/cirq-google/cirq_google/serialization/serializer.py index d25d2879cc3..12beccf8af4 100644 --- a/cirq-google/cirq_google/serialization/serializer.py +++ b/cirq-google/cirq_google/serialization/serializer.py @@ -48,17 +48,12 @@ def serialize( `Program.Language`. """ - def deserialize( - self, proto: v2.program_pb2.Program, device: Optional[cirq.Device] = None - ) -> cirq.Circuit: + def deserialize(self, proto: v2.program_pb2.Program) -> cirq.Circuit: """Deserialize a Circuit from a cirq_google.api.v2.Program. Args: proto: A dictionary representing a cirq_google.api.v2.Program proto. - device: If the proto is for a schedule, a device is required - Otherwise optional. Returns: - The deserialized Circuit, with a device if device was - not None. + The deserialized Circuit. """ diff --git a/cirq-pasqal/cirq_pasqal/pasqal_device_test.py b/cirq-pasqal/cirq_pasqal/pasqal_device_test.py index 6b97289fa2d..902cbc937c9 100644 --- a/cirq-pasqal/cirq_pasqal/pasqal_device_test.py +++ b/cirq-pasqal/cirq_pasqal/pasqal_device_test.py @@ -77,29 +77,6 @@ def test_init_errors(): square_virtual_device(control_r=11.0, num_qubits=2) -def test_decompose_error_deprecated(): - d = generic_device(2) - op = (cirq.ops.CZ).on(*(d.qubit_list())) - with cirq.testing.assert_deprecated('decompose', deadline='v0.15'): - assert d.decompose_operation(op) == [op] - - op = op ** sympy.Symbol('exp') - with pytest.raises(TypeError, match="Don't know how to work with "): - with cirq.testing.assert_deprecated('decompose', deadline='v0.15'): - d.decompose_operation(op) - - # MeasurementGate is not a GateOperation - with pytest.raises(TypeError): - with cirq.testing.assert_deprecated('decompose', deadline='v0.15'): - d.decompose_operation(cirq.ops.MeasurementGate(num_qubits=2, key='a')) - # It has to be made into one - assert d.is_pasqal_device_op( - cirq.ops.GateOperation( - cirq.ops.MeasurementGate(2, 'b'), [cirq.NamedQubit('q0'), cirq.NamedQubit('q1')] - ) - ) - - def test_is_pasqal_device_op(): d = generic_device(2) @@ -129,7 +106,7 @@ def test_is_pasqal_device_op(): def test_decompose_operation_deprecated(): d = generic_device(3) with cirq.testing.assert_deprecated('decompose', deadline='v0.15'): - for op in d.decompose_operation((cirq.CCZ ** 1.5).on(*(d.qubit_list()))): + for op in d.decompose_operation((cirq.CCZ**1.5).on(*(d.qubit_list()))): d.validate_operation(op) p_qubits = [cirq.LineQubit(3), cirq.LineQubit(4)] @@ -171,7 +148,7 @@ def test_validate_operation_errors(): d.validate_operation(cirq.NamedQubit('q0')) with pytest.raises(ValueError, match="is not a supported gate"): - d.validate_operation((cirq.ops.H ** 0.2).on(cirq.NamedQubit('q0'))) + d.validate_operation((cirq.ops.H**0.2).on(cirq.NamedQubit('q0'))) with pytest.raises(ValueError, match="is not a valid qubit for gate cirq.X"): d.validate_operation(cirq.X.on(cirq.LineQubit(0))) @@ -184,17 +161,6 @@ def test_validate_operation_errors(): d.validate_operation(cirq.CZ.on(TwoDQubit(0, 0), TwoDQubit(2, 2))) -def test_validate_operation_errors_deprecated(): - d = generic_device(3) - circuit = cirq.Circuit() - circuit._device = d - with pytest.raises( - NotImplementedError, match="Measurements on Pasqal devices don't support invert_mask." - ): - with cirq.testing.assert_deprecated('insert', deadline='v0.15'): - circuit.append(cirq.measure(*d.qubits, invert_mask=(True, False, False))) - - def test_qubit_set_deprecated(): d = generic_device(3) with cirq.testing.assert_deprecated('qubit_set', deadline='v0.15'): diff --git a/cirq-pasqal/cirq_pasqal/pasqal_sampler.py b/cirq-pasqal/cirq_pasqal/pasqal_sampler.py index 2027a043057..4d0a331e785 100644 --- a/cirq-pasqal/cirq_pasqal/pasqal_sampler.py +++ b/cirq-pasqal/cirq_pasqal/pasqal_sampler.py @@ -105,20 +105,6 @@ def _send_serialized_circuit( return result - @cirq._compat.deprecated_parameter( - deadline='v0.15', - fix='The program.device component is going away.' - 'Attaching a device to PasqalSampler is now done in __init__.', - parameter_desc='program', - match=lambda args, kwargs: ( - len(args) >= 2 - and isinstance(args[1], cirq.AbstractCircuit) - and args[1]._device != cirq.UNCONSTRAINED_DEVICE - ) - or 'program' in kwargs - and isinstance(kwargs['program'], cirq.AbstractCircuit) - and kwargs['program']._device != cirq.UNCONSTRAINED_DEVICE, - ) def run_sweep( self, program: cirq.AbstractCircuit, params: cirq.study.Sweepable, repetitions: int = 1 ) -> List[cirq.study.Result]: @@ -133,7 +119,7 @@ def run_sweep( Result list for this run; one for each possible parameter resolver. """ - device = program._device if program._device != cirq.UNCONSTRAINED_DEVICE else self._device + device = self._device assert isinstance( device, cirq_pasqal.PasqalDevice ), "Device must inherit from cirq.PasqalDevice." diff --git a/cirq-pasqal/cirq_pasqal/pasqal_sampler_test.py b/cirq-pasqal/cirq_pasqal/pasqal_sampler_test.py index be35d2abcfd..65d2f606127 100644 --- a/cirq-pasqal/cirq_pasqal/pasqal_sampler_test.py +++ b/cirq-pasqal/cirq_pasqal/pasqal_sampler_test.py @@ -71,7 +71,7 @@ def test_run_sweep(mock_post, mock_get): par = sympy.Symbol('par') sweep = cirq.Linspace(key='par', start=0.0, stop=1.0, length=2) - num = np.random.randint(0, 2 ** 9) + num = np.random.randint(0, 2**9) binary = bin(num)[2:].zfill(9) device = cirq_pasqal.PasqalVirtualDevice(control_radius=1, qubits=qs) @@ -103,42 +103,3 @@ def test_run_sweep(mock_post, mock_get): assert cirq.read_json(json_text=submitted_json) == ex_circuit_odd assert mock_post.call_count == 2 assert data[1] == ex_circuit_odd - - -@patch('cirq_pasqal.pasqal_sampler.requests.get') -@patch('cirq_pasqal.pasqal_sampler.requests.post') -def test_run_sweep_device_deprecated(mock_post, mock_get): - """Test running a sweep. - - Encodes a random binary number in the qubits, sweeps between odd and even - without noise and checks if the results match. - """ - - qs = [cirq_pasqal.ThreeDQubit(i, j, 0) for i in range(3) for j in range(3)] - - par = sympy.Symbol('par') - sweep = cirq.Linspace(key='par', start=0.0, stop=1.0, length=2) - - num = np.random.randint(0, 2 ** 9) - binary = bin(num)[2:].zfill(9) - - device = cirq_pasqal.PasqalVirtualDevice(control_radius=1, qubits=qs) - ex_circuit = cirq.Circuit() - - for i, b in enumerate(binary[:-1]): - if b == '1': - ex_circuit.append(cirq.X(qs[-i - 1]), strategy=cirq.InsertStrategy.NEW) - - ex_circuit_odd = copy.deepcopy(ex_circuit) - ex_circuit_odd.append(cirq.X(qs[0]), strategy=cirq.InsertStrategy.NEW) - ex_circuit_odd.append(cirq.measure(*qs), strategy=cirq.InsertStrategy.NEW) - - xpow = cirq.XPowGate(exponent=par) - ex_circuit.append([xpow(qs[0])], strategy=cirq.InsertStrategy.NEW) - ex_circuit.append(cirq.measure(*qs), strategy=cirq.InsertStrategy.NEW) - - mock_get.return_value = MockGet(cirq.to_json(ex_circuit_odd)) - sampler = _make_sampler(device) - ex_circuit._device = device - with cirq.testing.assert_deprecated('The program.device component', deadline='v0.15'): - _ = sampler.run_sweep(program=ex_circuit, params=sweep, repetitions=1)