From a8c3e5afd70d8b96e452c983dfbaf2a9bf3b7d88 Mon Sep 17 00:00:00 2001 From: Tanuj Khattar Date: Tue, 1 Mar 2022 00:47:15 +0530 Subject: [PATCH] Deprecate cirq.ConvertToSqrtIswapGates and cirq.MergeInteractionsToSqrtIswap (#5040) --- cirq/optimizers/merge_interactions.py | 4 + cirq/optimizers/merge_interactions_test.py | 32 ++++++-- .../merge_interactions_to_sqrt_iswap.py | 6 +- .../merge_interactions_to_sqrt_iswap_test.py | 74 +++++++++++++++---- 4 files changed, 92 insertions(+), 24 deletions(-) diff --git a/cirq/optimizers/merge_interactions.py b/cirq/optimizers/merge_interactions.py index 37acab314eb..37c567e053f 100644 --- a/cirq/optimizers/merge_interactions.py +++ b/cirq/optimizers/merge_interactions.py @@ -26,6 +26,10 @@ import cirq +@_compat.deprecated_class( + deadline='v1.0', + fix='Use cirq.optimize_for_target_gateset and cirq.CompilationTargetGateset instead.', +) class MergeInteractionsAbc(circuits.PointOptimizer, metaclass=abc.ABCMeta): """Combines series of adjacent one- and two-qubit, non-parametrized gates operating on a pair of qubits.""" diff --git a/cirq/optimizers/merge_interactions_test.py b/cirq/optimizers/merge_interactions_test.py index 2c0db675a15..d508c50a5fd 100644 --- a/cirq/optimizers/merge_interactions_test.py +++ b/cirq/optimizers/merge_interactions_test.py @@ -22,7 +22,9 @@ def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit): actual = cirq.Circuit(before) - with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): opt = cirq.MergeInteractions() opt.optimize_circuit(actual) @@ -46,7 +48,9 @@ def assert_optimization_not_broken(circuit): global phase and rounding error) as the unitary matrix of the optimized circuit.""" u_before = circuit.unitary() - with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): cirq.MergeInteractions().optimize_circuit(circuit) u_after = circuit.unitary() @@ -161,7 +165,9 @@ def test_optimizes_single_iswap(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.ISWAP(a, b)) assert_optimization_not_broken(c) - with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): cirq.MergeInteractions().optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2 @@ -170,7 +176,9 @@ def test_optimizes_tagged_partial_cz(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit((cirq.CZ ** 0.5)(a, b).with_tags('mytag')) assert_optimization_not_broken(c) - with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): cirq.MergeInteractions(allow_partial_czs=False).optimize_circuit(c) assert ( len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2 @@ -182,7 +190,9 @@ def test_not_decompose_czs(): cirq.CZPowGate(exponent=1, global_shift=-0.5).on(*cirq.LineQubit.range(2)) ) circ_orig = circuit.copy() - with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): cirq.MergeInteractions(allow_partial_czs=False).optimize_circuit(circuit) assert circ_orig == circuit @@ -200,7 +210,9 @@ def test_not_decompose_czs(): ), ) def test_decompose_partial_czs(circuit): - with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): optimizer = cirq.MergeInteractions(allow_partial_czs=False) optimizer.optimize_circuit(circuit) @@ -219,7 +231,9 @@ def test_not_decompose_partial_czs(): circuit = cirq.Circuit( cirq.CZPowGate(exponent=0.1, global_shift=-0.5)(*cirq.LineQubit.range(2)), ) - with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): optimizer = cirq.MergeInteractions(allow_partial_czs=True) optimizer.optimize_circuit(circuit) @@ -253,7 +267,9 @@ def clean_up(operations): yield operations yield Marker()(a, b) - with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): optimizer = cirq.MergeInteractions(allow_partial_czs=False, post_clean_up=clean_up) optimizer.optimize_circuit(circuit) circuit = cirq.drop_empty_moments(circuit) diff --git a/cirq/optimizers/merge_interactions_to_sqrt_iswap.py b/cirq/optimizers/merge_interactions_to_sqrt_iswap.py index 06213b1a121..f58d5ec21e8 100644 --- a/cirq/optimizers/merge_interactions_to_sqrt_iswap.py +++ b/cirq/optimizers/merge_interactions_to_sqrt_iswap.py @@ -19,7 +19,7 @@ import numpy as np -from cirq import ops +from cirq import ops, _compat from cirq.optimizers import merge_interactions from cirq.transformers.analytical_decompositions import two_qubit_to_sqrt_iswap @@ -27,6 +27,10 @@ import cirq +@_compat.deprecated_class( + deadline='v1.0', + fix='Use cirq.optimize_for_target_gateset and cirq.SqrtIswapTargetGateset instead.', +) class MergeInteractionsToSqrtIswap(merge_interactions.MergeInteractionsAbc): """Combines series of adjacent one- and two-qubit, non-parametrized gates operating on a pair of qubits and replaces each series with the minimum diff --git a/cirq/optimizers/merge_interactions_to_sqrt_iswap_test.py b/cirq/optimizers/merge_interactions_to_sqrt_iswap_test.py index 1e6316553c7..26e2f7b60b8 100644 --- a/cirq/optimizers/merge_interactions_to_sqrt_iswap_test.py +++ b/cirq/optimizers/merge_interactions_to_sqrt_iswap_test.py @@ -33,8 +33,11 @@ def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit, **kwargs): ``MergeInteractionsToSqrtIswap`` constructor. """ actual = before.copy() - opt = cirq.MergeInteractionsToSqrtIswap(**kwargs) - opt.optimize_circuit(actual) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + opt = cirq.MergeInteractionsToSqrtIswap(**kwargs) + opt.optimize_circuit(actual) # Ignore differences that would be caught by follow-up optimizations. followup_transformers: List[cirq.TRANSFORMER] = [ @@ -57,7 +60,10 @@ def assert_optimization_not_broken(circuit: cirq.Circuit, **kwargs): circuit.""" u_before = circuit.unitary(sorted(circuit.all_qubits())) c_sqrt_iswap = circuit.copy() - cirq.MergeInteractionsToSqrtIswap(**kwargs).optimize_circuit(c_sqrt_iswap) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(**kwargs).optimize_circuit(c_sqrt_iswap) u_after = c_sqrt_iswap.unitary(sorted(circuit.all_qubits())) # Not 1e-8 because of some unaccounted accumulated error in some of Cirq's linalg functions @@ -65,7 +71,12 @@ def assert_optimization_not_broken(circuit: cirq.Circuit, **kwargs): # Also test optimization with SQRT_ISWAP_INV c_sqrt_iswap_inv = circuit.copy() - cirq.MergeInteractionsToSqrtIswap(use_sqrt_iswap_inv=True).optimize_circuit(c_sqrt_iswap_inv) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(use_sqrt_iswap_inv=True).optimize_circuit( + c_sqrt_iswap_inv + ) u_after2 = c_sqrt_iswap_inv.unitary(sorted(circuit.all_qubits())) cirq.testing.assert_allclose_up_to_global_phase(u_before, u_after2, atol=1e-6) @@ -230,7 +241,10 @@ def test_optimizes_single_iswap(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.ISWAP(a, b)) assert_optimization_not_broken(c) - cirq.MergeInteractionsToSqrtIswap().optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap().optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2 @@ -238,20 +252,29 @@ def test_optimizes_single_inv_sqrt_iswap(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) assert_optimization_not_broken(c) - cirq.MergeInteractionsToSqrtIswap().optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap().optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 1 def test_init_raises(): with pytest.raises(ValueError, match='must be 0, 1, 2, or 3'): - cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=4) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=4) def test_optimizes_single_iswap_require0(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.CNOT(a, b), cirq.CNOT(a, b)) # Minimum 0 sqrt-iSWAP assert_optimization_not_broken(c, required_sqrt_iswap_count=0) - cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=0).optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=0).optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 0 @@ -259,14 +282,20 @@ def test_optimizes_single_iswap_require0_raises(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.CNOT(a, b)) # Minimum 2 sqrt-iSWAP with pytest.raises(ValueError, match='cannot be decomposed into exactly 0 sqrt-iSWAP gates'): - cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=0).optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=0).optimize_circuit(c) def test_optimizes_single_iswap_require1(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) # Minimum 1 sqrt-iSWAP assert_optimization_not_broken(c, required_sqrt_iswap_count=1) - cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=1).optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=1).optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 1 @@ -274,14 +303,20 @@ def test_optimizes_single_iswap_require1_raises(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.CNOT(a, b)) # Minimum 2 sqrt-iSWAP with pytest.raises(ValueError, match='cannot be decomposed into exactly 1 sqrt-iSWAP gates'): - cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=1).optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=1).optimize_circuit(c) def test_optimizes_single_iswap_require2(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) # Minimum 1 sqrt-iSWAP but 2 possible assert_optimization_not_broken(c, required_sqrt_iswap_count=2) - cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=2).optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=2).optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2 @@ -289,14 +324,20 @@ def test_optimizes_single_iswap_require2_raises(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.SWAP(a, b)) # Minimum 3 sqrt-iSWAP with pytest.raises(ValueError, match='cannot be decomposed into exactly 2 sqrt-iSWAP gates'): - cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=2).optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=2).optimize_circuit(c) def test_optimizes_single_iswap_require3(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.ISWAP(a, b)) # Minimum 2 sqrt-iSWAP but 3 possible assert_optimization_not_broken(c, required_sqrt_iswap_count=3) - cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=3).optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=3).optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 3 @@ -304,5 +345,8 @@ def test_optimizes_single_inv_sqrt_iswap_require3(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) assert_optimization_not_broken(c, required_sqrt_iswap_count=3) - cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=3).optimize_circuit(c) + with cirq.testing.assert_deprecated( + "Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2 + ): + cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=3).optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 3