-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add parallel randomized benchmarking #6382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 18 commits
c4f52a4
1e0a1b4
21b41d5
489cd09
5be6786
f8b1c42
d03db79
207f1e9
ca5d0b1
dd37885
4bbdc2b
4029c3a
bfed7c7
9c57fa6
4c1a538
6008b7f
188eaa7
609706a
796d5b7
aeff626
9980416
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -207,9 +207,9 @@ def single_qubit_randomized_benchmarking( | |||||
| qubit: 'cirq.Qid', | ||||||
| use_xy_basis: bool = True, | ||||||
| *, | ||||||
| num_clifford_range: Sequence[int] = range(10, 100, 10), | ||||||
| num_circuits: int = 20, | ||||||
| repetitions: int = 1000, | ||||||
| num_clifford_range: Sequence[int] = tuple(np.logspace(np.log10(5), 3, 5, dtype=int)), | ||||||
| num_circuits: int = 10, | ||||||
| repetitions: int = 600, | ||||||
|
eliottrosenberg marked this conversation as resolved.
|
||||||
| ) -> RandomizedBenchMarkResult: | ||||||
| """Clifford-based randomized benchmarking (RB) of a single qubit. | ||||||
|
|
||||||
|
|
@@ -245,21 +245,73 @@ def single_qubit_randomized_benchmarking( | |||||
| A RandomizedBenchMarkResult object that stores and plots the result. | ||||||
| """ | ||||||
|
|
||||||
| qubits = cast(Iterator['cirq.Qid'], (qubit,)) | ||||||
| result = parallel_single_qubit_randomized_benchmarking( | ||||||
| sampler, | ||||||
| qubits, | ||||||
| use_xy_basis, | ||||||
| num_clifford_range=num_clifford_range, | ||||||
| num_circuits=num_circuits, | ||||||
| repetitions=repetitions, | ||||||
| ) | ||||||
| return result[qubit] | ||||||
|
|
||||||
|
|
||||||
| def parallel_single_qubit_randomized_benchmarking( | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OOC, would it be possible to put this in the existing
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I changed it so that |
||||||
| sampler: 'cirq.Sampler', | ||||||
| qubits: Iterator['cirq.Qid'], | ||||||
| use_xy_basis: bool = True, | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason this is before the kwargs cut-off?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was following the same format as in |
||||||
| *, | ||||||
| num_clifford_range: Sequence[int] = tuple(np.logspace(np.log10(5), 3, 5, dtype=int)), | ||||||
| num_circuits: int = 10, | ||||||
| repetitions: int = 600, | ||||||
| ) -> dict: | ||||||
|
eliottrosenberg marked this conversation as resolved.
Outdated
|
||||||
| """Clifford-based randomized benchmarking (RB) single qubits in parallel. | ||||||
|
|
||||||
| This is the same as `single_qubit_randomized_benchmarking` except on all | ||||||
| of the specified qubits in parallel, i.e. with the individual randomized | ||||||
| benchmarking circuits zipped together. | ||||||
|
|
||||||
| Args: | ||||||
| sampler: The quantum engine or simulator to run the circuits. | ||||||
| use_xy_basis: Determines if the Clifford gates are built with x and y | ||||||
| rotations (True) or x and z rotations (False). | ||||||
| qubits: The qubits to benchmark. | ||||||
| num_clifford_range: The different numbers of Cliffords in the RB study. | ||||||
| num_circuits: The number of random circuits generated for each | ||||||
| number of Cliffords. | ||||||
| repetitions: The number of repetitions of each circuit. | ||||||
|
|
||||||
| Returns: | ||||||
| A dictionary from qubits to RandomizedBenchMarkResult objects. | ||||||
| """ | ||||||
|
|
||||||
| cliffords = _single_qubit_cliffords() | ||||||
| c1 = cliffords.c1_in_xy if use_xy_basis else cliffords.c1_in_xz | ||||||
| cfd_mats = np.array([_gate_seq_to_mats(gates) for gates in c1]) | ||||||
| clifford_mats = np.array([_gate_seq_to_mats(gates) for gates in c1]) | ||||||
|
|
||||||
| gnd_probs = [] | ||||||
| for num_cfds in num_clifford_range: | ||||||
| excited_probs_l = [] | ||||||
| # create circuits | ||||||
| circuits_all = [] | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: call this
Suggested change
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think I should call this |
||||||
| for num_cliffords in num_clifford_range: | ||||||
| for _ in range(num_circuits): | ||||||
| circuit = _random_single_q_clifford(qubit, num_cfds, c1, cfd_mats) | ||||||
| circuit.append(ops.measure(qubit, key='z')) | ||||||
| results = sampler.run(circuit, repetitions=repetitions) | ||||||
| excited_probs_l.append(np.mean(results.measurements['z'])) | ||||||
| gnd_probs.append(1.0 - np.mean(excited_probs_l)) | ||||||
| circuits_all.append( | ||||||
| _create_parallel_rb_circuit(qubits, num_cliffords, c1, clifford_mats) | ||||||
| ) | ||||||
|
|
||||||
| return RandomizedBenchMarkResult(num_clifford_range, gnd_probs) | ||||||
| # run circuits | ||||||
| results_all = sampler.run_batch(circuits_all, repetitions=repetitions) | ||||||
|
eliottrosenberg marked this conversation as resolved.
Outdated
|
||||||
| gnd_probs: dict = {q: [] for q in qubits} | ||||||
| idx = 0 | ||||||
| for num_cliffords in num_clifford_range: | ||||||
| excited_probs_l: dict = {q: [] for q in qubits} | ||||||
|
eliottrosenberg marked this conversation as resolved.
Outdated
|
||||||
| for _ in range(num_circuits): | ||||||
| results = results_all[idx][0] | ||||||
| for qubit in qubits: | ||||||
| excited_probs_l[qubit].append(np.mean(results.measurements[str(qubit)])) | ||||||
| idx += 1 | ||||||
| for qubit in qubits: | ||||||
| gnd_probs[qubit].append(1.0 - np.mean(excited_probs_l[qubit])) | ||||||
| return {q: RandomizedBenchMarkResult(num_clifford_range, gnd_probs[q]) for q in qubits} | ||||||
|
|
||||||
|
|
||||||
| def two_qubit_randomized_benchmarking( | ||||||
|
|
@@ -496,6 +548,18 @@ def _measurement(two_qubit_circuit: circuits.Circuit) -> np.ndarray: | |||||
| return TomographyResult(rho) | ||||||
|
|
||||||
|
|
||||||
| def _create_parallel_rb_circuit( | ||||||
| qubits: Iterator['cirq.Qid'], num_cliffords: int, c1: list, clifford_mats: np.ndarray | ||||||
| ) -> 'cirq.Circuit': | ||||||
| circuits_to_zip = [ | ||||||
| _random_single_q_clifford(qubit, num_cliffords, c1, clifford_mats) for qubit in qubits | ||||||
| ] | ||||||
| circuit = circuits.Circuit.zip(*circuits_to_zip) | ||||||
| measure_moment = circuits.Moment(ops.measure_each(*qubits)) | ||||||
| circuit_with_meas = circuits.Circuit.from_moments(*circuit.moments, measure_moment) | ||||||
| return circuit_with_meas | ||||||
|
eliottrosenberg marked this conversation as resolved.
Outdated
|
||||||
|
|
||||||
|
|
||||||
| def _indices_after_basis_rot(i: int, j: int) -> Tuple[int, Sequence[int], Sequence[int]]: | ||||||
| mat_idx = 3 * (3 * i + j) | ||||||
| q_0_i = 3 - i | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.