Skip to content

Commit 5ad8e6e

Browse files
authored
Deprecating cross_entropy_benchmarking and grid_parallel_two_qubit_xeb (#5424)
- cirq.experiments.cross_entropy_benchmarking is redundant and not easy to adapt. - cirq.experiments.grid_parallel_two_qubit_xeb moved to recirq.benchmarks.xeb - Also delete cross_entropy_benchmarking example This is part of #3775.
1 parent ac7994e commit 5ad8e6e

7 files changed

+169
-172
lines changed

cirq-core/cirq/experiments/cross_entropy_benchmarking.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import dataclasses
3030
import numpy as np
3131
from matplotlib import pyplot as plt
32-
from cirq import _import, circuits, devices, ops, protocols, sim, value, work
32+
from cirq import _compat, _import, circuits, devices, ops, protocols, sim, value, work
3333

3434
if TYPE_CHECKING:
3535
import cirq
@@ -98,6 +98,9 @@ def purity(self) -> float:
9898
return self.cycle_depolarization**2
9999

100100

101+
@_compat.deprecated_class(
102+
deadline='v0.16', fix=('Use cirq.experiments.xeb_fitting.XEBCharacterizationResult instead')
103+
)
101104
@dataclasses.dataclass(frozen=True)
102105
class CrossEntropyResult:
103106
"""Results from a cross-entropy benchmarking (XEB) experiment.
@@ -243,6 +246,9 @@ def f(a, S, p):
243246
return optimize.curve_fit(f, x, y, p0=p0)
244247

245248

249+
@_compat.deprecated_class(
250+
deadline='v0.16', fix=('Use cirq.experiments.xeb_fitting.XEBCharacterizationResult instead')
251+
)
246252
@dataclasses.dataclass
247253
class CrossEntropyResultDict(Mapping[Tuple['cirq.Qid', ...], CrossEntropyResult]):
248254
"""Per-qubit-tuple results from cross-entropy benchmarking.
@@ -276,6 +282,9 @@ def __len__(self):
276282
return len(self.results)
277283

278284

285+
@_compat.deprecated(
286+
deadline='v0.16', fix=('Use cirq.experiments.xeb_fitting.benchmark_2q_xeb_fidelities instead')
287+
)
279288
def cross_entropy_benchmarking(
280289
sampler: work.Sampler,
281290
qubits: Sequence[ops.Qid],
@@ -418,6 +427,9 @@ def cross_entropy_benchmarking(
418427
return CrossEntropyResult(data=xeb_data, repetitions=repetitions) # type: ignore
419428

420429

430+
@_compat.deprecated(
431+
deadline='v0.16', fix=('Use cirq.experiments.random_quantum_circuit_generation instead')
432+
)
421433
def build_entangling_layers(
422434
qubits: Sequence[devices.GridQubit], two_qubit_gate: ops.Gate
423435
) -> List[circuits.Moment]:

cirq-core/cirq/experiments/cross_entropy_benchmarking_test.py

+90-70
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
)
2626
from cirq.experiments.cross_entropy_benchmarking import CrossEntropyPair, SpecklePurityPair
2727

28+
_DEPRECATION_MESSAGE = 'Use cirq.experiments.xeb_fitting.XEBCharacterizationResult instead'
29+
_DEPRECATION_RANDOM_CIRCUIT = 'Use cirq.experiments.random_quantum_circuit_generation instead'
30+
2831

2932
@pytest.mark.usefixtures('closefigures')
3033
def test_cross_entropy_benchmarking():
@@ -36,10 +39,12 @@ def test_cross_entropy_benchmarking():
3639

3740
# Sanity check single-qubit-gate causes error
3841
with pytest.raises(ValueError):
39-
build_entangling_layers(qubits, cirq.Z**0.91)
42+
with cirq.testing.assert_deprecated(_DEPRECATION_RANDOM_CIRCUIT, deadline='v0.16'):
43+
build_entangling_layers(qubits, cirq.Z**0.91)
4044

4145
# Build a sequence of CZ gates.
42-
interleaved_ops = build_entangling_layers(qubits, cirq.CZ**0.91)
46+
with cirq.testing.assert_deprecated(_DEPRECATION_RANDOM_CIRCUIT, deadline='v0.16'):
47+
interleaved_ops = build_entangling_layers(qubits, cirq.CZ**0.91)
4348

4449
# Specify a set of single-qubit rotations. Pick prime numbers for the
4550
# exponent to avoid evolving the system into a basis state.
@@ -56,35 +61,42 @@ def test_cross_entropy_benchmarking():
5661
# gate. Check that the fidelities are close to 1.0 in all cases. Also,
5762
# check that a single XEB fidelity is returned if a single cycle number
5863
# is specified.
59-
results_0 = cross_entropy_benchmarking(
60-
simulator, qubits, num_circuits=3, repetitions=1000, cycles=range(4, 20, 5)
61-
)
62-
results_1 = cross_entropy_benchmarking(
63-
simulator,
64-
qubits,
65-
num_circuits=3,
66-
repetitions=1000,
67-
cycles=[4, 8, 12],
68-
scrambling_gates_per_cycle=single_qubit_rots,
69-
)
70-
results_2 = cross_entropy_benchmarking(
71-
simulator,
72-
qubits,
73-
benchmark_ops=interleaved_ops,
74-
num_circuits=3,
75-
repetitions=1000,
76-
cycles=[4, 8, 12],
77-
scrambling_gates_per_cycle=single_qubit_rots,
78-
)
79-
results_3 = cross_entropy_benchmarking(
80-
simulator,
81-
qubits,
82-
benchmark_ops=interleaved_ops,
83-
num_circuits=3,
84-
repetitions=1000,
85-
cycles=15,
86-
scrambling_gates_per_cycle=single_qubit_rots,
87-
)
64+
65+
# Each of theese has one ideprecation for cross_entropy_benchmarking
66+
# and one deprecation for CrossEntropyResult
67+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16', count=2):
68+
results_0 = cross_entropy_benchmarking(
69+
simulator, qubits, num_circuits=3, repetitions=1000, cycles=range(4, 20, 5)
70+
)
71+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16', count=2):
72+
results_1 = cross_entropy_benchmarking(
73+
simulator,
74+
qubits,
75+
num_circuits=3,
76+
repetitions=1000,
77+
cycles=[4, 8, 12],
78+
scrambling_gates_per_cycle=single_qubit_rots,
79+
)
80+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16', count=2):
81+
results_2 = cross_entropy_benchmarking(
82+
simulator,
83+
qubits,
84+
benchmark_ops=interleaved_ops,
85+
num_circuits=3,
86+
repetitions=1000,
87+
cycles=[4, 8, 12],
88+
scrambling_gates_per_cycle=single_qubit_rots,
89+
)
90+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16', count=2):
91+
results_3 = cross_entropy_benchmarking(
92+
simulator,
93+
qubits,
94+
benchmark_ops=interleaved_ops,
95+
num_circuits=3,
96+
repetitions=1000,
97+
cycles=15,
98+
scrambling_gates_per_cycle=single_qubit_rots,
99+
)
88100
fidelities_0 = [datum.xeb_fidelity for datum in results_0.data]
89101
fidelities_1 = [datum.xeb_fidelity for datum in results_1.data]
90102
fidelities_2 = [datum.xeb_fidelity for datum in results_2.data]
@@ -100,52 +112,60 @@ def test_cross_entropy_benchmarking():
100112

101113

102114
def test_cross_entropy_result_depolarizing_models():
103-
prng = np.random.RandomState(59566)
104-
S = 0.8
105-
p = 0.99
106-
data = [
107-
CrossEntropyPair(num_cycle=d, xeb_fidelity=S * p**d + prng.normal(scale=0.01))
108-
for d in range(10, 211, 20)
109-
]
110-
purity_data = [
111-
SpecklePurityPair(num_cycle=d, purity=S * p ** (2 * d) + prng.normal(scale=0.01))
112-
for d in range(10, 211, 20)
113-
]
114-
result = CrossEntropyResult(data=data, repetitions=1000, purity_data=purity_data)
115-
model = result.depolarizing_model()
116-
purity_model = result.purity_depolarizing_model()
117-
np.testing.assert_allclose(model.spam_depolarization, S, atol=1e-2)
118-
np.testing.assert_allclose(model.cycle_depolarization, p, atol=1e-2)
119-
np.testing.assert_allclose(purity_model.purity, p**2, atol=1e-2)
115+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16'):
116+
prng = np.random.RandomState(59566)
117+
S = 0.8
118+
p = 0.99
119+
data = [
120+
CrossEntropyPair(num_cycle=d, xeb_fidelity=S * p**d + prng.normal(scale=0.01))
121+
for d in range(10, 211, 20)
122+
]
123+
purity_data = [
124+
SpecklePurityPair(num_cycle=d, purity=S * p ** (2 * d) + prng.normal(scale=0.01))
125+
for d in range(10, 211, 20)
126+
]
127+
result = CrossEntropyResult(data=data, repetitions=1000, purity_data=purity_data)
128+
model = result.depolarizing_model()
129+
purity_model = result.purity_depolarizing_model()
130+
np.testing.assert_allclose(model.spam_depolarization, S, atol=1e-2)
131+
np.testing.assert_allclose(model.cycle_depolarization, p, atol=1e-2)
132+
np.testing.assert_allclose(purity_model.purity, p**2, atol=1e-2)
120133

121134

122135
def test_cross_entropy_result_repr():
123-
result1 = CrossEntropyResult(
124-
data=[CrossEntropyPair(2, 0.9), CrossEntropyPair(5, 0.5)], repetitions=1000
125-
)
126-
result2 = CrossEntropyResult(
127-
data=[CrossEntropyPair(2, 0.9), CrossEntropyPair(5, 0.5)],
128-
repetitions=1000,
129-
purity_data=[SpecklePurityPair(2, 0.8), SpecklePurityPair(5, 0.3)],
130-
)
131-
cirq.testing.assert_equivalent_repr(result1)
132-
cirq.testing.assert_equivalent_repr(result2)
136+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16'):
137+
result1 = CrossEntropyResult(
138+
data=[CrossEntropyPair(2, 0.9), CrossEntropyPair(5, 0.5)], repetitions=1000
139+
)
140+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16'):
141+
result2 = CrossEntropyResult(
142+
data=[CrossEntropyPair(2, 0.9), CrossEntropyPair(5, 0.5)],
143+
repetitions=1000,
144+
purity_data=[SpecklePurityPair(2, 0.8), SpecklePurityPair(5, 0.3)],
145+
)
146+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16', count=6):
147+
cirq.testing.assert_equivalent_repr(result1)
148+
cirq.testing.assert_equivalent_repr(result2)
133149

134150

135151
def test_cross_entropy_result_dict_repr():
136152
pair = tuple(cirq.LineQubit.range(2))
137-
result = CrossEntropyResult(
138-
data=[CrossEntropyPair(2, 0.9), CrossEntropyPair(5, 0.5)], repetitions=1000
139-
)
140-
result_dict = CrossEntropyResultDict(results={pair: result})
141-
cirq.testing.assert_equivalent_repr(result_dict)
153+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16'):
154+
result = CrossEntropyResult(
155+
data=[CrossEntropyPair(2, 0.9), CrossEntropyPair(5, 0.5)], repetitions=1000
156+
)
157+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16'):
158+
result_dict = CrossEntropyResultDict(results={pair: result})
159+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16', count=6):
160+
cirq.testing.assert_equivalent_repr(result_dict)
142161

143162

144163
def test_cross_entropy_result_purity_model_fails_with_no_data():
145-
data = [
146-
CrossEntropyPair(num_cycle=2, xeb_fidelity=0.9),
147-
CrossEntropyPair(num_cycle=4, xeb_fidelity=0.8),
148-
]
149-
result = CrossEntropyResult(data=data, repetitions=1000)
150-
with pytest.raises(ValueError):
151-
_ = result.purity_depolarizing_model()
164+
with cirq.testing.assert_deprecated(_DEPRECATION_MESSAGE, deadline='v0.16'):
165+
data = [
166+
CrossEntropyPair(num_cycle=2, xeb_fidelity=0.9),
167+
CrossEntropyPair(num_cycle=4, xeb_fidelity=0.8),
168+
]
169+
result = CrossEntropyResult(data=data, repetitions=1000)
170+
with pytest.raises(ValueError):
171+
_ = result.purity_depolarizing_model()

cirq-core/cirq/experiments/grid_parallel_two_qubit_xeb.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
import numpy as np
3333

34-
from cirq import devices, ops, protocols, sim, value
34+
from cirq import _compat, devices, ops, protocols, sim, value
3535
from cirq.experiments.cross_entropy_benchmarking import (
3636
CrossEntropyResult,
3737
CrossEntropyResultDict,
@@ -219,6 +219,10 @@ def filename(self) -> str:
219219
return os.path.join(self.data_collection_id, 'results.json')
220220

221221

222+
@_compat.deprecated(
223+
deadline='v0.16',
224+
fix=('Use recirq.benchmarks.xeb.collect_grid_parallel_two_qubit_xeb_data instead.'),
225+
)
222226
def collect_grid_parallel_two_qubit_xeb_data(
223227
sampler: 'cirq.Sampler',
224228
qubits: Iterable['cirq.GridQubit'],
@@ -373,6 +377,10 @@ def run_truncated_circuit(
373377
return data_collection_id
374378

375379

380+
@_compat.deprecated(
381+
deadline='v0.16',
382+
fix=('Use recirq.benchmarks.xeb.compute_grid_parallel_two_qubit_xeb_results instead.'),
383+
)
376384
def compute_grid_parallel_two_qubit_xeb_results(
377385
data_collection_id: str, num_processors: int = 1, base_dir: str = DEFAULT_BASE_DIR
378386
) -> CrossEntropyResultDict:

0 commit comments

Comments
 (0)