Skip to content

Commit 3c6a305

Browse files
authored
Deprecate Cirq-FT module in favour of Qualtran (#6362)
* Deprecate Cirq-FT module in favour of Qualtran * Fix failing tests, lint and add coverage ignores * Address comments
1 parent cf973a5 commit 3c6a305

31 files changed

+233
-47
lines changed

cirq-ft/cirq_ft/algos/and_gate_test.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
import itertools
1616
import random
17-
import sys
1817
from typing import List, Tuple
1918

2019
import cirq
@@ -23,11 +22,13 @@
2322
import pytest
2423
from cirq_ft import infra
2524
from cirq_ft.infra.jupyter_tools import execute_notebook
25+
from cirq_ft.deprecation import allow_deprecated_cirq_ft_use_in_tests
2626

2727
random.seed(12345)
2828

2929

3030
@pytest.mark.parametrize("cv", [(0, 0), (0, 1), (1, 0), (1, 1)])
31+
@allow_deprecated_cirq_ft_use_in_tests
3132
def test_and_gate(cv: Tuple[int, int]):
3233
c1, c2, t = cirq.LineQubit.range(3)
3334
input_states = [(0, 0, 0), (0, 1, 0), (1, 0, 0), (1, 1, 0)]
@@ -44,6 +45,7 @@ def random_cv(n: int) -> List[int]:
4445

4546

4647
@pytest.mark.parametrize("cv", [[1] * 3, random_cv(5), random_cv(6), random_cv(7)])
48+
@allow_deprecated_cirq_ft_use_in_tests
4749
def test_multi_controlled_and_gate(cv: List[int]):
4850
gate = cirq_ft.And(cv)
4951
r = gate.signature
@@ -77,6 +79,7 @@ def test_multi_controlled_and_gate(cv: List[int]):
7779
)
7880

7981

82+
@allow_deprecated_cirq_ft_use_in_tests
8083
def test_and_gate_diagram():
8184
gate = cirq_ft.And((1, 0, 1, 0, 1, 0))
8285
qubit_regs = infra.get_named_qubits(gate.signature)
@@ -186,13 +189,15 @@ def test_and_gate_diagram():
186189
((1, 0, 1), True, "And†(1, 0, 1)"),
187190
],
188191
)
192+
@allow_deprecated_cirq_ft_use_in_tests
189193
def test_and_gate_str_and_repr(cv, adjoint, str_output):
190194
gate = cirq_ft.And(cv, adjoint=adjoint)
191195
assert str(gate) == str_output
192196
cirq.testing.assert_equivalent_repr(gate, setup_code="import cirq_ft\n")
193197

194198

195199
@pytest.mark.parametrize("cv", [(0, 0), (0, 1), (1, 0), (1, 1)])
200+
@allow_deprecated_cirq_ft_use_in_tests
196201
def test_and_gate_adjoint(cv: Tuple[int, int]):
197202
c1, c2, t = cirq.LineQubit.range(3)
198203
all_cvs = [(0, 0), (0, 1), (1, 0), (1, 1)]
@@ -204,7 +209,7 @@ def test_and_gate_adjoint(cv: Tuple[int, int]):
204209
cirq_ft.testing.assert_circuit_inp_out_cirqsim(circuit, [c1, c2, t], inp, out)
205210

206211

207-
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
212+
@pytest.mark.skip(reason="Cirq-FT is deprecated, use Qualtran instead.")
208213
def test_notebook():
209214
execute_notebook('and_gate')
210215

@@ -213,16 +218,19 @@ def test_notebook():
213218
"cv", [*itertools.chain(*[itertools.product(range(2), repeat=n) for n in range(2, 7 + 1)])]
214219
)
215220
@pytest.mark.parametrize("adjoint", [*range(2)])
221+
@allow_deprecated_cirq_ft_use_in_tests
216222
def test_t_complexity(cv, adjoint):
217223
gate = cirq_ft.And(cv=cv, adjoint=adjoint)
218224
cirq_ft.testing.assert_decompose_is_consistent_with_t_complexity(gate)
219225

220226

227+
@allow_deprecated_cirq_ft_use_in_tests
221228
def test_and_gate_raises():
222229
with pytest.raises(ValueError, match="at-least 2 control values"):
223230
_ = cirq_ft.And(cv=(1,))
224231

225232

233+
@allow_deprecated_cirq_ft_use_in_tests
226234
def test_and_gate_power():
227235
cv = (1, 0)
228236
and_gate = cirq_ft.And(cv)

cirq-ft/cirq_ft/algos/apply_gate_to_lth_target.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,13 @@ class ApplyGateToLthQubit(unary_iteration_gate.UnaryIterationGate):
5252
)
5353
nth_gate: Callable[..., cirq.Gate]
5454
control_regs: Tuple[infra.Register, ...] = attr.field(
55-
converter=lambda v: (v,) if isinstance(v, infra.Register) else tuple(v),
56-
default=(infra.Register('control', 1),),
55+
converter=lambda v: (v,) if isinstance(v, infra.Register) else tuple(v)
5756
)
5857

58+
@control_regs.default
59+
def control_regs_default(self):
60+
return (infra.Register('control', 1),)
61+
5962
@classmethod
6063
def make_on(
6164
cls, *, nth_gate: Callable[..., cirq.Gate], **quregs: Sequence[cirq.Qid]

cirq-ft/cirq_ft/algos/apply_gate_to_lth_target_test.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import sys
16-
1715
import cirq
1816
import cirq_ft
1917
import pytest
2018
from cirq_ft import infra
2119
from cirq_ft.infra.bit_tools import iter_bits
2220
from cirq_ft.infra.jupyter_tools import execute_notebook
21+
from cirq_ft.deprecation import allow_deprecated_cirq_ft_use_in_tests
2322

2423

2524
@pytest.mark.parametrize("selection_bitsize,target_bitsize", [[3, 5], [3, 7], [4, 5]])
25+
@allow_deprecated_cirq_ft_use_in_tests
2626
def test_apply_gate_to_lth_qubit(selection_bitsize, target_bitsize):
2727
greedy_mm = cirq.GreedyQubitManager(prefix="_a", maximize_reuse=True)
2828
gate = cirq_ft.ApplyGateToLthQubit(
@@ -51,6 +51,7 @@ def test_apply_gate_to_lth_qubit(selection_bitsize, target_bitsize):
5151
)
5252

5353

54+
@allow_deprecated_cirq_ft_use_in_tests
5455
def test_apply_gate_to_lth_qubit_diagram():
5556
# Apply Z gate to all odd targets and Identity to even targets.
5657
gate = cirq_ft.ApplyGateToLthQubit(
@@ -87,6 +88,7 @@ def test_apply_gate_to_lth_qubit_diagram():
8788
)
8889

8990

91+
@allow_deprecated_cirq_ft_use_in_tests
9092
def test_apply_gate_to_lth_qubit_make_on():
9193
gate = cirq_ft.ApplyGateToLthQubit(
9294
cirq_ft.SelectionRegister('selection', 3, 5),
@@ -103,6 +105,6 @@ def test_apply_gate_to_lth_qubit_make_on():
103105
assert op.gate.control_regs == op2.gate.control_regs
104106

105107

106-
@pytest.mark.skipif(sys.platform != "linux", reason="Linux-only test")
108+
@pytest.mark.skip(reason="Cirq-FT is deprecated, use Qualtran instead.")
107109
def test_notebook():
108110
execute_notebook('apply_gate_to_lth_target')

cirq-ft/cirq_ft/algos/arithmetic_gates.py

+6
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121

2222
from cirq_ft import infra
2323
from cirq_ft.algos import and_gate
24+
from cirq_ft.deprecation import deprecated_cirq_ft_class
2425

2526

27+
@deprecated_cirq_ft_class()
2628
@attr.frozen
2729
class LessThanGate(cirq.ArithmeticGate):
2830
"""Applies U_a|x>|z> = |x> |z ^ (x < a)>"""
@@ -297,6 +299,7 @@ def _equality_with_zero(
297299
yield and_gate.And(cv=[0] * len(qubits)).on(*qubits, *ancilla, z)
298300

299301

302+
@deprecated_cirq_ft_class()
300303
@attr.frozen
301304
class LessThanEqualGate(cirq.ArithmeticGate):
302305
"""Applies U|x>|y>|z> = |x>|y> |z ^ (x <= y)>"""
@@ -454,6 +457,7 @@ def _has_unitary_(self):
454457
return True
455458

456459

460+
@deprecated_cirq_ft_class()
457461
@attr.frozen
458462
class ContiguousRegisterGate(cirq.ArithmeticGate):
459463
"""Applies U|x>|y>|0> -> |x>|y>|x(x-1)/2 + y>
@@ -530,6 +534,7 @@ def __pow__(self, power: int):
530534
return NotImplemented # pragma: no cover
531535

532536

537+
@deprecated_cirq_ft_class()
533538
@attr.frozen
534539
class AdditionGate(cirq.ArithmeticGate):
535540
"""Applies U|p>|q> -> |p>|p+q>.
@@ -613,6 +618,7 @@ def __repr__(self) -> str:
613618
return f'cirq_ft.AdditionGate({self.bitsize})'
614619

615620

621+
@deprecated_cirq_ft_class()
616622
@attr.frozen(auto_attribs=True)
617623
class AddMod(cirq.ArithmeticGate):
618624
"""Applies U_{M}_{add}|x> = |(x + add) % M> if x < M else |x>.

cirq-ft/cirq_ft/algos/arithmetic_gates_test.py

+20
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919
import numpy as np
2020
import pytest
2121
from cirq_ft.infra import bit_tools
22+
from cirq_ft.deprecation import allow_deprecated_cirq_ft_use_in_tests
2223

2324

2425
def identity_map(n: int):
2526
"""Returns a dict of size `2**n` mapping each integer in range [0, 2**n) to itself."""
2627
return {i: i for i in range(2**n)}
2728

2829

30+
@allow_deprecated_cirq_ft_use_in_tests
2931
def test_less_than_gate():
3032
qubits = cirq.LineQubit.range(4)
3133
gate = cirq_ft.LessThanGate(3, 5)
@@ -61,6 +63,7 @@ def test_less_than_gate():
6163

6264
@pytest.mark.parametrize("bits", [*range(8)])
6365
@pytest.mark.parametrize("val", [3, 5, 7, 8, 9])
66+
@allow_deprecated_cirq_ft_use_in_tests
6467
def test_decompose_less_than_gate(bits: int, val: int):
6568
qubit_states = list(bit_tools.iter_bits(bits, 3))
6669
circuit = cirq.Circuit(
@@ -81,6 +84,7 @@ def test_decompose_less_than_gate(bits: int, val: int):
8184

8285
@pytest.mark.parametrize("n", [*range(2, 5)])
8386
@pytest.mark.parametrize("val", [3, 4, 5, 7, 8, 9])
87+
@allow_deprecated_cirq_ft_use_in_tests
8488
def test_less_than_consistent_protocols(n: int, val: int):
8589
g = cirq_ft.LessThanGate(n, val)
8690
cirq_ft.testing.assert_decompose_is_consistent_with_t_complexity(g)
@@ -90,6 +94,7 @@ def test_less_than_consistent_protocols(n: int, val: int):
9094
np.testing.assert_allclose(u @ u, np.eye(2 ** (n + 1)))
9195

9296

97+
@allow_deprecated_cirq_ft_use_in_tests
9398
def test_multi_in_less_equal_than_gate():
9499
qubits = cirq.LineQubit.range(7)
95100
op = cirq_ft.LessThanEqualGate(3, 3).on(*qubits)
@@ -114,6 +119,7 @@ def test_multi_in_less_equal_than_gate():
114119

115120
@pytest.mark.parametrize("x_bitsize", [*range(1, 5)])
116121
@pytest.mark.parametrize("y_bitsize", [*range(1, 5)])
122+
@allow_deprecated_cirq_ft_use_in_tests
117123
def test_less_than_equal_consistent_protocols(x_bitsize: int, y_bitsize: int):
118124
g = cirq_ft.LessThanEqualGate(x_bitsize, y_bitsize)
119125
cirq_ft.testing.assert_decompose_is_consistent_with_t_complexity(g)
@@ -138,6 +144,7 @@ def test_less_than_equal_consistent_protocols(x_bitsize: int, y_bitsize: int):
138144
assert g.with_registers([2] * 4, [2] * 5, [2]) == cirq_ft.LessThanEqualGate(4, 5)
139145

140146

147+
@allow_deprecated_cirq_ft_use_in_tests
141148
def test_contiguous_register_gate():
142149
gate = cirq_ft.ContiguousRegisterGate(3, 6)
143150
circuit = cirq.Circuit(gate.on(*cirq.LineQubit.range(12)))
@@ -163,13 +170,15 @@ def test_contiguous_register_gate():
163170

164171

165172
@pytest.mark.parametrize('n', [*range(1, 10)])
173+
@allow_deprecated_cirq_ft_use_in_tests
166174
def test_contiguous_register_gate_t_complexity(n):
167175
gate = cirq_ft.ContiguousRegisterGate(n, 2 * n)
168176
toffoli_complexity = cirq_ft.t_complexity(cirq.CCNOT)
169177
assert cirq_ft.t_complexity(gate) == (n**2 + n - 1) * toffoli_complexity
170178

171179

172180
@pytest.mark.parametrize('a,b,num_bits', itertools.product(range(4), range(4), range(3, 5)))
181+
@allow_deprecated_cirq_ft_use_in_tests
173182
def test_add(a: int, b: int, num_bits: int):
174183
num_anc = num_bits - 1
175184
gate = cirq_ft.AdditionGate(num_bits)
@@ -199,6 +208,7 @@ def test_add(a: int, b: int, num_bits: int):
199208
@pytest.mark.parametrize('mod', [5, 8])
200209
@pytest.mark.parametrize('add_val', [1, 2])
201210
@pytest.mark.parametrize('cv', [[], [0, 1], [1, 0], [1, 1]])
211+
@allow_deprecated_cirq_ft_use_in_tests
202212
def test_add_mod_n(bitsize, mod, add_val, cv):
203213
gate = cirq_ft.AddMod(bitsize, mod, add_val=add_val, cv=cv)
204214
basis_map = {}
@@ -225,6 +235,7 @@ def test_add_mod_n(bitsize, mod, add_val, cv):
225235
cirq.testing.assert_equivalent_repr(gate, setup_code='import cirq_ft')
226236

227237

238+
@allow_deprecated_cirq_ft_use_in_tests
228239
def test_add_mod_n_protocols():
229240
with pytest.raises(ValueError, match="must be between"):
230241
_ = cirq_ft.AddMod(3, 10)
@@ -238,6 +249,7 @@ def test_add_mod_n_protocols():
238249
assert cirq.circuit_diagram_info(add_two).wire_symbols == ('@', '@(0)') + ('Add_2_Mod_5',) * 3
239250

240251

252+
@allow_deprecated_cirq_ft_use_in_tests
241253
def test_add_truncated():
242254
num_bits = 3
243255
num_anc = num_bits - 1
@@ -286,6 +298,7 @@ def test_add_truncated():
286298

287299

288300
@pytest.mark.parametrize('a,b,num_bits', itertools.product(range(4), range(4), range(3, 5)))
301+
@allow_deprecated_cirq_ft_use_in_tests
289302
def test_subtract(a, b, num_bits):
290303
num_anc = num_bits - 1
291304
gate = cirq_ft.AdditionGate(num_bits)
@@ -309,13 +322,15 @@ def test_subtract(a, b, num_bits):
309322

310323

311324
@pytest.mark.parametrize("n", [*range(3, 10)])
325+
@allow_deprecated_cirq_ft_use_in_tests
312326
def test_addition_gate_t_complexity(n: int):
313327
g = cirq_ft.AdditionGate(n)
314328
cirq_ft.testing.assert_decompose_is_consistent_with_t_complexity(g)
315329
cirq.testing.assert_equivalent_repr(g, setup_code='import cirq_ft')
316330

317331

318332
@pytest.mark.parametrize('a,b', itertools.product(range(2**3), repeat=2))
333+
@allow_deprecated_cirq_ft_use_in_tests
319334
def test_add_no_decompose(a, b):
320335
num_bits = 5
321336
qubits = cirq.LineQubit.range(2 * num_bits)
@@ -335,6 +350,7 @@ def test_add_no_decompose(a, b):
335350

336351
@pytest.mark.parametrize("P,n", [(v, n) for n in range(1, 4) for v in range(1 << n)])
337352
@pytest.mark.parametrize("Q,m", [(v, n) for n in range(1, 4) for v in range(1 << n)])
353+
@allow_deprecated_cirq_ft_use_in_tests
338354
def test_decompose_less_than_equal_gate(P: int, n: int, Q: int, m: int):
339355
qubit_states = list(bit_tools.iter_bits(P, n)) + list(bit_tools.iter_bits(Q, m))
340356
circuit = cirq.Circuit(
@@ -353,6 +369,7 @@ def test_decompose_less_than_equal_gate(P: int, n: int, Q: int, m: int):
353369

354370

355371
@pytest.mark.parametrize("adjoint", [False, True])
372+
@allow_deprecated_cirq_ft_use_in_tests
356373
def test_single_qubit_compare_protocols(adjoint: bool):
357374
g = cirq_ft.algos.SingleQubitCompare(adjoint=adjoint)
358375
cirq_ft.testing.assert_decompose_is_consistent_with_t_complexity(g)
@@ -370,6 +387,7 @@ def test_single_qubit_compare_protocols(adjoint: bool):
370387

371388

372389
@pytest.mark.parametrize("v1,v2", [(v1, v2) for v1 in range(2) for v2 in range(2)])
390+
@allow_deprecated_cirq_ft_use_in_tests
373391
def test_single_qubit_compare(v1: int, v2: int):
374392
g = cirq_ft.algos.SingleQubitCompare()
375393
qubits = cirq.LineQid.range(4, dimension=2)
@@ -388,6 +406,7 @@ def test_single_qubit_compare(v1: int, v2: int):
388406

389407

390408
@pytest.mark.parametrize("adjoint", [False, True])
409+
@allow_deprecated_cirq_ft_use_in_tests
391410
def test_bi_qubits_mixer_protocols(adjoint: bool):
392411
g = cirq_ft.algos.BiQubitsMixer(adjoint=adjoint)
393412
cirq_ft.testing.assert_decompose_is_consistent_with_t_complexity(g)
@@ -399,6 +418,7 @@ def test_bi_qubits_mixer_protocols(adjoint: bool):
399418

400419
@pytest.mark.parametrize("x", [*range(4)])
401420
@pytest.mark.parametrize("y", [*range(4)])
421+
@allow_deprecated_cirq_ft_use_in_tests
402422
def test_bi_qubits_mixer(x: int, y: int):
403423
g = cirq_ft.algos.BiQubitsMixer()
404424
qubits = cirq.LineQid.range(7, dimension=2)

0 commit comments

Comments
 (0)