cirq-core 1.5.0.dev20250122072446__py3-none-any.whl → 1.5.0.dev20250122193029__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 CHANGED
@@ -28,4 +28,4 @@ if sys.version_info < (3, 10, 0): # pragma: no cover
28
28
  'of cirq (e.g. "python -m pip install cirq==1.1.*")'
29
29
  )
30
30
 
31
- __version__ = "1.5.0.dev20250122072446"
31
+ __version__ = "1.5.0.dev20250122193029"
cirq/_version_test.py CHANGED
@@ -3,4 +3,4 @@ import cirq
3
3
 
4
4
 
5
5
  def test_version():
6
- assert cirq.__version__ == "1.5.0.dev20250122072446"
6
+ assert cirq.__version__ == "1.5.0.dev20250122193029"
@@ -0,0 +1,18 @@
1
+ # Copyright 2025 The Cirq Developers
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Utility for shuffling circuits and do readout error benchmarking."""
15
+
16
+ from cirq.contrib.shuffle_circuits.shuffle_circuits_with_readout_benchmarking import (
17
+ run_shuffled_with_readout_benchmarking as run_shuffled_with_readout_benchmarking,
18
+ )
@@ -0,0 +1,229 @@
1
+ # Copyright 2025 The Cirq Developers
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Tools for running circuits in a shuffled order with readout error benchmarking."""
15
+ import time
16
+ from typing import Optional, Union
17
+
18
+ import numpy as np
19
+
20
+ from cirq import ops, circuits, work, protocols
21
+ from cirq.experiments import SingleQubitReadoutCalibrationResult
22
+ from cirq.study import ResultDict
23
+
24
+
25
+ def _validate_input(
26
+ input_circuits: list[circuits.Circuit],
27
+ circuit_repetitions: Union[int, list[int]],
28
+ rng_or_seed: Union[np.random.Generator, int],
29
+ num_random_bitstrings: int,
30
+ readout_repetitions: int,
31
+ ):
32
+ if not input_circuits:
33
+ raise ValueError("Input circuits must not be empty.")
34
+ # Check input_circuits type is cirq.circuits
35
+ if not all(isinstance(circuit, circuits.Circuit) for circuit in input_circuits):
36
+ raise ValueError("Input circuits must be of type cirq.Circuit.")
37
+ # Check input_circuits have measurements
38
+ for circuit in input_circuits:
39
+ if not any(protocols.is_measurement(circuit) for op in circuit.all_operations()):
40
+ raise ValueError("Input circuits must have measurements.")
41
+
42
+ # Check circuit_repetitions
43
+ if isinstance(circuit_repetitions, int):
44
+ if circuit_repetitions <= 0:
45
+ raise ValueError("Must provide non-zero circuit_repetitions.")
46
+ if isinstance(circuit_repetitions, list) and len(circuit_repetitions) != len(input_circuits):
47
+ raise ValueError("Number of circuit_repetitions must match the number of input circuits.")
48
+
49
+ # Check rng is a numpy random generator
50
+ if not isinstance(rng_or_seed, np.random.Generator) and not isinstance(rng_or_seed, int):
51
+ raise ValueError("Must provide a numpy random generator or a seed")
52
+
53
+ # Check num_random_bitstrings is bigger than 0
54
+ if num_random_bitstrings <= 0:
55
+ raise ValueError("Must provide non-zero num_random_bitstrings.")
56
+
57
+ # Check readout_repetitions is bigger than 0
58
+ if readout_repetitions <= 0:
59
+ raise ValueError("Must provide non-zero readout_repetitions for readout calibration.")
60
+
61
+
62
+ def _generate_readout_calibration_circuits(
63
+ qubits: list[ops.Qid], rng: np.random.Generator, num_random_bitstrings: int
64
+ ) -> tuple[list[circuits.Circuit], np.ndarray]:
65
+ """Generates the readout calibration circuits with random bitstrings."""
66
+ bit_to_gate = (ops.I, ops.X)
67
+
68
+ random_bitstrings = rng.integers(0, 2, size=(num_random_bitstrings, len(qubits)))
69
+
70
+ readout_calibration_circuits = []
71
+ for bitstr in random_bitstrings:
72
+ readout_calibration_circuits.append(
73
+ circuits.Circuit(
74
+ [bit_to_gate[bit](qubit) for bit, qubit in zip(bitstr, qubits)]
75
+ + [ops.M(qubits, key="m")]
76
+ )
77
+ )
78
+ return readout_calibration_circuits, random_bitstrings
79
+
80
+
81
+ def _shuffle_circuits(
82
+ all_circuits: list[circuits.Circuit], all_repetitions: list[int], rng: np.random.Generator
83
+ ) -> tuple[list[circuits.Circuit], list[int], np.ndarray]:
84
+ """Shuffles the input circuits and readout calibration circuits."""
85
+ shuf_order = rng.permutation(len(all_circuits))
86
+ unshuf_order = np.zeros_like(shuf_order) # Inverse permutation
87
+ unshuf_order[shuf_order] = np.arange(len(all_circuits))
88
+ shuffled_circuits = [all_circuits[i] for i in shuf_order]
89
+ all_repetitions = [all_repetitions[i] for i in shuf_order]
90
+ return shuffled_circuits, all_repetitions, unshuf_order
91
+
92
+
93
+ def _analyze_readout_results(
94
+ unshuffled_readout_measurements: list[ResultDict],
95
+ random_bitstrings: np.ndarray,
96
+ readout_repetitions: int,
97
+ qubits: list[ops.Qid],
98
+ timestamp: float,
99
+ ) -> SingleQubitReadoutCalibrationResult:
100
+ """Analyzes the readout error rates from the unshuffled measurements.
101
+
102
+ Args:
103
+ readout_measurements: A list of dictionaries containing the measurement results
104
+ for each readout calibration circuit.
105
+ random_bitstrings: A numpy array of random bitstrings used for measuring readout.
106
+ readout_repetitions: The number of repetitions for each readout bitstring.
107
+ qubits: The list of qubits for which the readout error rates are to be calculated.
108
+
109
+ Returns:
110
+ A dictionary mapping each qubit to a tuple of readout error rates(e0 and e1),
111
+ where e0 is the 0->1 readout error rate and e1 is the 1->0 readout error rate.
112
+ """
113
+
114
+ zero_state_trials = np.zeros((1, len(qubits)), dtype=np.int64)
115
+ one_state_trials = np.zeros((1, len(qubits)), dtype=np.int64)
116
+ zero_state_totals = np.zeros((1, len(qubits)), dtype=np.int64)
117
+ one_state_totals = np.zeros((1, len(qubits)), dtype=np.int64)
118
+ for measurement_result, bitstr in zip(unshuffled_readout_measurements, random_bitstrings):
119
+ for _, trial_result in measurement_result.measurements.items():
120
+ trial_result = trial_result.astype(np.int64) # Cast to int64
121
+ sample_counts = np.sum(trial_result, axis=0)
122
+
123
+ zero_state_trials += sample_counts * (1 - bitstr)
124
+ zero_state_totals += readout_repetitions * (1 - bitstr)
125
+ one_state_trials += (readout_repetitions - sample_counts) * bitstr
126
+ one_state_totals += readout_repetitions * bitstr
127
+
128
+ zero_state_errors = {
129
+ q: (
130
+ zero_state_trials[0][qubit_idx] / zero_state_totals[0][qubit_idx]
131
+ if zero_state_totals[0][qubit_idx] > 0
132
+ else np.nan
133
+ )
134
+ for qubit_idx, q in enumerate(qubits)
135
+ }
136
+
137
+ one_state_errors = {
138
+ q: (
139
+ one_state_trials[0][qubit_idx] / one_state_totals[0][qubit_idx]
140
+ if one_state_totals[0][qubit_idx] > 0
141
+ else np.nan
142
+ )
143
+ for qubit_idx, q in enumerate(qubits)
144
+ }
145
+ return SingleQubitReadoutCalibrationResult(
146
+ zero_state_errors=zero_state_errors,
147
+ one_state_errors=one_state_errors,
148
+ repetitions=readout_repetitions,
149
+ timestamp=timestamp,
150
+ )
151
+
152
+
153
+ def run_shuffled_with_readout_benchmarking(
154
+ input_circuits: list[circuits.Circuit],
155
+ sampler: work.Sampler,
156
+ circuit_repetitions: Union[int, list[int]],
157
+ rng_or_seed: Union[np.random.Generator, int],
158
+ num_random_bitstrings: int = 100,
159
+ readout_repetitions: int = 1000,
160
+ qubits: Optional[list[ops.Qid]] = None,
161
+ ) -> tuple[list[ResultDict], SingleQubitReadoutCalibrationResult]:
162
+ """Run the circuits in a shuffled order with readout error benchmarking.
163
+
164
+ Args:
165
+ input_circuits: The circuits to run.
166
+ sampler: The sampler to use.
167
+ circuit_repetitions: The repetitions for `circuits`.
168
+ rng_or_seed: A random number generator used to generate readout circuits.
169
+ Or an integer seed.
170
+ num_random_bitstrings: The number of random bitstrings for measuring readout.
171
+ readout_repetitions: The number of repetitions for each readout bitstring.
172
+ qubits: The qubits to benchmark readout errors. If None, all qubits in the
173
+ input_circuits are used.
174
+
175
+ Returns:
176
+ A tuple containing:
177
+ - A list of dictionaries with the unshuffled measurement results.
178
+ - A dictionary mapping each qubit to a tuple of readout error rates(e0 and e1),
179
+ where e0 is the 0->1 readout error rate and e1 is the 1->0 readout error rate.
180
+
181
+ """
182
+
183
+ _validate_input(
184
+ input_circuits, circuit_repetitions, rng_or_seed, num_random_bitstrings, readout_repetitions
185
+ )
186
+
187
+ # If input qubits is None, extract qubits from input circuits
188
+ if qubits is None:
189
+ qubits_set: set[ops.Qid] = set()
190
+ for circuit in input_circuits:
191
+ qubits_set.update(circuit.all_qubits())
192
+ qubits = sorted(qubits_set)
193
+
194
+ # Generate the readout calibration circuits
195
+ rng = (
196
+ rng_or_seed
197
+ if isinstance(rng_or_seed, np.random.Generator)
198
+ else np.random.default_rng(rng_or_seed)
199
+ )
200
+ readout_calibration_circuits, random_bitstrings = _generate_readout_calibration_circuits(
201
+ qubits, rng, num_random_bitstrings
202
+ )
203
+
204
+ # Shuffle the circuits
205
+ if isinstance(circuit_repetitions, int):
206
+ circuit_repetitions = [circuit_repetitions] * len(input_circuits)
207
+ all_repetitions = circuit_repetitions + [readout_repetitions] * len(
208
+ readout_calibration_circuits
209
+ )
210
+
211
+ shuffled_circuits, all_repetitions, unshuf_order = _shuffle_circuits(
212
+ input_circuits + readout_calibration_circuits, all_repetitions, rng
213
+ )
214
+
215
+ # Run the shuffled circuits and measure
216
+ results = sampler.run_batch(shuffled_circuits, repetitions=all_repetitions)
217
+ timestamp = time.time()
218
+ shuffled_measurements = [res[0] for res in results]
219
+ unshuffled_measurements = [shuffled_measurements[i] for i in unshuf_order]
220
+
221
+ unshuffled_input_circuits_measiurements = unshuffled_measurements[: len(input_circuits)]
222
+ unshuffled_readout_measurements = unshuffled_measurements[len(input_circuits) :]
223
+
224
+ # Analyze results
225
+ readout_calibration_results = _analyze_readout_results(
226
+ unshuffled_readout_measurements, random_bitstrings, readout_repetitions, qubits, timestamp
227
+ )
228
+
229
+ return unshuffled_input_circuits_measiurements, readout_calibration_results
@@ -0,0 +1,302 @@
1
+ # Copyright 2025 The Cirq Developers
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import pytest
16
+
17
+ import cirq
18
+ import numpy as np
19
+
20
+ from cirq.experiments.single_qubit_readout_calibration_test import NoisySingleQubitReadoutSampler
21
+ from cirq.experiments import random_quantum_circuit_generation as rqcg
22
+ from cirq.experiments import SingleQubitReadoutCalibrationResult
23
+ from cirq.study import ResultDict
24
+
25
+
26
+ def test_shuffled_circuits_with_readout_benchmarking_errors_no_noise():
27
+ """Test shuffled circuits with readout benchmarking with no noise from sampler."""
28
+ qubits = cirq.LineQubit.range(5)
29
+
30
+ # Generate random input circuits
31
+ input_circuits = []
32
+ input_circuits += rqcg.generate_library_of_2q_circuits(
33
+ n_library_circuits=5, two_qubit_gate=cirq.ISWAP**0.5, q0=qubits[0], q1=qubits[2]
34
+ )
35
+ input_circuits += rqcg.generate_library_of_2q_circuits(
36
+ n_library_circuits=5, two_qubit_gate=cirq.CNOT**0.5, q0=qubits[1], q1=qubits[3]
37
+ )
38
+ input_circuits += rqcg.generate_library_of_2q_circuits(
39
+ n_library_circuits=5, two_qubit_gate=cirq.CNOT**0.5, q0=qubits[0], q1=qubits[4]
40
+ )
41
+ input_circuits += rqcg.generate_library_of_2q_circuits(
42
+ n_library_circuits=5, two_qubit_gate=cirq.ISWAP**0.5, q0=qubits[2], q1=qubits[4]
43
+ )
44
+ for circuit in input_circuits:
45
+ circuit.append(cirq.measure(*qubits, key="m"))
46
+
47
+ sampler = cirq.Simulator()
48
+ circuit_repetitions = 1
49
+ # allow passing a seed
50
+ rng = 123
51
+ readout_repetitions = 1000
52
+
53
+ measurements, readout_calibration_results = (
54
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
55
+ input_circuits,
56
+ sampler,
57
+ circuit_repetitions,
58
+ rng,
59
+ num_random_bitstrings=100,
60
+ readout_repetitions=readout_repetitions,
61
+ )
62
+ )
63
+
64
+ for measurement in measurements:
65
+ assert isinstance(measurement, ResultDict)
66
+
67
+ assert isinstance(readout_calibration_results, SingleQubitReadoutCalibrationResult)
68
+
69
+ assert readout_calibration_results.zero_state_errors == {q: 0 for q in qubits}
70
+ assert readout_calibration_results.one_state_errors == {q: 0 for q in qubits}
71
+ assert readout_calibration_results.repetitions == readout_repetitions
72
+ assert isinstance(readout_calibration_results.timestamp, float)
73
+
74
+
75
+ def test_shuffled_circuits_with_readout_benchmarking_errors_with_noise():
76
+ """Test shuffled circuits with readout benchmarking with noise from sampler."""
77
+ qubits = cirq.LineQubit.range(6)
78
+
79
+ # Generate random input circuits
80
+ input_circuits = []
81
+ input_circuits += rqcg.generate_library_of_2q_circuits(
82
+ n_library_circuits=5, two_qubit_gate=cirq.ISWAP**0.5, q0=qubits[0], q1=qubits[1]
83
+ )
84
+ input_circuits += rqcg.generate_library_of_2q_circuits(
85
+ n_library_circuits=5, two_qubit_gate=cirq.CNOT**0.5, q0=qubits[1], q1=qubits[3]
86
+ )
87
+ input_circuits += rqcg.generate_library_of_2q_circuits(
88
+ n_library_circuits=5, two_qubit_gate=cirq.CNOT**0.5, q0=qubits[0], q1=qubits[4]
89
+ )
90
+ input_circuits += rqcg.generate_library_of_2q_circuits(
91
+ n_library_circuits=5, two_qubit_gate=cirq.ISWAP**0.5, q0=qubits[2], q1=qubits[4]
92
+ )
93
+ input_circuits += rqcg.generate_library_of_2q_circuits(
94
+ n_library_circuits=5, two_qubit_gate=cirq.ISWAP**0.5, q0=qubits[2], q1=qubits[5]
95
+ )
96
+ for circuit in input_circuits:
97
+ circuit.append(cirq.measure(*qubits, key="m"))
98
+
99
+ sampler = NoisySingleQubitReadoutSampler(p0=0.1, p1=0.2, seed=1234)
100
+ circuit_repetitions = 1
101
+ rng = np.random.default_rng()
102
+ readout_repetitions = 1000
103
+
104
+ measurements, readout_calibration_results = (
105
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
106
+ input_circuits,
107
+ sampler,
108
+ circuit_repetitions,
109
+ rng,
110
+ num_random_bitstrings=100,
111
+ readout_repetitions=readout_repetitions,
112
+ )
113
+ )
114
+
115
+ for measurement in measurements:
116
+ assert isinstance(measurement, ResultDict)
117
+
118
+ assert isinstance(readout_calibration_results, SingleQubitReadoutCalibrationResult)
119
+
120
+ for error in readout_calibration_results.zero_state_errors.values():
121
+ assert 0.08 < error < 0.12
122
+ for error in readout_calibration_results.one_state_errors.values():
123
+ assert 0.18 < error < 0.22
124
+ assert readout_calibration_results.repetitions == readout_repetitions
125
+ assert isinstance(readout_calibration_results.timestamp, float)
126
+
127
+
128
+ def test_shuffled_circuits_with_readout_benchmarking_errors_with_noise_and_input_qubits():
129
+ """Test shuffled circuits with readout benchmarking with noise from sampler and input qubits."""
130
+ qubits = cirq.LineQubit.range(6)
131
+ readout_qubits = qubits[:4]
132
+
133
+ # Generate random input circuits
134
+ input_circuits = []
135
+ input_circuits += rqcg.generate_library_of_2q_circuits(
136
+ n_library_circuits=5, two_qubit_gate=cirq.ISWAP**0.5, q0=qubits[0], q1=qubits[1]
137
+ )
138
+ input_circuits += rqcg.generate_library_of_2q_circuits(
139
+ n_library_circuits=5, two_qubit_gate=cirq.CNOT**0.5, q0=qubits[1], q1=qubits[3]
140
+ )
141
+ input_circuits += rqcg.generate_library_of_2q_circuits(
142
+ n_library_circuits=5, two_qubit_gate=cirq.CNOT**0.5, q0=qubits[0], q1=qubits[4]
143
+ )
144
+ input_circuits += rqcg.generate_library_of_2q_circuits(
145
+ n_library_circuits=5, two_qubit_gate=cirq.ISWAP**0.5, q0=qubits[2], q1=qubits[4]
146
+ )
147
+ input_circuits += rqcg.generate_library_of_2q_circuits(
148
+ n_library_circuits=5, two_qubit_gate=cirq.ISWAP**0.5, q0=qubits[2], q1=qubits[5]
149
+ )
150
+ for circuit in input_circuits:
151
+ circuit.append(cirq.measure(*qubits, key="m"))
152
+
153
+ sampler = NoisySingleQubitReadoutSampler(p0=0.1, p1=0.3, seed=1234)
154
+ circuit_repetitions = 1
155
+ rng = np.random.default_rng()
156
+ readout_repetitions = 1000
157
+
158
+ measurements, readout_calibration_results = (
159
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
160
+ input_circuits,
161
+ sampler,
162
+ circuit_repetitions,
163
+ rng,
164
+ num_random_bitstrings=100,
165
+ readout_repetitions=readout_repetitions,
166
+ qubits=readout_qubits,
167
+ )
168
+ )
169
+
170
+ for measurement in measurements:
171
+ assert isinstance(measurement, ResultDict)
172
+
173
+ assert isinstance(readout_calibration_results, SingleQubitReadoutCalibrationResult)
174
+
175
+ for error in readout_calibration_results.zero_state_errors.values():
176
+ assert 0.08 < error < 0.12
177
+ for error in readout_calibration_results.one_state_errors.values():
178
+ assert 0.28 < error < 0.32
179
+ assert readout_calibration_results.repetitions == readout_repetitions
180
+ assert isinstance(readout_calibration_results.timestamp, float)
181
+
182
+
183
+ def test_empty_input_circuits():
184
+ """Test that the input circuits are empty."""
185
+ with pytest.raises(ValueError, match="Input circuits must not be empty."):
186
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
187
+ [],
188
+ cirq.ZerosSampler(),
189
+ circuit_repetitions=10,
190
+ rng_or_seed=np.random.default_rng(456),
191
+ num_random_bitstrings=5,
192
+ readout_repetitions=100,
193
+ )
194
+
195
+
196
+ def test_non_circuit_input():
197
+ """Test that the input circuits are not of type cirq.Circuit."""
198
+ q = cirq.LineQubit(0)
199
+ with pytest.raises(ValueError, match="Input circuits must be of type cirq.Circuit."):
200
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
201
+ [q],
202
+ cirq.ZerosSampler(),
203
+ circuit_repetitions=10,
204
+ rng_or_seed=np.random.default_rng(456),
205
+ num_random_bitstrings=5,
206
+ readout_repetitions=100,
207
+ )
208
+
209
+
210
+ def test_no_measurements():
211
+ """Test that the input circuits don't have measurements."""
212
+ q = cirq.LineQubit(0)
213
+ circuit = cirq.Circuit(cirq.H(q))
214
+ with pytest.raises(ValueError, match="Input circuits must have measurements."):
215
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
216
+ [circuit],
217
+ cirq.ZerosSampler(),
218
+ circuit_repetitions=10,
219
+ rng_or_seed=np.random.default_rng(456),
220
+ num_random_bitstrings=5,
221
+ readout_repetitions=100,
222
+ )
223
+
224
+
225
+ def test_zero_circuit_repetitions():
226
+ """Test that the circuit repetitions are zero."""
227
+ q = cirq.LineQubit(0)
228
+ circuit = cirq.Circuit(cirq.H(q), cirq.measure(q))
229
+ with pytest.raises(ValueError, match="Must provide non-zero circuit_repetitions."):
230
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
231
+ [circuit],
232
+ cirq.ZerosSampler(),
233
+ circuit_repetitions=0,
234
+ rng_or_seed=np.random.default_rng(456),
235
+ num_random_bitstrings=5,
236
+ readout_repetitions=100,
237
+ )
238
+
239
+
240
+ def test_mismatch_circuit_repetitions():
241
+ """Test that the number of circuit repetitions don't match the number of input circuits."""
242
+ q = cirq.LineQubit(0)
243
+ circuit = cirq.Circuit(cirq.H(q), cirq.measure(q))
244
+ with pytest.raises(
245
+ ValueError,
246
+ match="Number of circuit_repetitions must match the number of" + " input circuits.",
247
+ ):
248
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
249
+ [circuit],
250
+ cirq.ZerosSampler(),
251
+ circuit_repetitions=[10, 20],
252
+ rng_or_seed=np.random.default_rng(456),
253
+ num_random_bitstrings=5,
254
+ readout_repetitions=100,
255
+ )
256
+
257
+
258
+ def test_zero_num_random_bitstrings():
259
+ """Test that the number of random bitstrings is zero."""
260
+ q = cirq.LineQubit(0)
261
+ circuit = cirq.Circuit(cirq.H(q), cirq.measure(q))
262
+ with pytest.raises(ValueError, match="Must provide non-zero num_random_bitstrings."):
263
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
264
+ [circuit],
265
+ cirq.ZerosSampler(),
266
+ circuit_repetitions=10,
267
+ rng_or_seed=np.random.default_rng(456),
268
+ num_random_bitstrings=0,
269
+ readout_repetitions=100,
270
+ )
271
+
272
+
273
+ def test_zero_readout_repetitions():
274
+ """Test that the readout repetitions is zero."""
275
+ q = cirq.LineQubit(0)
276
+ circuit = cirq.Circuit(cirq.H(q), cirq.measure(q))
277
+ with pytest.raises(
278
+ ValueError, match="Must provide non-zero readout_repetitions for readout" + " calibration."
279
+ ):
280
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
281
+ [circuit],
282
+ cirq.ZerosSampler(),
283
+ circuit_repetitions=10,
284
+ rng_or_seed=np.random.default_rng(456),
285
+ num_random_bitstrings=5,
286
+ readout_repetitions=0,
287
+ )
288
+
289
+
290
+ def test_rng_type_mismatch():
291
+ """Test that the rng is not a numpy random generator or a seed."""
292
+ q = cirq.LineQubit(0)
293
+ circuit = cirq.Circuit(cirq.H(q), cirq.measure(q))
294
+ with pytest.raises(ValueError, match="Must provide a numpy random generator or a seed"):
295
+ cirq.contrib.shuffle_circuits.run_shuffled_with_readout_benchmarking(
296
+ [circuit],
297
+ cirq.ZerosSampler(),
298
+ circuit_repetitions=10,
299
+ rng_or_seed="not a random generator or seed",
300
+ num_random_bitstrings=5,
301
+ readout_repetitions=100,
302
+ )
@@ -38,7 +38,7 @@ class _BaseGridQid(ops.Qid):
38
38
 
39
39
  def __hash__(self) -> int:
40
40
  if self._hash is None:
41
- self._hash = hash((self._row, self._col, self._dimension))
41
+ self._hash = ((self._dimension - 2) * 1_000_003 + self._col) * 1_000_003 + self._row
42
42
  return self._hash
43
43
 
44
44
  def __eq__(self, other) -> bool:
@@ -34,7 +34,7 @@ class _BaseLineQid(ops.Qid):
34
34
 
35
35
  def __hash__(self) -> int:
36
36
  if self._hash is None:
37
- self._hash = hash((self._x, self._dimension))
37
+ self._hash = (self._dimension - 2) * 1_000_003 + self._x
38
38
  return self._hash
39
39
 
40
40
  def __eq__(self, other) -> bool:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cirq-core
3
- Version: 1.5.0.dev20250122072446
3
+ Version: 1.5.0.dev20250122193029
4
4
  Summary: A framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
5
5
  Home-page: http://github.com/quantumlib/cirq
6
6
  Author: The Cirq Developers
@@ -4,8 +4,8 @@ cirq/_compat_test.py,sha256=Qq3ZcfgD-Nb81cEppQdJqhAyrVqXKtfXZYGXT0p-Wh0,34718
4
4
  cirq/_doc.py,sha256=yDyWUD_2JDS0gShfGRb-rdqRt9-WeL7DhkqX7np0Nko,2879
5
5
  cirq/_import.py,sha256=p9gMHJscbtDDkfHOaulvd3Aer0pwUF5AXpL89XR8dNw,8402
6
6
  cirq/_import_test.py,sha256=6K_v0riZJXOXUphHNkGA8MY-JcmGlezFaGmvrNhm3OQ,1015
7
- cirq/_version.py,sha256=470G-P6DA3djKNF_HCkuRFOH7f0FirM6QHAJHkyprS8,1206
8
- cirq/_version_test.py,sha256=4qRn82WFPwcgLmCjI2RUccL_VFZjv_vZgidg5VGjld8,147
7
+ cirq/_version.py,sha256=VNvum6puwoivPgI01uE4_mzKs1mcRd64x8wXcVKjcHQ,1206
8
+ cirq/_version_test.py,sha256=lddalsRUBod_GeiiguYus5hpJF2DAszETuWBNgVQBnM,147
9
9
  cirq/conftest.py,sha256=X7yLFL8GLhg2CjPw0hp5e_dGASfvHx1-QT03aUbhKJw,1168
10
10
  cirq/json_resolver_cache.py,sha256=p-vEOa-8GQ2cFIAdze-kd6C1un1uRvtujVPljVKaHBg,13557
11
11
  cirq/py.typed,sha256=VFSlmh_lNwnaXzwY-ZuW-C2Ws5PkuDoVgBdNCs0jXJE,63
@@ -146,6 +146,9 @@ cirq/contrib/routing/swap_network.py,sha256=w14mOyeXGmZOUvnJFP1Evk89rsqdplGyxqts
146
146
  cirq/contrib/routing/swap_network_test.py,sha256=XxbjIvOowvtOVwT2RN4e7YWlLebLm98Ty2TtOI1zXzU,4816
147
147
  cirq/contrib/routing/utils.py,sha256=P0_PnaGfy4Rm6CVl9FE7RpdZ0YzGtimcW1acduvp5rU,3761
148
148
  cirq/contrib/routing/utils_test.py,sha256=1oGEDAd70uQ2OrBwbaQd1DYoPcMSZsBQ2l5VLJBtXBM,2021
149
+ cirq/contrib/shuffle_circuits/__init__.py,sha256=AL-V3OaZiaF596WTLlyxDPk0t1WMpTHpQrpRW_A9t48,832
150
+ cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py,sha256=ly4O2xhukp8xkBbk-a0ukSykd1G1yR-L91XNxdePBWU,9660
151
+ cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py,sha256=3SQO5bjrfs1ZRbDNTa_D90f8gx_HL6WCZs1d0IPdEMQ,11790
149
152
  cirq/contrib/svg/__init__.py,sha256=m7d-CNT2j74uNQdmM2xJ1a7HG6v0FZMt8eAwW4rPJpI,148
150
153
  cirq/contrib/svg/svg.py,sha256=d4_XgDNb8o1lDINVJA44XXunGmK71qTAlqw2sc_UnAo,9366
151
154
  cirq/contrib/svg/svg_test.py,sha256=gBHXeosNRHzrKWVo-JwhZLguHbksKQSiFwZ8fUXp-a8,2379
@@ -154,11 +157,11 @@ cirq/devices/device.py,sha256=9rUZwpbbmqk8AUVH4N4KfJ59j5im7hVgDJAHtN9iH_0,5361
154
157
  cirq/devices/device_test.py,sha256=v3gT6jrGLLfYnZbTizIaIMkI3s5_xVM3OV9JQchvAxY,1124
155
158
  cirq/devices/grid_device_metadata.py,sha256=h4Xo_PaiZqQSVUgb1ctVtYYYE2tNik2KQhCgooilZrE,8629
156
159
  cirq/devices/grid_device_metadata_test.py,sha256=IeOqYOZcUGhB4ivuQW2g0Q9dt-zFA0H6Dav6yv6Lul0,8592
157
- cirq/devices/grid_qubit.py,sha256=CeR3ILjzN6H6UjOp2KBhxOoVSjX1TFaAUvbmsU-uGuQ,18793
160
+ cirq/devices/grid_qubit.py,sha256=ynJYYih1QcZPLuNQYbooJWvSruhlep6qKFdiwdfVuSk,18819
158
161
  cirq/devices/grid_qubit_test.py,sha256=EzI8dWWnCfYbwruwsKlBzb41lQTA6AEOB2X16oQAz-0,14044
159
162
  cirq/devices/insertion_noise_model.py,sha256=-X07pSTp-lxQj6AQT_89gTHx_jKtI9GSMrD4dozCwTs,3614
160
163
  cirq/devices/insertion_noise_model_test.py,sha256=i9jB257VXO5wi5QdDO5G4tphx5RKMaouUsdsQT3kiBU,3992
161
- cirq/devices/line_qubit.py,sha256=q7rqUx8Pda3hlL8u6Zu2Ufe0eI5IN5m8Kz_oyBV_yTw,11825
164
+ cirq/devices/line_qubit.py,sha256=SFN7VaxVhcEnH9VPtqPeQ3Aygp0xa8kZ0yntkI_DiVc,11836
162
165
  cirq/devices/line_qubit_test.py,sha256=_X1ofFHtuo0myFfsu1nlTJf9OLuLWRgZHHW2VG23ERY,9547
163
166
  cirq/devices/named_topologies.py,sha256=grFXvi0UDHZl1pRyHDWSqjub3xF_Yf7RLXfMAZbyoEA,15790
164
167
  cirq/devices/named_topologies_test.py,sha256=Nj_tlGmqPH7IVUzpUHPnAPlfUWhSGbZsIHdsLLjxIZs,4736
@@ -1199,8 +1202,8 @@ cirq/work/sampler.py,sha256=bE5tmVkcR6cZZMLETxDfHehdsYUMbx2RvBeIBetehI4,19187
1199
1202
  cirq/work/sampler_test.py,sha256=hL2UWx3dz2ukZVNxWftiKVvJcQoLplLZdQm-k1QcA40,13282
1200
1203
  cirq/work/zeros_sampler.py,sha256=x1C7cup66a43n-3tm8QjhiqJa07qcJW10FxNp9jJ59Q,2356
1201
1204
  cirq/work/zeros_sampler_test.py,sha256=JIkpBBFPJe5Ba4142vzogyWyboG1Q1ZAm0UVGgOoZn8,3279
1202
- cirq_core-1.5.0.dev20250122072446.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1203
- cirq_core-1.5.0.dev20250122072446.dist-info/METADATA,sha256=7qHaIYvtwyqsMcAD9TMOHh9mVdw8ixUszxYjpfA498Y,2105
1204
- cirq_core-1.5.0.dev20250122072446.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
1205
- cirq_core-1.5.0.dev20250122072446.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1206
- cirq_core-1.5.0.dev20250122072446.dist-info/RECORD,,
1205
+ cirq_core-1.5.0.dev20250122193029.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1206
+ cirq_core-1.5.0.dev20250122193029.dist-info/METADATA,sha256=mfgqH-SrwfF7mAeXQyquW9kWfj3G1J9OLSeTNo9FYjU,2105
1207
+ cirq_core-1.5.0.dev20250122193029.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
1208
+ cirq_core-1.5.0.dev20250122193029.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1209
+ cirq_core-1.5.0.dev20250122193029.dist-info/RECORD,,