cirq-core 1.7.0.dev20250806162852__py3-none-any.whl → 1.7.0.dev20250812001555__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cirq-core might be problematic. Click here for more details.
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/contrib/noise_models/noise_models.py +8 -8
- cirq/contrib/quimb/grid_circuits.py +1 -1
- cirq/contrib/quimb/grid_circuits_test.py +10 -5
- cirq/contrib/quimb/mps_simulator.py +3 -3
- cirq/contrib/quimb/mps_simulator_test.py +41 -42
- cirq/contrib/quimb/state_vector_test.py +14 -13
- cirq/contrib/quirk/export_to_quirk_test.py +2 -2
- cirq/contrib/quirk/linearize_circuit.py +1 -1
- cirq/contrib/routing/device.py +1 -1
- cirq/contrib/routing/device_test.py +7 -5
- cirq/contrib/routing/greedy_test.py +7 -2
- cirq/contrib/routing/initialization_test.py +1 -1
- cirq/contrib/routing/router_test.py +9 -10
- cirq/contrib/routing/swap_network_test.py +10 -4
- cirq/contrib/routing/utils_test.py +4 -4
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +9 -9
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +18 -16
- cirq/contrib/svg/svg.py +1 -1
- cirq/devices/grid_device_metadata_test.py +12 -12
- cirq/devices/grid_qubit_test.py +52 -52
- cirq/devices/line_qubit_test.py +37 -37
- cirq/devices/named_topologies.py +7 -5
- cirq/devices/named_topologies_test.py +3 -2
- cirq/devices/noise_model.py +1 -1
- cirq/devices/noise_properties_test.py +1 -1
- cirq/devices/noise_utils.py +1 -1
- cirq/devices/noise_utils_test.py +6 -6
- cirq/devices/superconducting_qubits_noise_properties_test.py +31 -24
- cirq/devices/thermal_noise_model_test.py +48 -44
- cirq/devices/unconstrained_device.py +1 -1
- cirq/devices/unconstrained_device_test.py +3 -3
- cirq/experiments/benchmarking/parallel_xeb.py +24 -17
- cirq/experiments/benchmarking/parallel_xeb_test.py +42 -28
- cirq/experiments/fidelity_estimation.py +5 -5
- cirq/experiments/fidelity_estimation_test.py +7 -7
- cirq/experiments/purity_estimation.py +1 -1
- cirq/experiments/purity_estimation_test.py +1 -1
- cirq/experiments/qubit_characterizations_test.py +10 -10
- cirq/experiments/random_quantum_circuit_generation.py +1 -1
- cirq/experiments/random_quantum_circuit_generation_test.py +18 -13
- cirq/experiments/readout_confusion_matrix_test.py +12 -8
- cirq/experiments/single_qubit_readout_calibration_test.py +13 -13
- cirq/experiments/t2_decay_experiment.py +1 -1
- cirq/experiments/t2_decay_experiment_test.py +13 -13
- cirq/experiments/two_qubit_xeb_test.py +20 -22
- cirq/experiments/xeb_fitting.py +3 -3
- cirq/experiments/xeb_fitting_test.py +21 -19
- cirq/experiments/xeb_sampling.py +2 -2
- cirq/experiments/xeb_sampling_test.py +9 -9
- cirq/experiments/xeb_simulation.py +1 -1
- cirq/experiments/xeb_simulation_test.py +6 -6
- cirq/ops/measure_util.py +2 -0
- cirq/transformers/eject_phased_paulis.py +2 -19
- cirq/transformers/eject_phased_paulis_test.py +3 -51
- {cirq_core-1.7.0.dev20250806162852.dist-info → cirq_core-1.7.0.dev20250812001555.dist-info}/METADATA +1 -1
- {cirq_core-1.7.0.dev20250806162852.dist-info → cirq_core-1.7.0.dev20250812001555.dist-info}/RECORD +61 -61
- {cirq_core-1.7.0.dev20250806162852.dist-info → cirq_core-1.7.0.dev20250812001555.dist-info}/WHEEL +0 -0
- {cirq_core-1.7.0.dev20250806162852.dist-info → cirq_core-1.7.0.dev20250812001555.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.7.0.dev20250806162852.dist-info → cirq_core-1.7.0.dev20250812001555.dist-info}/top_level.txt +0 -0
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
+
from typing import Any, Sequence
|
|
18
|
+
|
|
17
19
|
import numpy as np
|
|
18
20
|
import pytest
|
|
19
21
|
|
|
@@ -37,7 +39,9 @@ DEFAULT_GATE_NS: dict[type, float] = {
|
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
|
|
40
|
-
def default_props(
|
|
42
|
+
def default_props(
|
|
43
|
+
system_qubits: Sequence[cirq.Qid], qubit_pairs: Sequence[tuple[cirq.Qid, cirq.Qid]]
|
|
44
|
+
) -> dict[str, Any]:
|
|
41
45
|
return {
|
|
42
46
|
'gate_times_ns': DEFAULT_GATE_NS,
|
|
43
47
|
't1_ns': {q: 1e5 for q in system_qubits},
|
|
@@ -75,7 +79,7 @@ class ExampleNoiseProperties(SuperconductingQubitsNoiseProperties):
|
|
|
75
79
|
return set()
|
|
76
80
|
|
|
77
81
|
|
|
78
|
-
def test_init_validation():
|
|
82
|
+
def test_init_validation() -> None:
|
|
79
83
|
q0, q1, q2 = cirq.LineQubit.range(3)
|
|
80
84
|
with pytest.raises(ValueError, match='Keys specified for T1 and Tphi are not identical.'):
|
|
81
85
|
_ = ExampleNoiseProperties(
|
|
@@ -92,7 +96,7 @@ def test_init_validation():
|
|
|
92
96
|
t1_ns={q0: 1},
|
|
93
97
|
tphi_ns={q0: 1},
|
|
94
98
|
readout_errors={q0: [0.1, 0.2]},
|
|
95
|
-
gate_pauli_errors={OpIdentifier(cirq.CCNOT, q0, q1, q2): 0.1},
|
|
99
|
+
gate_pauli_errors={OpIdentifier(type(cirq.CCNOT), q0, q1, q2): 0.1},
|
|
96
100
|
)
|
|
97
101
|
|
|
98
102
|
with pytest.raises(ValueError, match='does not appear in the symmetric or asymmetric'):
|
|
@@ -102,8 +106,8 @@ def test_init_validation():
|
|
|
102
106
|
tphi_ns={q0: 1},
|
|
103
107
|
readout_errors={q0: [0.1, 0.2]},
|
|
104
108
|
gate_pauli_errors={
|
|
105
|
-
OpIdentifier(cirq.
|
|
106
|
-
OpIdentifier(cirq.
|
|
109
|
+
OpIdentifier(cirq.CNotPowGate, q0, q1): 0.1,
|
|
110
|
+
OpIdentifier(cirq.CNotPowGate, q1, q0): 0.1,
|
|
107
111
|
},
|
|
108
112
|
)
|
|
109
113
|
|
|
@@ -136,18 +140,19 @@ def test_init_validation():
|
|
|
136
140
|
# All errors are ignored if validation is disabled.
|
|
137
141
|
_ = ExampleNoiseProperties(
|
|
138
142
|
gate_times_ns=DEFAULT_GATE_NS,
|
|
139
|
-
t1_ns={},
|
|
143
|
+
# t1_ns={},
|
|
144
|
+
t1_ns={q0: 1},
|
|
140
145
|
tphi_ns={q0: 1},
|
|
141
146
|
readout_errors={q0: [0.1, 0.2]},
|
|
142
147
|
gate_pauli_errors={
|
|
143
|
-
OpIdentifier(cirq.CCNOT, q0, q1, q2): 0.1,
|
|
144
|
-
OpIdentifier(cirq.CNOT, q0, q1): 0.1,
|
|
148
|
+
OpIdentifier(type(cirq.CCNOT), q0, q1, q2): 0.1,
|
|
149
|
+
OpIdentifier(type(cirq.CNOT), q0, q1): 0.1,
|
|
145
150
|
},
|
|
146
151
|
validate=False,
|
|
147
152
|
)
|
|
148
153
|
|
|
149
154
|
|
|
150
|
-
def test_qubits():
|
|
155
|
+
def test_qubits() -> None:
|
|
151
156
|
q0 = cirq.LineQubit(0)
|
|
152
157
|
props = ExampleNoiseProperties(**default_props([q0], []))
|
|
153
158
|
assert props.qubits == [q0]
|
|
@@ -155,7 +160,7 @@ def test_qubits():
|
|
|
155
160
|
assert props.qubits == [q0]
|
|
156
161
|
|
|
157
162
|
|
|
158
|
-
def test_depol_memoization():
|
|
163
|
+
def test_depol_memoization() -> None:
|
|
159
164
|
# Verify that depolarizing error is memoized.
|
|
160
165
|
q0 = cirq.LineQubit(0)
|
|
161
166
|
props = ExampleNoiseProperties(**default_props([q0], []))
|
|
@@ -165,7 +170,7 @@ def test_depol_memoization():
|
|
|
165
170
|
assert depol_error_a is depol_error_b
|
|
166
171
|
|
|
167
172
|
|
|
168
|
-
def test_depol_validation():
|
|
173
|
+
def test_depol_validation() -> None:
|
|
169
174
|
q0, q1, q2 = cirq.LineQubit.range(3)
|
|
170
175
|
# Create unvalidated properties with too many qubits on a Z gate.
|
|
171
176
|
z_2q_props = ExampleNoiseProperties(
|
|
@@ -213,7 +218,7 @@ def test_depol_validation():
|
|
|
213
218
|
),
|
|
214
219
|
],
|
|
215
220
|
)
|
|
216
|
-
def test_single_qubit_gates(op):
|
|
221
|
+
def test_single_qubit_gates(op) -> None:
|
|
217
222
|
q0 = cirq.LineQubit(0)
|
|
218
223
|
props = ExampleNoiseProperties(**default_props([q0], []))
|
|
219
224
|
model = NoiseModelFromNoiseProperties(props)
|
|
@@ -237,10 +242,10 @@ def test_single_qubit_gates(op):
|
|
|
237
242
|
assert np.allclose(
|
|
238
243
|
thermal_choi,
|
|
239
244
|
[
|
|
240
|
-
[1, 0, 0, 9.99750031e-01],
|
|
241
|
-
[0, 2.49968753e-04, 0, 0],
|
|
242
|
-
[0, 0, 0, 0],
|
|
243
|
-
[9.99750031e-01, 0, 0, 9.99750031e-01],
|
|
245
|
+
[1.0, 0.0, 0.0, 9.99750031e-01],
|
|
246
|
+
[0.0, 2.49968753e-04, 0.0, 0.0],
|
|
247
|
+
[0.0, 0.0, 0.0, 0.0],
|
|
248
|
+
[9.99750031e-01, 0.0, 0.0, 9.99750031e-01],
|
|
244
249
|
],
|
|
245
250
|
)
|
|
246
251
|
|
|
@@ -248,7 +253,7 @@ def test_single_qubit_gates(op):
|
|
|
248
253
|
@pytest.mark.parametrize(
|
|
249
254
|
'op', [cirq.ISWAP(*cirq.LineQubit.range(2)) ** 0.6, cirq.CZ(*cirq.LineQubit.range(2)) ** 0.3]
|
|
250
255
|
)
|
|
251
|
-
def test_two_qubit_gates(op):
|
|
256
|
+
def test_two_qubit_gates(op) -> None:
|
|
252
257
|
q0, q1 = cirq.LineQubit.range(2)
|
|
253
258
|
props = ExampleNoiseProperties(**default_props([q0, q1], [(q0, q1), (q1, q0)]))
|
|
254
259
|
model = NoiseModelFromNoiseProperties(props)
|
|
@@ -268,6 +273,8 @@ def test_two_qubit_gates(op):
|
|
|
268
273
|
assert len(noisy_circuit.moments[2].operations) == 2
|
|
269
274
|
thermal_op_0 = noisy_circuit.moments[2].operation_at(q0)
|
|
270
275
|
thermal_op_1 = noisy_circuit.moments[2].operation_at(q1)
|
|
276
|
+
assert thermal_op_0 is not None
|
|
277
|
+
assert thermal_op_1 is not None
|
|
271
278
|
assert isinstance(thermal_op_0.gate, cirq.KrausChannel)
|
|
272
279
|
assert isinstance(thermal_op_1.gate, cirq.KrausChannel)
|
|
273
280
|
thermal_choi_0 = cirq.kraus_to_choi(cirq.kraus(thermal_op_0))
|
|
@@ -284,7 +291,7 @@ def test_two_qubit_gates(op):
|
|
|
284
291
|
assert np.allclose(thermal_choi_1, expected_thermal_choi)
|
|
285
292
|
|
|
286
293
|
|
|
287
|
-
def test_measure_gates():
|
|
294
|
+
def test_measure_gates() -> None:
|
|
288
295
|
q00, q01, q10, q11 = cirq.GridQubit.rect(2, 2)
|
|
289
296
|
qubits = [q00, q01, q10, q11]
|
|
290
297
|
props = ExampleNoiseProperties(
|
|
@@ -311,7 +318,7 @@ def test_measure_gates():
|
|
|
311
318
|
# Amplitude damping before measurement
|
|
312
319
|
assert len(noisy_circuit.moments[0].operations) == 4
|
|
313
320
|
for q in qubits:
|
|
314
|
-
op = noisy_circuit.moments[0].operation_at(q)
|
|
321
|
+
op = noisy_circuit.moments[0].operation_at(q) # type: ignore[assignment]
|
|
315
322
|
assert isinstance(op.gate, cirq.GeneralizedAmplitudeDampingChannel), q
|
|
316
323
|
assert np.isclose(op.gate.p, 0.90909090), q
|
|
317
324
|
assert np.isclose(op.gate.gamma, 0.011), q
|
|
@@ -322,7 +329,7 @@ def test_measure_gates():
|
|
|
322
329
|
assert noisy_circuit.moments[1] == circuit.moments[0]
|
|
323
330
|
|
|
324
331
|
|
|
325
|
-
def test_wait_gates():
|
|
332
|
+
def test_wait_gates() -> None:
|
|
326
333
|
q0 = cirq.LineQubit(0)
|
|
327
334
|
props = ExampleNoiseProperties(**default_props([q0], []))
|
|
328
335
|
model = NoiseModelFromNoiseProperties(props)
|
|
@@ -341,9 +348,9 @@ def test_wait_gates():
|
|
|
341
348
|
assert np.allclose(
|
|
342
349
|
thermal_choi,
|
|
343
350
|
[
|
|
344
|
-
[1, 0, 0, 9.990005e-01],
|
|
345
|
-
[0, 9.99500167e-04, 0, 0],
|
|
346
|
-
[0, 0, 0, 0],
|
|
347
|
-
[9.990005e-01, 0, 0, 9.990005e-01],
|
|
351
|
+
[1.0, 0.0, 0.0, 9.990005e-01],
|
|
352
|
+
[0.0, 9.99500167e-04, 0.0, 0.0],
|
|
353
|
+
[0.0, 0.0, 0.0, 0.0],
|
|
354
|
+
[9.990005e-01, 0.0, 0.0, 9.990005e-01],
|
|
348
355
|
],
|
|
349
356
|
)
|
|
@@ -28,7 +28,7 @@ from cirq.devices.thermal_noise_model import (
|
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def test_helper_method_errors():
|
|
31
|
+
def test_helper_method_errors() -> None:
|
|
32
32
|
with pytest.raises(ValueError, match='_left_mul only accepts square matrices'):
|
|
33
33
|
_ = _left_mul(np.array([[1, 2, 3], [4, 5, 6]]))
|
|
34
34
|
|
|
@@ -49,12 +49,12 @@ def test_helper_method_errors():
|
|
|
49
49
|
_validate_rates({q0}, {q0: np.array([[0.001, 0.01, 0.1], [0.002, 0.02, 0.2]])})
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
def test_create_thermal_noise_per_qubit():
|
|
52
|
+
def test_create_thermal_noise_per_qubit() -> None:
|
|
53
53
|
q0, q1 = cirq.LineQubit.range(2)
|
|
54
|
-
gate_durations = {cirq.PhasedXZGate: 25.0}
|
|
55
|
-
heat_rate_GHz = {q0: 1e-5, q1: 2e-5}
|
|
56
|
-
cool_rate_GHz = {q0: 1e-4, q1: 2e-4}
|
|
57
|
-
dephase_rate_GHz = {q0: 3e-4, q1: 4e-4}
|
|
54
|
+
gate_durations: dict[type, float] = {cirq.PhasedXZGate: 25.0}
|
|
55
|
+
heat_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-5, q1: 2e-5}
|
|
56
|
+
cool_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-4, q1: 2e-4}
|
|
57
|
+
dephase_rate_GHz: dict[cirq.Qid, float] = {q0: 3e-4, q1: 4e-4}
|
|
58
58
|
model = ThermalNoiseModel(
|
|
59
59
|
qubits={q0, q1},
|
|
60
60
|
gate_durations_ns=gate_durations,
|
|
@@ -69,11 +69,11 @@ def test_create_thermal_noise_per_qubit():
|
|
|
69
69
|
assert np.allclose(model.rate_matrix_GHz[q1], np.array([[0, 2e-4], [2e-5, 4e-4]]))
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
def test_create_thermal_noise_mixed_type():
|
|
72
|
+
def test_create_thermal_noise_mixed_type() -> None:
|
|
73
73
|
q0, q1 = cirq.LineQubit.range(2)
|
|
74
|
-
gate_durations = {cirq.PhasedXZGate: 25.0}
|
|
74
|
+
gate_durations: dict[type, float] = {cirq.PhasedXZGate: 25.0}
|
|
75
75
|
heat_rate_GHz = None
|
|
76
|
-
cool_rate_GHz = {q0: 1e-4, q1: 2e-4}
|
|
76
|
+
cool_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-4, q1: 2e-4}
|
|
77
77
|
dephase_rate_GHz = 3e-4
|
|
78
78
|
model = ThermalNoiseModel(
|
|
79
79
|
qubits={q0, q1},
|
|
@@ -89,11 +89,11 @@ def test_create_thermal_noise_mixed_type():
|
|
|
89
89
|
assert np.allclose(model.rate_matrix_GHz[q1], np.array([[0, 2e-4], [0, 3e-4]]))
|
|
90
90
|
|
|
91
91
|
|
|
92
|
-
def test_incomplete_rates():
|
|
92
|
+
def test_incomplete_rates() -> None:
|
|
93
93
|
q0, q1 = cirq.LineQubit.range(2)
|
|
94
|
-
gate_durations = {cirq.PhasedXZGate: 25.0}
|
|
95
|
-
heat_rate_GHz = {q1: 1e-5}
|
|
96
|
-
cool_rate_GHz = {q0: 1e-4}
|
|
94
|
+
gate_durations: dict[type, float] = {cirq.PhasedXZGate: 25.0}
|
|
95
|
+
heat_rate_GHz: dict[cirq.Qid, float] = {q1: 1e-5}
|
|
96
|
+
cool_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-4}
|
|
97
97
|
model = ThermalNoiseModel(
|
|
98
98
|
qubits={q0, q1},
|
|
99
99
|
gate_durations_ns=gate_durations,
|
|
@@ -108,12 +108,12 @@ def test_incomplete_rates():
|
|
|
108
108
|
assert np.allclose(model.rate_matrix_GHz[q1], np.array([[0, 0], [1e-5, 0]]))
|
|
109
109
|
|
|
110
110
|
|
|
111
|
-
def test_noise_from_empty_moment():
|
|
111
|
+
def test_noise_from_empty_moment() -> None:
|
|
112
112
|
# Verify that a moment with no duration has no noise.
|
|
113
113
|
q0, q1 = cirq.LineQubit.range(2)
|
|
114
|
-
gate_durations = {}
|
|
115
|
-
heat_rate_GHz = {q1: 1e-5}
|
|
116
|
-
cool_rate_GHz = {q0: 1e-4}
|
|
114
|
+
gate_durations: dict[type, float] = {}
|
|
115
|
+
heat_rate_GHz: dict[cirq.Qid, float] = {q1: 1e-5}
|
|
116
|
+
cool_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-4}
|
|
117
117
|
model = ThermalNoiseModel(
|
|
118
118
|
qubits={q0, q1},
|
|
119
119
|
gate_durations_ns=gate_durations,
|
|
@@ -127,12 +127,12 @@ def test_noise_from_empty_moment():
|
|
|
127
127
|
assert model.noisy_moment(moment, system_qubits=[q0, q1]) == [moment]
|
|
128
128
|
|
|
129
129
|
|
|
130
|
-
def test_noise_from_zero_duration():
|
|
130
|
+
def test_noise_from_zero_duration() -> None:
|
|
131
131
|
# Verify that a moment with no duration has no noise.
|
|
132
132
|
q0, q1 = cirq.LineQubit.range(2)
|
|
133
|
-
gate_durations = {}
|
|
134
|
-
heat_rate_GHz = {q1: 1e-5}
|
|
135
|
-
cool_rate_GHz = {q0: 1e-4}
|
|
133
|
+
gate_durations: dict[type, float] = {}
|
|
134
|
+
heat_rate_GHz: dict[cirq.Qid, float] = {q1: 1e-5}
|
|
135
|
+
cool_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-4}
|
|
136
136
|
model = ThermalNoiseModel(
|
|
137
137
|
qubits={q0, q1},
|
|
138
138
|
gate_durations_ns=gate_durations,
|
|
@@ -146,13 +146,13 @@ def test_noise_from_zero_duration():
|
|
|
146
146
|
assert model.noisy_moment(moment, system_qubits=[q0, q1]) == [moment]
|
|
147
147
|
|
|
148
148
|
|
|
149
|
-
def test_noise_from_virtual_gates():
|
|
149
|
+
def test_noise_from_virtual_gates() -> None:
|
|
150
150
|
# Verify that a moment with only virtual gates has no noise if
|
|
151
151
|
# require_physical_tag is True.
|
|
152
152
|
q0, q1 = cirq.LineQubit.range(2)
|
|
153
|
-
gate_durations = {cirq.ZPowGate: 25.0}
|
|
154
|
-
heat_rate_GHz = {q1: 1e-5}
|
|
155
|
-
cool_rate_GHz = {q0: 1e-4}
|
|
153
|
+
gate_durations: dict[type, float] = {cirq.ZPowGate: 25.0}
|
|
154
|
+
heat_rate_GHz: dict[cirq.Qid, float] = {q1: 1e-5}
|
|
155
|
+
cool_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-4}
|
|
156
156
|
model = ThermalNoiseModel(
|
|
157
157
|
qubits={q0, q1},
|
|
158
158
|
gate_durations_ns=gate_durations,
|
|
@@ -170,16 +170,16 @@ def test_noise_from_virtual_gates():
|
|
|
170
170
|
_ = model.noisy_moment(part_virtual_moment, system_qubits=[q0, q1])
|
|
171
171
|
|
|
172
172
|
model.require_physical_tag = False
|
|
173
|
-
assert len(model.noisy_moment(moment, system_qubits=[q0, q1])) == 2
|
|
173
|
+
assert len(model.noisy_moment(moment, system_qubits=[q0, q1])) == 2 # type: ignore[arg-type]
|
|
174
174
|
|
|
175
175
|
|
|
176
|
-
def test_noise_from_measurement():
|
|
176
|
+
def test_noise_from_measurement() -> None:
|
|
177
177
|
# Verify that a moment with only measurement gates has no noise if
|
|
178
178
|
# skip_measurements is True.
|
|
179
179
|
q0, q1 = cirq.LineQubit.range(2)
|
|
180
|
-
gate_durations = {cirq.ZPowGate: 25.0, cirq.MeasurementGate: 4000.0}
|
|
181
|
-
heat_rate_GHz = {q1: 1e-5}
|
|
182
|
-
cool_rate_GHz = {q0: 1e-4}
|
|
180
|
+
gate_durations: dict[type, float] = {cirq.ZPowGate: 25.0, cirq.MeasurementGate: 4000.0}
|
|
181
|
+
heat_rate_GHz: dict[cirq.Qid, float] = {q1: 1e-5}
|
|
182
|
+
cool_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-4}
|
|
183
183
|
model = ThermalNoiseModel(
|
|
184
184
|
qubits={q0, q1},
|
|
185
185
|
gate_durations_ns=gate_durations,
|
|
@@ -193,13 +193,13 @@ def test_noise_from_measurement():
|
|
|
193
193
|
assert model.noisy_moment(moment, system_qubits=[q0, q1]) == [moment]
|
|
194
194
|
|
|
195
195
|
part_measure_moment = cirq.Moment(cirq.measure(q0, key='m'), cirq.Z(q1))
|
|
196
|
-
assert len(model.noisy_moment(part_measure_moment, system_qubits=[q0, q1])) == 2
|
|
196
|
+
assert len(model.noisy_moment(part_measure_moment, system_qubits=[q0, q1])) == 2 # type: ignore[arg-type]
|
|
197
197
|
|
|
198
198
|
model.skip_measurements = False
|
|
199
|
-
assert len(model.noisy_moment(moment, system_qubits=[q0, q1])) == 2
|
|
199
|
+
assert len(model.noisy_moment(moment, system_qubits=[q0, q1])) == 2 # type: ignore[arg-type]
|
|
200
200
|
|
|
201
201
|
|
|
202
|
-
def test_noisy_moment_one_qubit():
|
|
202
|
+
def test_noisy_moment_one_qubit() -> None:
|
|
203
203
|
q0, q1 = cirq.LineQubit.range(2)
|
|
204
204
|
model = ThermalNoiseModel(
|
|
205
205
|
qubits={q0, q1},
|
|
@@ -212,6 +212,7 @@ def test_noisy_moment_one_qubit():
|
|
|
212
212
|
gate = cirq.PhasedXZGate(x_exponent=1, z_exponent=0.5, axis_phase_exponent=0.25)
|
|
213
213
|
moment = cirq.Moment(gate.on(q0))
|
|
214
214
|
noisy_moment = model.noisy_moment(moment, system_qubits=[q0, q1])
|
|
215
|
+
assert isinstance(noisy_moment, list)
|
|
215
216
|
assert noisy_moment[0] == moment
|
|
216
217
|
# Noise applies to both qubits, even if only one is acted upon.
|
|
217
218
|
assert len(noisy_moment[1]) == 2
|
|
@@ -227,7 +228,7 @@ def test_noisy_moment_one_qubit():
|
|
|
227
228
|
)
|
|
228
229
|
|
|
229
230
|
|
|
230
|
-
def test_noisy_moment_one_qubit_prepend():
|
|
231
|
+
def test_noisy_moment_one_qubit_prepend() -> None:
|
|
231
232
|
q0, q1 = cirq.LineQubit.range(2)
|
|
232
233
|
model = ThermalNoiseModel(
|
|
233
234
|
qubits={q0, q1},
|
|
@@ -241,6 +242,7 @@ def test_noisy_moment_one_qubit_prepend():
|
|
|
241
242
|
gate = cirq.PhasedXZGate(x_exponent=1, z_exponent=0.5, axis_phase_exponent=0.25)
|
|
242
243
|
moment = cirq.Moment(gate.on(q0))
|
|
243
244
|
noisy_moment = model.noisy_moment(moment, system_qubits=[q0, q1])
|
|
245
|
+
assert isinstance(noisy_moment, list)
|
|
244
246
|
# Noise applies to both qubits, even if only one is acted upon.
|
|
245
247
|
assert len(noisy_moment[0]) == 2
|
|
246
248
|
noisy_choi = cirq.kraus_to_choi(cirq.kraus(noisy_moment[0].operations[0]))
|
|
@@ -257,12 +259,12 @@ def test_noisy_moment_one_qubit_prepend():
|
|
|
257
259
|
assert noisy_moment[1] == moment
|
|
258
260
|
|
|
259
261
|
|
|
260
|
-
def test_noise_from_wait():
|
|
262
|
+
def test_noise_from_wait() -> None:
|
|
261
263
|
# Verify that wait-gate noise is duration-dependent.
|
|
262
264
|
q0 = cirq.LineQubit(0)
|
|
263
|
-
gate_durations = {cirq.ZPowGate: 25.0}
|
|
264
|
-
heat_rate_GHz = {q0: 1e-5}
|
|
265
|
-
cool_rate_GHz = {q0: 1e-4}
|
|
265
|
+
gate_durations: dict[type, float] = {cirq.ZPowGate: 25.0}
|
|
266
|
+
heat_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-5}
|
|
267
|
+
cool_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-4}
|
|
266
268
|
model = ThermalNoiseModel(
|
|
267
269
|
qubits={q0},
|
|
268
270
|
gate_durations_ns=gate_durations,
|
|
@@ -274,6 +276,7 @@ def test_noise_from_wait():
|
|
|
274
276
|
)
|
|
275
277
|
moment = cirq.Moment(cirq.wait(q0, nanos=100))
|
|
276
278
|
noisy_moment = model.noisy_moment(moment, system_qubits=[q0])
|
|
279
|
+
assert isinstance(noisy_moment, list)
|
|
277
280
|
assert noisy_moment[0] == moment
|
|
278
281
|
assert len(noisy_moment[1]) == 1
|
|
279
282
|
noisy_choi = cirq.kraus_to_choi(cirq.kraus(noisy_moment[1].operations[0]))
|
|
@@ -288,11 +291,11 @@ def test_noise_from_wait():
|
|
|
288
291
|
)
|
|
289
292
|
|
|
290
293
|
|
|
291
|
-
def test_symbolic_times_for_wait_gate():
|
|
294
|
+
def test_symbolic_times_for_wait_gate() -> None:
|
|
292
295
|
q0 = cirq.LineQubit(0)
|
|
293
|
-
gate_durations = {cirq.ZPowGate: 25.0}
|
|
294
|
-
heat_rate_GHz = {q0: 1e-5}
|
|
295
|
-
cool_rate_GHz = {q0: 1e-4}
|
|
296
|
+
gate_durations: dict[type, float] = {cirq.ZPowGate: 25.0}
|
|
297
|
+
heat_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-5}
|
|
298
|
+
cool_rate_GHz: dict[cirq.Qid, float] = {q0: 1e-4}
|
|
296
299
|
model = ThermalNoiseModel(
|
|
297
300
|
qubits={q0},
|
|
298
301
|
gate_durations_ns=gate_durations,
|
|
@@ -307,7 +310,7 @@ def test_symbolic_times_for_wait_gate():
|
|
|
307
310
|
_ = model.noisy_moment(moment, system_qubits=[q0])
|
|
308
311
|
|
|
309
312
|
|
|
310
|
-
def test_noisy_moment_two_qubit():
|
|
313
|
+
def test_noisy_moment_two_qubit() -> None:
|
|
311
314
|
q0, q1 = cirq.LineQubit.range(2)
|
|
312
315
|
model = ThermalNoiseModel(
|
|
313
316
|
qubits={q0, q1},
|
|
@@ -320,6 +323,7 @@ def test_noisy_moment_two_qubit():
|
|
|
320
323
|
gate = cirq.CZ**0.5
|
|
321
324
|
moment = cirq.Moment(gate.on(q0, q1))
|
|
322
325
|
noisy_moment = model.noisy_moment(moment, system_qubits=[q0, q1])
|
|
326
|
+
assert isinstance(noisy_moment, list)
|
|
323
327
|
assert noisy_moment[0] == moment
|
|
324
328
|
assert len(noisy_moment[1]) == 2
|
|
325
329
|
noisy_choi_0 = cirq.kraus_to_choi(cirq.kraus(noisy_moment[1].operations[0]))
|
|
@@ -344,7 +348,7 @@ def test_noisy_moment_two_qubit():
|
|
|
344
348
|
)
|
|
345
349
|
|
|
346
350
|
|
|
347
|
-
def test_repr():
|
|
351
|
+
def test_repr() -> None:
|
|
348
352
|
q0 = cirq.LineQubit(0)
|
|
349
353
|
model = ThermalNoiseModel(
|
|
350
354
|
qubits={q0},
|
|
@@ -47,5 +47,5 @@ class _UnconstrainedDevice(device.Device):
|
|
|
47
47
|
return protocols.obj_to_dict_helper(self, [])
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
UNCONSTRAINED_DEVICE
|
|
50
|
+
UNCONSTRAINED_DEVICE = _UnconstrainedDevice()
|
|
51
51
|
document(UNCONSTRAINED_DEVICE, """A device with no constraints on operations or qubits.""")
|
|
@@ -17,17 +17,17 @@ from __future__ import annotations
|
|
|
17
17
|
import cirq
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def test_repr():
|
|
20
|
+
def test_repr() -> None:
|
|
21
21
|
cirq.testing.assert_equivalent_repr(cirq.UNCONSTRAINED_DEVICE)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
def test_infinitely_fast():
|
|
24
|
+
def test_infinitely_fast() -> None:
|
|
25
25
|
assert cirq.UNCONSTRAINED_DEVICE.duration_of(cirq.X(cirq.NamedQubit('a'))) == cirq.Duration(
|
|
26
26
|
picos=0
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
def test_any_qubit_works():
|
|
30
|
+
def test_any_qubit_works() -> None:
|
|
31
31
|
moment = cirq.Moment([cirq.X(cirq.LineQubit(987654321))])
|
|
32
32
|
cirq.UNCONSTRAINED_DEVICE.validate_moment(moment)
|
|
33
33
|
cirq.UNCONSTRAINED_DEVICE.validate_circuit(cirq.Circuit(moment))
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
from concurrent import futures
|
|
20
|
-
from typing import overload, Sequence, TYPE_CHECKING, Union
|
|
20
|
+
from typing import Iterable, Mapping, overload, Sequence, TYPE_CHECKING, Union
|
|
21
21
|
|
|
22
22
|
import attrs
|
|
23
23
|
import networkx as nx
|
|
@@ -34,14 +34,18 @@ if TYPE_CHECKING:
|
|
|
34
34
|
|
|
35
35
|
_TARGET_T = Union['cirq.Gate', 'cirq.Operation', 'cirq.AbstractCircuit']
|
|
36
36
|
_QUBIT_PAIR_T = tuple['cirq.GridQubit', 'cirq.GridQubit']
|
|
37
|
-
_CANONICAL_TARGET_T = Union['cirq.Operation',
|
|
38
|
-
_PROBABILITIES_DICT_T =
|
|
37
|
+
_CANONICAL_TARGET_T = Union['cirq.Operation', Mapping[_QUBIT_PAIR_T, 'cirq.Operation']]
|
|
38
|
+
_PROBABILITIES_DICT_T = Mapping[_QUBIT_PAIR_T, list[list[np.ndarray]]]
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def _canonize_pair(pair: _QUBIT_PAIR_T) -> _QUBIT_PAIR_T:
|
|
42
42
|
return min(pair), max(pair)
|
|
43
43
|
|
|
44
44
|
|
|
45
|
+
def _tuple_from_ints(seq: Iterable[int]) -> tuple[int, ...]:
|
|
46
|
+
return tuple(seq)
|
|
47
|
+
|
|
48
|
+
|
|
45
49
|
@attrs.frozen
|
|
46
50
|
class XEBParameters:
|
|
47
51
|
"""A frozen dataclass that holds the parameter of an XEB experiment.
|
|
@@ -56,7 +60,9 @@ class XEBParameters:
|
|
|
56
60
|
n_repetitions: int = 10**4
|
|
57
61
|
n_combinations: int = 10
|
|
58
62
|
n_circuits: int = 20
|
|
59
|
-
cycle_depths: tuple[int, ...] = attrs.field(
|
|
63
|
+
cycle_depths: tuple[int, ...] = attrs.field(
|
|
64
|
+
default=(5, 25, 50, 100, 200, 300), converter=_tuple_from_ints
|
|
65
|
+
)
|
|
60
66
|
|
|
61
67
|
|
|
62
68
|
@attrs.frozen
|
|
@@ -75,7 +81,7 @@ class XEBWideCircuitInfo:
|
|
|
75
81
|
pairs: Sequence[_QUBIT_PAIR_T] = attrs.field(
|
|
76
82
|
converter=lambda seq: [_canonize_pair(pair) for pair in seq]
|
|
77
83
|
)
|
|
78
|
-
narrow_template_indices: tuple[int, ...] = attrs.field(converter=
|
|
84
|
+
narrow_template_indices: tuple[int, ...] = attrs.field(converter=_tuple_from_ints)
|
|
79
85
|
cycle_depth: int | None = None
|
|
80
86
|
|
|
81
87
|
@staticmethod
|
|
@@ -166,7 +172,7 @@ def _target_to_operation(target: _TARGET_T) -> cirq.Operation:
|
|
|
166
172
|
return target
|
|
167
173
|
|
|
168
174
|
|
|
169
|
-
def _canonize_target(target: _TARGET_T |
|
|
175
|
+
def _canonize_target(target: _TARGET_T | Mapping[_QUBIT_PAIR_T, _TARGET_T]) -> _CANONICAL_TARGET_T:
|
|
170
176
|
if isinstance(target, (ops.Gate, ops.Operation, circuits.AbstractCircuit)):
|
|
171
177
|
return _target_to_operation(target)
|
|
172
178
|
return {k: _target_to_operation(v) for k, v in target.items()}
|
|
@@ -272,10 +278,10 @@ def simulate_circuit_library(
|
|
|
272
278
|
@overload
|
|
273
279
|
def simulate_circuit_library(
|
|
274
280
|
circuit_templates: Sequence[cirq.Circuit],
|
|
275
|
-
target_or_dict:
|
|
281
|
+
target_or_dict: Mapping[_QUBIT_PAIR_T, ops.Operation],
|
|
276
282
|
cycle_depths: Sequence[int],
|
|
277
283
|
pool: futures.Executor | None = None,
|
|
278
|
-
) ->
|
|
284
|
+
) -> Mapping[_QUBIT_PAIR_T, Sequence[Sequence[np.ndarray]]]: ...
|
|
279
285
|
|
|
280
286
|
|
|
281
287
|
def simulate_circuit_library(
|
|
@@ -283,7 +289,7 @@ def simulate_circuit_library(
|
|
|
283
289
|
target_or_dict: _CANONICAL_TARGET_T,
|
|
284
290
|
cycle_depths: Sequence[int],
|
|
285
291
|
pool: futures.Executor | None = None,
|
|
286
|
-
) -> Sequence[Sequence[np.ndarray]] |
|
|
292
|
+
) -> Sequence[Sequence[np.ndarray]] | Mapping[_QUBIT_PAIR_T, Sequence[Sequence[np.ndarray]]]:
|
|
287
293
|
"""Simulate the given sequence of circuits.
|
|
288
294
|
|
|
289
295
|
Args:
|
|
@@ -407,15 +413,16 @@ def _reshape_sampling_results(
|
|
|
407
413
|
|
|
408
414
|
def _reshape_simulation_results(
|
|
409
415
|
simulation_results: (
|
|
410
|
-
Sequence[Sequence[np.ndarray]] |
|
|
416
|
+
Sequence[Sequence[np.ndarray]] | Mapping[_QUBIT_PAIR_T, Sequence[Sequence[np.ndarray]]]
|
|
411
417
|
),
|
|
412
418
|
cycle_depths: Sequence[int],
|
|
413
419
|
pairs: Sequence[_QUBIT_PAIR_T],
|
|
414
420
|
num_templates: int,
|
|
415
421
|
) -> _PROBABILITIES_DICT_T:
|
|
422
|
+
cycle_depth_to_index: dict[int, int]
|
|
416
423
|
cycle_depth_to_index = {d: i for i, d in enumerate(cycle_depths)}
|
|
417
424
|
|
|
418
|
-
if isinstance(simulation_results,
|
|
425
|
+
if isinstance(simulation_results, Mapping):
|
|
419
426
|
pure_probabilities = {
|
|
420
427
|
pair: [[np.empty(0)] * num_templates for _ in range(len(cycle_depths))]
|
|
421
428
|
for pair in pairs
|
|
@@ -463,7 +470,7 @@ def _cross_entropy(p: np.ndarray, q: np.ndarray, eps: float = 1e-60) -> float:
|
|
|
463
470
|
def estimate_fidelities(
|
|
464
471
|
sampling_results: Sequence[dict[str, np.ndarray]],
|
|
465
472
|
simulation_results: (
|
|
466
|
-
Sequence[Sequence[np.ndarray]] |
|
|
473
|
+
Sequence[Sequence[np.ndarray]] | Mapping[_QUBIT_PAIR_T, Sequence[Sequence[np.ndarray]]]
|
|
467
474
|
),
|
|
468
475
|
cycle_depths: Sequence[int],
|
|
469
476
|
wide_circuits_info: Sequence[XEBWideCircuitInfo],
|
|
@@ -525,7 +532,7 @@ def estimate_fidelities(
|
|
|
525
532
|
|
|
526
533
|
def _extract_pairs(
|
|
527
534
|
sampler: cirq.Sampler,
|
|
528
|
-
target: _TARGET_T |
|
|
535
|
+
target: _TARGET_T | Mapping[_QUBIT_PAIR_T, _TARGET_T],
|
|
529
536
|
qubits: Sequence[cirq.GridQubit] | None,
|
|
530
537
|
pairs: Sequence[_QUBIT_PAIR_T] | None,
|
|
531
538
|
) -> Sequence[_QUBIT_PAIR_T]:
|
|
@@ -545,8 +552,8 @@ def _extract_pairs(
|
|
|
545
552
|
|
|
546
553
|
def parallel_xeb_workflow(
|
|
547
554
|
sampler: cirq.Sampler,
|
|
548
|
-
target: _TARGET_T |
|
|
549
|
-
ideal_target: _TARGET_T |
|
|
555
|
+
target: _TARGET_T | Mapping[_QUBIT_PAIR_T, _TARGET_T],
|
|
556
|
+
ideal_target: _TARGET_T | Mapping[_QUBIT_PAIR_T, _TARGET_T] | None = None,
|
|
550
557
|
qubits: Sequence[cirq.GridQubit] | None = None,
|
|
551
558
|
pairs: Sequence[_QUBIT_PAIR_T] | None = None,
|
|
552
559
|
parameters: XEBParameters = XEBParameters(),
|
|
@@ -644,8 +651,8 @@ def parallel_xeb_workflow(
|
|
|
644
651
|
|
|
645
652
|
def parallel_two_qubit_xeb(
|
|
646
653
|
sampler: cirq.Sampler,
|
|
647
|
-
target: _TARGET_T |
|
|
648
|
-
ideal_target: _TARGET_T |
|
|
654
|
+
target: _TARGET_T | Mapping[_QUBIT_PAIR_T, _TARGET_T],
|
|
655
|
+
ideal_target: _TARGET_T | Mapping[_QUBIT_PAIR_T, _TARGET_T] | None = None,
|
|
649
656
|
qubits: Sequence[cirq.GridQubit] | None = None,
|
|
650
657
|
pairs: Sequence[_QUBIT_PAIR_T] | None = None,
|
|
651
658
|
parameters: XEBParameters = XEBParameters(),
|