Skip to content

Commit a8c3e5a

Browse files
authored
Deprecate cirq.ConvertToSqrtIswapGates and cirq.MergeInteractionsToSqrtIswap (quantumlib#5040)
1 parent 7c0179d commit a8c3e5a

4 files changed

+92
-24
lines changed

cirq/optimizers/merge_interactions.py

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
import cirq
2727

2828

29+
@_compat.deprecated_class(
30+
deadline='v1.0',
31+
fix='Use cirq.optimize_for_target_gateset and cirq.CompilationTargetGateset instead.',
32+
)
2933
class MergeInteractionsAbc(circuits.PointOptimizer, metaclass=abc.ABCMeta):
3034
"""Combines series of adjacent one- and two-qubit, non-parametrized gates
3135
operating on a pair of qubits."""

cirq/optimizers/merge_interactions_test.py

+24-8
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222

2323
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit):
2424
actual = cirq.Circuit(before)
25-
with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'):
25+
with cirq.testing.assert_deprecated(
26+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
27+
):
2628
opt = cirq.MergeInteractions()
2729
opt.optimize_circuit(actual)
2830

@@ -46,7 +48,9 @@ def assert_optimization_not_broken(circuit):
4648
global phase and rounding error) as the unitary matrix of the optimized
4749
circuit."""
4850
u_before = circuit.unitary()
49-
with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'):
51+
with cirq.testing.assert_deprecated(
52+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
53+
):
5054
cirq.MergeInteractions().optimize_circuit(circuit)
5155
u_after = circuit.unitary()
5256

@@ -161,7 +165,9 @@ def test_optimizes_single_iswap():
161165
a, b = cirq.LineQubit.range(2)
162166
c = cirq.Circuit(cirq.ISWAP(a, b))
163167
assert_optimization_not_broken(c)
164-
with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'):
168+
with cirq.testing.assert_deprecated(
169+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
170+
):
165171
cirq.MergeInteractions().optimize_circuit(c)
166172
assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2
167173

@@ -170,7 +176,9 @@ def test_optimizes_tagged_partial_cz():
170176
a, b = cirq.LineQubit.range(2)
171177
c = cirq.Circuit((cirq.CZ ** 0.5)(a, b).with_tags('mytag'))
172178
assert_optimization_not_broken(c)
173-
with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'):
179+
with cirq.testing.assert_deprecated(
180+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
181+
):
174182
cirq.MergeInteractions(allow_partial_czs=False).optimize_circuit(c)
175183
assert (
176184
len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2
@@ -182,7 +190,9 @@ def test_not_decompose_czs():
182190
cirq.CZPowGate(exponent=1, global_shift=-0.5).on(*cirq.LineQubit.range(2))
183191
)
184192
circ_orig = circuit.copy()
185-
with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'):
193+
with cirq.testing.assert_deprecated(
194+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
195+
):
186196
cirq.MergeInteractions(allow_partial_czs=False).optimize_circuit(circuit)
187197
assert circ_orig == circuit
188198

@@ -200,7 +210,9 @@ def test_not_decompose_czs():
200210
),
201211
)
202212
def test_decompose_partial_czs(circuit):
203-
with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'):
213+
with cirq.testing.assert_deprecated(
214+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
215+
):
204216
optimizer = cirq.MergeInteractions(allow_partial_czs=False)
205217
optimizer.optimize_circuit(circuit)
206218

@@ -219,7 +231,9 @@ def test_not_decompose_partial_czs():
219231
circuit = cirq.Circuit(
220232
cirq.CZPowGate(exponent=0.1, global_shift=-0.5)(*cirq.LineQubit.range(2)),
221233
)
222-
with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'):
234+
with cirq.testing.assert_deprecated(
235+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
236+
):
223237
optimizer = cirq.MergeInteractions(allow_partial_czs=True)
224238
optimizer.optimize_circuit(circuit)
225239

@@ -253,7 +267,9 @@ def clean_up(operations):
253267
yield operations
254268
yield Marker()(a, b)
255269

256-
with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'):
270+
with cirq.testing.assert_deprecated(
271+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
272+
):
257273
optimizer = cirq.MergeInteractions(allow_partial_czs=False, post_clean_up=clean_up)
258274
optimizer.optimize_circuit(circuit)
259275
circuit = cirq.drop_empty_moments(circuit)

cirq/optimizers/merge_interactions_to_sqrt_iswap.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@
1919

2020
import numpy as np
2121

22-
from cirq import ops
22+
from cirq import ops, _compat
2323
from cirq.optimizers import merge_interactions
2424
from cirq.transformers.analytical_decompositions import two_qubit_to_sqrt_iswap
2525

2626
if TYPE_CHECKING:
2727
import cirq
2828

2929

30+
@_compat.deprecated_class(
31+
deadline='v1.0',
32+
fix='Use cirq.optimize_for_target_gateset and cirq.SqrtIswapTargetGateset instead.',
33+
)
3034
class MergeInteractionsToSqrtIswap(merge_interactions.MergeInteractionsAbc):
3135
"""Combines series of adjacent one- and two-qubit, non-parametrized gates
3236
operating on a pair of qubits and replaces each series with the minimum

cirq/optimizers/merge_interactions_to_sqrt_iswap_test.py

+59-15
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit, **kwargs):
3333
``MergeInteractionsToSqrtIswap`` constructor.
3434
"""
3535
actual = before.copy()
36-
opt = cirq.MergeInteractionsToSqrtIswap(**kwargs)
37-
opt.optimize_circuit(actual)
36+
with cirq.testing.assert_deprecated(
37+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
38+
):
39+
opt = cirq.MergeInteractionsToSqrtIswap(**kwargs)
40+
opt.optimize_circuit(actual)
3841

3942
# Ignore differences that would be caught by follow-up optimizations.
4043
followup_transformers: List[cirq.TRANSFORMER] = [
@@ -57,15 +60,23 @@ def assert_optimization_not_broken(circuit: cirq.Circuit, **kwargs):
5760
circuit."""
5861
u_before = circuit.unitary(sorted(circuit.all_qubits()))
5962
c_sqrt_iswap = circuit.copy()
60-
cirq.MergeInteractionsToSqrtIswap(**kwargs).optimize_circuit(c_sqrt_iswap)
63+
with cirq.testing.assert_deprecated(
64+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
65+
):
66+
cirq.MergeInteractionsToSqrtIswap(**kwargs).optimize_circuit(c_sqrt_iswap)
6167
u_after = c_sqrt_iswap.unitary(sorted(circuit.all_qubits()))
6268

6369
# Not 1e-8 because of some unaccounted accumulated error in some of Cirq's linalg functions
6470
cirq.testing.assert_allclose_up_to_global_phase(u_before, u_after, atol=1e-6)
6571

6672
# Also test optimization with SQRT_ISWAP_INV
6773
c_sqrt_iswap_inv = circuit.copy()
68-
cirq.MergeInteractionsToSqrtIswap(use_sqrt_iswap_inv=True).optimize_circuit(c_sqrt_iswap_inv)
74+
with cirq.testing.assert_deprecated(
75+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
76+
):
77+
cirq.MergeInteractionsToSqrtIswap(use_sqrt_iswap_inv=True).optimize_circuit(
78+
c_sqrt_iswap_inv
79+
)
6980
u_after2 = c_sqrt_iswap_inv.unitary(sorted(circuit.all_qubits()))
7081

7182
cirq.testing.assert_allclose_up_to_global_phase(u_before, u_after2, atol=1e-6)
@@ -230,79 +241,112 @@ def test_optimizes_single_iswap():
230241
a, b = cirq.LineQubit.range(2)
231242
c = cirq.Circuit(cirq.ISWAP(a, b))
232243
assert_optimization_not_broken(c)
233-
cirq.MergeInteractionsToSqrtIswap().optimize_circuit(c)
244+
with cirq.testing.assert_deprecated(
245+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
246+
):
247+
cirq.MergeInteractionsToSqrtIswap().optimize_circuit(c)
234248
assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2
235249

236250

237251
def test_optimizes_single_inv_sqrt_iswap():
238252
a, b = cirq.LineQubit.range(2)
239253
c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b))
240254
assert_optimization_not_broken(c)
241-
cirq.MergeInteractionsToSqrtIswap().optimize_circuit(c)
255+
with cirq.testing.assert_deprecated(
256+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
257+
):
258+
cirq.MergeInteractionsToSqrtIswap().optimize_circuit(c)
242259
assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 1
243260

244261

245262
def test_init_raises():
246263
with pytest.raises(ValueError, match='must be 0, 1, 2, or 3'):
247-
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=4)
264+
with cirq.testing.assert_deprecated(
265+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
266+
):
267+
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=4)
248268

249269

250270
def test_optimizes_single_iswap_require0():
251271
a, b = cirq.LineQubit.range(2)
252272
c = cirq.Circuit(cirq.CNOT(a, b), cirq.CNOT(a, b)) # Minimum 0 sqrt-iSWAP
253273
assert_optimization_not_broken(c, required_sqrt_iswap_count=0)
254-
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=0).optimize_circuit(c)
274+
with cirq.testing.assert_deprecated(
275+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
276+
):
277+
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=0).optimize_circuit(c)
255278
assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 0
256279

257280

258281
def test_optimizes_single_iswap_require0_raises():
259282
a, b = cirq.LineQubit.range(2)
260283
c = cirq.Circuit(cirq.CNOT(a, b)) # Minimum 2 sqrt-iSWAP
261284
with pytest.raises(ValueError, match='cannot be decomposed into exactly 0 sqrt-iSWAP gates'):
262-
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=0).optimize_circuit(c)
285+
with cirq.testing.assert_deprecated(
286+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
287+
):
288+
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=0).optimize_circuit(c)
263289

264290

265291
def test_optimizes_single_iswap_require1():
266292
a, b = cirq.LineQubit.range(2)
267293
c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) # Minimum 1 sqrt-iSWAP
268294
assert_optimization_not_broken(c, required_sqrt_iswap_count=1)
269-
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=1).optimize_circuit(c)
295+
with cirq.testing.assert_deprecated(
296+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
297+
):
298+
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=1).optimize_circuit(c)
270299
assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 1
271300

272301

273302
def test_optimizes_single_iswap_require1_raises():
274303
a, b = cirq.LineQubit.range(2)
275304
c = cirq.Circuit(cirq.CNOT(a, b)) # Minimum 2 sqrt-iSWAP
276305
with pytest.raises(ValueError, match='cannot be decomposed into exactly 1 sqrt-iSWAP gates'):
277-
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=1).optimize_circuit(c)
306+
with cirq.testing.assert_deprecated(
307+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
308+
):
309+
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=1).optimize_circuit(c)
278310

279311

280312
def test_optimizes_single_iswap_require2():
281313
a, b = cirq.LineQubit.range(2)
282314
c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b)) # Minimum 1 sqrt-iSWAP but 2 possible
283315
assert_optimization_not_broken(c, required_sqrt_iswap_count=2)
284-
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=2).optimize_circuit(c)
316+
with cirq.testing.assert_deprecated(
317+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
318+
):
319+
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=2).optimize_circuit(c)
285320
assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2
286321

287322

288323
def test_optimizes_single_iswap_require2_raises():
289324
a, b = cirq.LineQubit.range(2)
290325
c = cirq.Circuit(cirq.SWAP(a, b)) # Minimum 3 sqrt-iSWAP
291326
with pytest.raises(ValueError, match='cannot be decomposed into exactly 2 sqrt-iSWAP gates'):
292-
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=2).optimize_circuit(c)
327+
with cirq.testing.assert_deprecated(
328+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
329+
):
330+
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=2).optimize_circuit(c)
293331

294332

295333
def test_optimizes_single_iswap_require3():
296334
a, b = cirq.LineQubit.range(2)
297335
c = cirq.Circuit(cirq.ISWAP(a, b)) # Minimum 2 sqrt-iSWAP but 3 possible
298336
assert_optimization_not_broken(c, required_sqrt_iswap_count=3)
299-
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=3).optimize_circuit(c)
337+
with cirq.testing.assert_deprecated(
338+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
339+
):
340+
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=3).optimize_circuit(c)
300341
assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 3
301342

302343

303344
def test_optimizes_single_inv_sqrt_iswap_require3():
304345
a, b = cirq.LineQubit.range(2)
305346
c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b))
306347
assert_optimization_not_broken(c, required_sqrt_iswap_count=3)
307-
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=3).optimize_circuit(c)
348+
with cirq.testing.assert_deprecated(
349+
"Use cirq.optimize_for_target_gateset", deadline='v1.0', count=2
350+
):
351+
cirq.MergeInteractionsToSqrtIswap(required_sqrt_iswap_count=3).optimize_circuit(c)
308352
assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 3

0 commit comments

Comments
 (0)