diff --git a/cirq-core/cirq/circuits/circuit.py b/cirq-core/cirq/circuits/circuit.py index d8ca53cf7f7..c2c2e2d1257 100644 --- a/cirq-core/cirq/circuits/circuit.py +++ b/cirq-core/cirq/circuits/circuit.py @@ -2015,6 +2015,10 @@ def _pick_or_create_inserted_op_moment_index( 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]) def insert( @@ -2102,19 +2106,28 @@ def insert_into_range(self, operations: 'cirq.OP_TREE', start: int, end: int) -> i = start op_index = 0 - while op_index < len(flat_ops): - op = flat_ops[op_index] - while i < end and not self._device.can_add_operation_into_moment(op, self._moments[i]): - i += 1 - if i >= end: - break - self._moments[i] = self._moments[i].with_operation(op) - op_index += 1 - - if op_index >= len(flat_ops): - return end - - return self.insert(end, flat_ops[op_index:]) + 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'): + 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 + self._moments[i] = self._moments[i].with_operation(op) + op_index += 1 + + if op_index >= len(flat_ops): + return end + + return self.insert(end, flat_ops[op_index:]) def _push_frontier( self, diff --git a/cirq-core/cirq/circuits/circuit_test.py b/cirq-core/cirq/circuits/circuit_test.py index 6739cc05836..132027b7347 100644 --- a/cirq-core/cirq/circuits/circuit_test.py +++ b/cirq-core/cirq/circuits/circuit_test.py @@ -1176,6 +1176,14 @@ 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') diff --git a/cirq-core/cirq/devices/device.py b/cirq-core/cirq/devices/device.py index 15a6e13ac04..953ec546bdb 100644 --- a/cirq-core/cirq/devices/device.py +++ b/cirq-core/cirq/devices/device.py @@ -152,6 +152,11 @@ def validate_moment(self, moment: 'cirq.Moment') -> None: for operation in moment.operations: self.validate_operation(operation) + @_compat.deprecated( + deadline='v0.15', + fix='can_add_operation_into_moment will be removed in the future.' + ' Consider using device.validate_circuit instead.', + ) def can_add_operation_into_moment( self, operation: 'cirq.Operation', moment: 'cirq.Moment' ) -> bool: diff --git a/cirq-core/cirq/ion/ion_device_test.py b/cirq-core/cirq/ion/ion_device_test.py index 14f853965b7..3c55dd8aa57 100644 --- a/cirq-core/cirq/ion/ion_device_test.py +++ b/cirq-core/cirq/ion/ion_device_test.py @@ -156,21 +156,22 @@ def num_qubits(self): d.validate_operation(NotImplementedOperation()) -def test_can_add_operation_into_moment(): - d = ion_device(3) - q0 = cirq.LineQubit(0) - q1 = cirq.LineQubit(1) - q2 = cirq.LineQubit(2) - q3 = cirq.LineQubit(3) - circuit = cirq.Circuit() - circuit.append(cirq.XX(q0, q1)) - for moment in circuit: - assert not d.can_add_operation_into_moment(cirq.XX(q2, q0), moment) - assert not d.can_add_operation_into_moment(cirq.XX(q1, q2), moment) - assert d.can_add_operation_into_moment(cirq.XX(q2, q3), moment) - assert d.can_add_operation_into_moment(cirq.Z(q3), moment) - circuit = cirq.Circuit([cirq.X(q0)]) - assert d.can_add_operation_into_moment(cirq.XX(q1, q2), circuit[0]) +def test_can_add_operation_into_moment_device_deprecated(): + with cirq.testing.assert_deprecated('can_add_operation_into_moment', deadline='v0.15', count=5): + d = ion_device(3) + q0 = cirq.LineQubit(0) + q1 = cirq.LineQubit(1) + q2 = cirq.LineQubit(2) + q3 = cirq.LineQubit(3) + circuit = cirq.Circuit() + circuit.append(cirq.XX(q0, q1)) + for moment in circuit: + assert not d.can_add_operation_into_moment(cirq.XX(q2, q0), moment) + assert not d.can_add_operation_into_moment(cirq.XX(q1, q2), moment) + assert d.can_add_operation_into_moment(cirq.XX(q2, q3), moment) + assert d.can_add_operation_into_moment(cirq.Z(q3), moment) + circuit = cirq.Circuit([cirq.X(q0)]) + assert d.can_add_operation_into_moment(cirq.XX(q1, q2), circuit[0]) def test_ion_device_eq(): diff --git a/cirq-core/cirq/neutral_atoms/neutral_atom_devices_test.py b/cirq-core/cirq/neutral_atoms/neutral_atom_devices_test.py index 74cb65809a6..42b4f6c9746 100644 --- a/cirq-core/cirq/neutral_atoms/neutral_atom_devices_test.py +++ b/cirq-core/cirq/neutral_atoms/neutral_atom_devices_test.py @@ -220,15 +220,16 @@ def test_validate_moment_errors(): d2.validate_moment(m) -def test_can_add_operation_into_moment_coverage(): - d = square_device(2, 2) - q00 = cirq.GridQubit(0, 0) - q01 = cirq.GridQubit(0, 1) - q10 = cirq.GridQubit(1, 0) - m = cirq.Moment([cirq.X.on(q00)]) - assert not d.can_add_operation_into_moment(cirq.X.on(q00), m) - assert not d.can_add_operation_into_moment(cirq.CZ.on(q01, q10), m) - assert d.can_add_operation_into_moment(cirq.Z.on(q01), m) +def test_can_add_operation_into_moment_coverage_deprecated(): + with cirq.testing.assert_deprecated('can_add_operation_into_moment', deadline='v0.15', count=3): + d = square_device(2, 2) + q00 = cirq.GridQubit(0, 0) + q01 = cirq.GridQubit(0, 1) + q10 = cirq.GridQubit(1, 0) + m = cirq.Moment([cirq.X.on(q00)]) + assert not d.can_add_operation_into_moment(cirq.X.on(q00), m) + assert not d.can_add_operation_into_moment(cirq.CZ.on(q01, q10), m) + assert d.can_add_operation_into_moment(cirq.Z.on(q01), m) def test_validate_circuit_errors(): diff --git a/cirq-pasqal/cirq_pasqal/pasqal_device_test.py b/cirq-pasqal/cirq_pasqal/pasqal_device_test.py index 9aad1ba1197..f72c18be1f3 100644 --- a/cirq-pasqal/cirq_pasqal/pasqal_device_test.py +++ b/cirq-pasqal/cirq_pasqal/pasqal_device_test.py @@ -215,13 +215,14 @@ def test_validate_circuit(): d.validate_circuit(circuit1) -def test_can_add_operation_into_moment(): +def test_can_add_operation_into_moment_deprecated(): d = square_virtual_device(control_r=1.0, num_qubits=2) - m1 = cirq.Moment([cirq.Z.on(TwoDQubit(0, 0))]) - assert not d.can_add_operation_into_moment(cirq.X.on(TwoDQubit(0, 0)), m1) - assert not d.can_add_operation_into_moment(cirq.X.on(TwoDQubit(1, 1)), m1) - m2 = cirq.Moment([cirq.measure(*d.qubits[:-1])]) - assert d.can_add_operation_into_moment(cirq.measure(TwoDQubit(1, 1)), m2) + with cirq.testing.assert_deprecated('can_add_operation_into_moment', deadline='v0.15', count=3): + m1 = cirq.Moment([cirq.Z.on(TwoDQubit(0, 0))]) + assert not d.can_add_operation_into_moment(cirq.X.on(TwoDQubit(0, 0)), m1) + assert not d.can_add_operation_into_moment(cirq.X.on(TwoDQubit(1, 1)), m1) + m2 = cirq.Moment([cirq.measure(*d.qubits[:-1])]) + assert d.can_add_operation_into_moment(cirq.measure(TwoDQubit(1, 1)), m2) def test_minimal_distance():