Skip to content

Commit ea1679d

Browse files
authored
Deprecate Cirq-Rigetti (#7176)
* Add deprecation helper module for cirq_rigetti Adapt similar module from #6362 * Add deprecation warnings for public functions and classes Skip deprecations for internal functions. * Let deprecation wrappers detect cirq_rigetti tests * Suppress Cirq-Rigetti deprecation warnings in cirq_rigetti tests Deprecated cirq objects are not allowed in tests otherwise. * Add deprecation note to Cirq-Rigetti README Turn off README adjustments for development releases. * Fix rendering of deprecation notice in Rigetti README * Exclude cirq-rigetti when searching for doctests cirq_rigetti is deprecated and does not define doctests anyway. Avoid having to install cirq-rigetti for doctests. * Address deprecation errors in JSON serialization tests Mark up cirq_rigetti classes as deprecated. * Avoid deprecation errors in hash_from_pickle_test.py Exclude deprecated cirq_rigetti classes from testing. * Fix pylint (consider-using-f-string)
1 parent eb51ddc commit ea1679d

27 files changed

+218
-14
lines changed

cirq-core/cirq/protocols/hash_from_pickle_test.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050
"cirq/protocols/json_test_data/sympy.Indexed.json",
5151
"cirq/protocols/json_test_data/sympy.IndexedBase.json",
5252
"cirq/protocols/json_test_data/sympy.pi.json",
53+
# Cirq-Rigetti is deprecated per #7058
54+
# Instead of handling deprecation-in-test errors we exclude
55+
# all cirq_rigetti classes here.
56+
"cirq_rigetti/json_test_data/AspenQubit.json",
57+
"cirq_rigetti/json_test_data/OctagonalQubit.json",
5358
# RigettiQCSAspenDevice does not pickle
5459
"cirq_rigetti/json_test_data/RigettiQCSAspenDevice.json",
5560
)

cirq-rigetti/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
<div align="center">
2+
3+
| ⚠️ WARNING |
4+
|:----------:|
5+
| Cirq-Rigetti is deprecated. For more details or to provide feedback see https://github.com/quantumlib/Cirq/issues/7058 |
6+
7+
</div>
8+
19
<div align="center">
210
<img width="190px" alt="Cirq logo"
311
src="https://raw.githubusercontent.com/quantumlib/Cirq/refs/heads/main/docs/images/Cirq_logo_color.svg"

cirq-rigetti/cirq_rigetti/aspen_device.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,20 @@
2121
from pyquil.quantum_processor import QCSQuantumProcessor
2222
from qcs_sdk.client import QCSClient
2323
from qcs_sdk.qpu.isa import get_instruction_set_architecture, InstructionSetArchitecture, Family
24+
from cirq_rigetti.deprecation import deprecated_cirq_rigetti_class, deprecated_cirq_rigetti_function
2425

2526

27+
@deprecated_cirq_rigetti_class()
2628
class UnsupportedQubit(ValueError):
2729
pass
2830

2931

32+
@deprecated_cirq_rigetti_class()
3033
class UnsupportedRigettiQCSOperation(ValueError):
3134
pass
3235

3336

37+
@deprecated_cirq_rigetti_class()
3438
class UnsupportedRigettiQCSQuantumProcessor(ValueError):
3539
pass
3640

@@ -45,6 +49,7 @@ class UnsupportedRigettiQCSQuantumProcessor(ValueError):
4549
_reverse_line_qubit_mapping = [1, 0, 7, 6]
4650

4751

52+
@deprecated_cirq_rigetti_class()
4853
@cirq.value.value_equality
4954
class RigettiQCSAspenDevice(cirq.devices.Device):
5055
"""A cirq.Qid supporting Rigetti QCS Aspen device topology."""
@@ -232,6 +237,7 @@ def _from_json_dict_(cls, isa, **kwargs):
232237
return cls(isa=InstructionSetArchitecture.from_raw(json.dumps(isa)))
233238

234239

240+
@deprecated_cirq_rigetti_function()
235241
def get_rigetti_qcs_aspen_device(
236242
quantum_processor_id: str, client: Optional[QCSClient] = None
237243
) -> RigettiQCSAspenDevice:
@@ -254,6 +260,7 @@ def get_rigetti_qcs_aspen_device(
254260
return RigettiQCSAspenDevice(isa=isa)
255261

256262

263+
@deprecated_cirq_rigetti_class()
257264
class OctagonalQubit(cirq.ops.Qid):
258265
"""A cirq.Qid supporting Octagonal indexing."""
259266

@@ -369,6 +376,7 @@ def _json_dict_(self):
369376
return {'octagon_position': self.octagon_position}
370377

371378

379+
@deprecated_cirq_rigetti_class()
372380
class AspenQubit(OctagonalQubit):
373381
def __init__(self, octagon: int, octagon_position: int):
374382
super(AspenQubit, self).__init__(octagon_position)

cirq-rigetti/cirq_rigetti/aspen_device_test.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# pylint: disable=wrong-or-nonexistent-copyright-notice
22
import os
3+
import warnings
34
from unittest.mock import patch, PropertyMock
45
from math import sqrt
56
import pathlib
@@ -12,32 +13,52 @@
1213
UnsupportedQubit,
1314
UnsupportedRigettiQCSOperation,
1415
)
16+
from cirq_rigetti.deprecation import allow_deprecated_cirq_rigetti_use_in_tests
1517
from qcs_sdk.qpu.isa import InstructionSetArchitecture, Family
1618
import numpy as np
19+
from cirq._compat import ALLOW_DEPRECATION_IN_TEST
20+
from cirq_rigetti.deprecation import allow_deprecated_cirq_rigetti_use_in_tests
1721

1822
dir_path = pathlib.Path(os.path.dirname(os.path.realpath(__file__)))
1923
fixture_path = dir_path / '__fixtures__'
2024

25+
# test parameterization uses deprecated classes, therefore we need to have
26+
# ALLOW_DEPRECATION_IN_TEST set during import time. The initial environment
27+
# is restored at the end of the module.
28+
29+
_SAVE_ENVIRON = {k: os.environ[k] for k in [ALLOW_DEPRECATION_IN_TEST] if k in os.environ}
30+
os.environ[ALLOW_DEPRECATION_IN_TEST] = "True"
31+
32+
warnings.filterwarnings(
33+
"ignore",
34+
message="(.|\n)*Cirq-Rigetti is deprecated.",
35+
category=DeprecationWarning,
36+
module=__name__,
37+
)
38+
2139

2240
@pytest.fixture
2341
def qcs_aspen8_isa() -> InstructionSetArchitecture:
2442
with open(fixture_path / 'QCS-Aspen-8-ISA.json', 'r') as f:
2543
return InstructionSetArchitecture.from_raw(f.read())
2644

2745

46+
@allow_deprecated_cirq_rigetti_use_in_tests
2847
def test_octagonal_qubit_index():
2948
"""test that OctagonalQubit properly calculates index and uses it for comparison"""
3049
qubit0 = OctagonalQubit(0)
3150
assert qubit0.index == 0
3251
assert OctagonalQubit(1) > qubit0
3352

3453

54+
@allow_deprecated_cirq_rigetti_use_in_tests
3555
def test_octagonal_qubit_repr():
3656
"""test OctagonalQubit.__repr__"""
3757
qubit5 = OctagonalQubit(5)
3858
assert "cirq_rigetti.OctagonalQubit(octagon_position=5)" == repr(qubit5)
3959

4060

61+
@allow_deprecated_cirq_rigetti_use_in_tests
4162
def test_octagonal_qubit_positions():
4263
"""test OctagonalQubit 2D position and distance calculations"""
4364
qubit0 = OctagonalQubit(0)
@@ -77,25 +98,29 @@ def test_octagonal_qubit_positions():
7798
_ = qubit0.distance(AspenQubit(0, 0))
7899

79100

101+
@allow_deprecated_cirq_rigetti_use_in_tests
80102
def test_octagonal_position_validation():
81103
"""test OctagonalQubit validates octagon position when initialized"""
82104
with pytest.raises(ValueError):
83105
_ = OctagonalQubit(8)
84106

85107

108+
@allow_deprecated_cirq_rigetti_use_in_tests
86109
def test_aspen_qubit_index():
87110
"""test that AspenQubit properly calculates index and uses it for comparison"""
88111
qubit10 = AspenQubit(1, 0)
89112
assert qubit10.index == 10
90113
assert qubit10 > AspenQubit(0, 5)
91114

92115

116+
@allow_deprecated_cirq_rigetti_use_in_tests
93117
def test_aspen_qubit_repr():
94118
"""test AspenQubit.__repr__"""
95119
qubit10 = AspenQubit(1, 0)
96120
assert "cirq_rigetti.AspenQubit(octagon=1, octagon_position=0)" == repr(qubit10)
97121

98122

123+
@allow_deprecated_cirq_rigetti_use_in_tests
99124
def test_aspen_qubit_positions_and_distance():
100125
"""test AspenQubit 2D position and distance calculations"""
101126
qubit10 = AspenQubit(1, 0)
@@ -131,6 +156,7 @@ def test_aspen_qubit_positions_and_distance():
131156
_ = AspenQubit(1, 9)
132157

133158

159+
@allow_deprecated_cirq_rigetti_use_in_tests
134160
def test_aspen_qubit_qid_conversions():
135161
"""test AspenQubit conversion to and from other `cirq.Qid` implementations"""
136162
qubit10 = AspenQubit(1, 0)
@@ -152,6 +178,7 @@ def test_aspen_qubit_qid_conversions():
152178
_ = AspenQubit.from_grid_qubit(cirq.GridQubit(3, 4))
153179

154180

181+
@allow_deprecated_cirq_rigetti_use_in_tests
155182
def test_rigetti_qcs_aspen_device_topology(qcs_aspen8_isa: InstructionSetArchitecture):
156183
"""test RigettiQCSAspenDevice topological nodes and edges"""
157184
device = RigettiQCSAspenDevice(isa=qcs_aspen8_isa)
@@ -171,6 +198,7 @@ def test_rigetti_qcs_aspen_device_topology(qcs_aspen8_isa: InstructionSetArchite
171198
OctagonalQubit(6),
172199
],
173200
)
201+
@allow_deprecated_cirq_rigetti_use_in_tests
174202
def test_rigetti_qcs_aspen_device_valid_qubit(
175203
qubit: cirq.Qid, qcs_aspen8_isa: InstructionSetArchitecture
176204
):
@@ -191,6 +219,7 @@ def test_rigetti_qcs_aspen_device_valid_qubit(
191219
AspenQubit(4, 0),
192220
],
193221
)
222+
@allow_deprecated_cirq_rigetti_use_in_tests
194223
def test_rigetti_qcs_aspen_device_invalid_qubit(
195224
qubit: cirq.Qid, qcs_aspen8_isa: InstructionSetArchitecture
196225
):
@@ -212,6 +241,7 @@ def test_rigetti_qcs_aspen_device_invalid_qubit(
212241
cirq.CNOT(AspenQubit(0, 1), AspenQubit(1, 1)),
213242
],
214243
)
244+
@allow_deprecated_cirq_rigetti_use_in_tests
215245
def test_rigetti_qcs_aspen_device_invalid_operation(
216246
operation: cirq.Operation, qcs_aspen8_isa: InstructionSetArchitecture
217247
):
@@ -224,6 +254,7 @@ def test_rigetti_qcs_aspen_device_invalid_operation(
224254

225255

226256
@pytest.mark.parametrize('operation', [cirq.CNOT(AspenQubit(0, 1), AspenQubit(0, 2))])
257+
@allow_deprecated_cirq_rigetti_use_in_tests
227258
def test_rigetti_qcs_aspen_device_valid_operation(
228259
operation: cirq.Operation, qcs_aspen8_isa: InstructionSetArchitecture
229260
):
@@ -234,6 +265,7 @@ def test_rigetti_qcs_aspen_device_valid_operation(
234265
device.validate_operation(operation)
235266

236267

268+
@allow_deprecated_cirq_rigetti_use_in_tests
237269
def test_rigetti_qcs_aspen_device_qubits(qcs_aspen8_isa: InstructionSetArchitecture):
238270
"""test RigettiQCSAspenDevice returns accurate set of qubits"""
239271
device = RigettiQCSAspenDevice(isa=qcs_aspen8_isa)
@@ -244,12 +276,14 @@ def test_rigetti_qcs_aspen_device_qubits(qcs_aspen8_isa: InstructionSetArchitect
244276
assert expected_qubits == set(device.qubits())
245277

246278

279+
@allow_deprecated_cirq_rigetti_use_in_tests
247280
def test_rigetti_qcs_aspen_device_repr(qcs_aspen8_isa: InstructionSetArchitecture):
248281
"""test RigettiQCSAspenDevice.__repr__"""
249282
device = RigettiQCSAspenDevice(isa=qcs_aspen8_isa)
250283
assert f'cirq_rigetti.RigettiQCSAspenDevice(isa={qcs_aspen8_isa!r})' == repr(device)
251284

252285

286+
@allow_deprecated_cirq_rigetti_use_in_tests
253287
def test_rigetti_qcs_aspen_device_family_validation(qcs_aspen8_isa: InstructionSetArchitecture):
254288
"""test RigettiQCSAspenDevice validates architecture family on initialization"""
255289
non_aspen_isa = InstructionSetArchitecture.from_raw(qcs_aspen8_isa.json())
@@ -260,10 +294,16 @@ def test_rigetti_qcs_aspen_device_family_validation(qcs_aspen8_isa: InstructionS
260294
), 'ISA family is read-only and should still be Aspen'
261295

262296

297+
@allow_deprecated_cirq_rigetti_use_in_tests
263298
def test_get_rigetti_qcs_aspen_device(qcs_aspen8_isa: InstructionSetArchitecture):
264299
with patch('cirq_rigetti.aspen_device.get_instruction_set_architecture') as mock:
265300
mock.return_value = qcs_aspen8_isa
266301

267302
from cirq_rigetti.aspen_device import get_rigetti_qcs_aspen_device
268303

269304
assert get_rigetti_qcs_aspen_device('Aspen-8') == RigettiQCSAspenDevice(isa=qcs_aspen8_isa)
305+
306+
307+
# clean up extra environment variable
308+
del os.environ[ALLOW_DEPRECATION_IN_TEST]
309+
os.environ.update(_SAVE_ENVIRON)

cirq-rigetti/cirq_rigetti/circuit_sweep_executors.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from typing_extensions import Protocol
2525
from cirq_rigetti.logging import logger
2626
from cirq_rigetti import circuit_transformers as transformers
27+
from cirq_rigetti.deprecation import deprecated_cirq_rigetti_class, deprecated_cirq_rigetti_function
2728

2829

2930
def _execute_and_read_result(
@@ -128,6 +129,7 @@ def _prepend_real_declarations(
128129
return program
129130

130131

132+
@deprecated_cirq_rigetti_class()
131133
class CircuitSweepExecutor(Protocol):
132134
"""A type definition for circuit sweep execution functions."""
133135

@@ -158,6 +160,7 @@ def __call__(
158160
"""
159161

160162

163+
@deprecated_cirq_rigetti_function()
161164
def without_quilc_compilation(
162165
*,
163166
quantum_computer: QuantumComputer,
@@ -199,6 +202,7 @@ def without_quilc_compilation(
199202
return cirq_results
200203

201204

205+
@deprecated_cirq_rigetti_function()
202206
def with_quilc_compilation_and_cirq_parameter_resolution(
203207
*,
204208
quantum_computer: QuantumComputer,
@@ -242,6 +246,7 @@ def with_quilc_compilation_and_cirq_parameter_resolution(
242246
return cirq_results
243247

244248

249+
@deprecated_cirq_rigetti_function()
245250
def with_quilc_parametric_compilation(
246251
*,
247252
quantum_computer: QuantumComputer,

cirq-rigetti/cirq_rigetti/circuit_sweep_executors_test.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
import numpy as np
77
import sympy
88
from cirq_rigetti import circuit_sweep_executors as executors, circuit_transformers
9+
from cirq_rigetti.deprecation import allow_deprecated_cirq_rigetti_use_in_tests
910

1011

12+
@allow_deprecated_cirq_rigetti_use_in_tests
1113
def test_with_quilc_compilation_and_cirq_parameter_resolution(
1214
mock_qpu_implementer: Any, parametric_circuit_with_params: Tuple[cirq.Circuit, cirq.Sweepable]
1315
) -> None:
@@ -46,6 +48,7 @@ def test_with_quilc_compilation_and_cirq_parameter_resolution(
4648

4749

4850
@pytest.mark.parametrize('pass_dict', [True, False])
51+
@allow_deprecated_cirq_rigetti_use_in_tests
4952
def test_with_quilc_parametric_compilation(
5053
mock_qpu_implementer: Any,
5154
parametric_circuit_with_params: Tuple[cirq.Circuit, cirq.Linspace],
@@ -88,6 +91,7 @@ def test_with_quilc_parametric_compilation(
8891
), "should return an ordered list of results with correct set of measurements"
8992

9093

94+
@allow_deprecated_cirq_rigetti_use_in_tests
9195
def test_parametric_with_symbols(
9296
mock_qpu_implementer: Any, parametric_circuit_with_params: Tuple[cirq.Circuit, cirq.Linspace]
9397
):
@@ -106,6 +110,7 @@ def test_parametric_with_symbols(
106110
)
107111

108112

113+
@allow_deprecated_cirq_rigetti_use_in_tests
109114
def test_without_quilc_compilation(
110115
mock_qpu_implementer: Any, parametric_circuit_with_params: Tuple[cirq.Circuit, cirq.Sweepable]
111116
) -> None:
@@ -143,6 +148,7 @@ def test_without_quilc_compilation(
143148
), "should return an ordered list of results with correct set of measurements"
144149

145150

151+
@allow_deprecated_cirq_rigetti_use_in_tests
146152
def test_invalid_pyquil_region_measurement(
147153
mock_qpu_implementer: Any, parametric_circuit_with_params: Tuple[cirq.Circuit, cirq.Sweepable]
148154
) -> None:

cirq-rigetti/cirq_rigetti/circuit_transformers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
import cirq
2020
from cirq_rigetti.quil_output import RigettiQCSQuilOutput
2121
from typing_extensions import Protocol
22+
from cirq_rigetti.deprecation import deprecated_cirq_rigetti_class, deprecated_cirq_rigetti_function
2223

2324

25+
@deprecated_cirq_rigetti_class()
2426
class _PostTransformationHook(Protocol):
2527
def __call__(
2628
self, *, program: Program, measurement_id_map: Dict[str, str]
@@ -57,6 +59,7 @@ def _transform_cirq_circuit_to_pyquil_program(
5759
return program, measurement_id_map
5860

5961

62+
@deprecated_cirq_rigetti_class()
6063
class CircuitTransformer(Protocol):
6164
"""A type definition for `cirq.Circuit` to `pyquil.Program` transformer functions."""
6265

@@ -72,6 +75,7 @@ def __call__(self, *, circuit: cirq.Circuit) -> Tuple[Program, Dict[str, str]]:
7275
"""
7376

7477

78+
@deprecated_cirq_rigetti_function()
7579
def build(
7680
*,
7781
qubits: Optional[Tuple[cirq.Qid, ...]] = None,
@@ -111,6 +115,7 @@ def transformer(*, circuit: cirq.Circuit) -> Tuple[Program, Dict[str, str]]:
111115
return cast(CircuitTransformer, transformer)
112116

113117

118+
@deprecated_cirq_rigetti_function()
114119
def default(*, circuit: cirq.Circuit) -> Tuple[Program, Dict[str, str]]:
115120
"""The default `CircuitTransformer` uses the default behavior of cirq's Quil
116121
protocol to transform a `cirq.Circuit` into a `pyquil.Program`.

0 commit comments

Comments
 (0)