-
Notifications
You must be signed in to change notification settings - Fork 131
Add Mirror RB experiment #842
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
base: main
Are you sure you want to change the base?
Changes from 14 commits
b493b29
11b8af2
f3121eb
b4e6072
aef0379
933bc7b
094ebd0
0e1ec4d
f28cdb7
281b777
9a4602a
1c9b350
66c6f3e
374fc2e
34e2cb7
fefc4ba
b8ab48d
5cd64e5
b43325a
f172c9b
d0feba2
d069f5d
6846e12
ddfcbaf
1124ea8
057de84
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 |
|---|---|---|
|
|
@@ -11,10 +11,15 @@ See `Qiskit | |
| Textbook <https://qiskit.org/textbook/ch-quantum-hardware/randomized-benchmarking.html>`__ | ||
| for an explanation on the RB method, which is based on Ref. [1, 2]. | ||
|
|
||
| .. jupyter-execute:: | ||
| :hide-code: | ||
|
|
||
| %matplotlib inline | ||
|
|
||
| .. jupyter-execute:: | ||
|
|
||
| import numpy as np | ||
| from qiskit_experiments.library import StandardRB, InterleavedRB | ||
| from qiskit_experiments.library import StandardRB, InterleavedRB, MirrorRB | ||
| from qiskit_experiments.framework import ParallelExperiment, BatchExperiment | ||
| import qiskit.circuit.library as circuits | ||
|
|
||
|
|
@@ -304,6 +309,211 @@ Running a 2-qubit interleaved RB experiment | |
| print(result) | ||
|
|
||
|
|
||
| Mirror RB experiment | ||
| -------------------- | ||
|
|
||
| Mirror RB is a RB protocol that is more scalable to larger numbers of qubits, | ||
| and as such, it can be used to detect crosstalk errors in a quantum device. A | ||
| randomized Clifford mirror circuit consists of | ||
|
|
||
| - random layers of one- and two-qubit Cliffords and their inverses sampled | ||
| according to some distribution :math:`\Omega` over a layer set | ||
| :math:`\mathbb{L}`, | ||
|
|
||
| - uniformly random Paulis between these layers, and | ||
|
|
||
| - a layer of uniformly random one-qubit Cliffords at the beginning and the end | ||
| of the circuit. | ||
|
|
||
| Even though a `MirrorRB` experiment can be instantiated without a backend, the | ||
| backend must be specified when the circuits are sampled because :math:`\Omega` | ||
| depends on the backend's connectivity. | ||
|
|
||
| In standard and interleaved RB, $n$-qubit circuits of varying lengths | ||
| :math:`\ell` that compose to the identity are run on a device, and the | ||
| **success probability** $P$, the probability that the circuit's output bit | ||
| string equals the input bit string, is estimated for each circuit length by | ||
| running several circuits at each length. The :math:`P`-versus-:math:`\ell` | ||
| curve is fit to the function :math:`A\alpha^\ell + b`, and the error per | ||
| Clifford (EPC) (the average infidelity) is estimated using | ||
|
|
||
| .. math:: | ||
|
|
||
| r = \frac{\left(2^n - 1\right)p}{2^n}. | ||
|
|
||
| Our implementation of MRB computes additional values in addition to the | ||
| success probability that have been seen in the literature and ``pyGSTi``. | ||
| Specifically, we compute the **adjusted success probability** | ||
|
|
||
| .. math:: | ||
|
|
||
| P_0 = \sum_{k=0}^n \left(-\frac{1}{2}\right)^k h_k, | ||
|
|
||
| where :math:`h_k` is the probability of the actual output bit string being | ||
| Hamming distance :math:`k` away from the expected output bit string (note | ||
| :math:`h_0 = P`). We also compute the **effective polarization** | ||
|
|
||
| .. math:: | ||
|
|
||
| S = \frac{4^n P_0}{4^n - 1} - \frac{1}{4^n - 1}. | ||
|
|
||
| In [6], the function :math:`A\alpha^\ell` (without a baseline) is fit to the | ||
| effective polarizations to find entanglement infidelities. | ||
|
|
||
| In Qiskit Experiments, mirror RB analysis results include the following: | ||
|
|
||
| - ``alpha``: the depolarizing parameter. The user can select which of :math:`P, P_0, S` | ||
| to fit, and the corresponding :math:`\alpha` will be provided. | ||
|
|
||
| - ``EPC``: the expectation of the average gate infidelity of a layer sampled | ||
| according to :math:`\Omega`. | ||
|
|
||
| - ``EI``: the expectation of the entanglement infidelity of a layer sampled | ||
| according to :math:`\Omega`. | ||
|
|
||
| Note that the ``EPC`` :math:`\epsilon_a` and the ``EI`` :math:`\epsilon_e` are | ||
| related by | ||
|
|
||
| .. math:: | ||
|
|
||
| \epsilon_e = \left(1 + \frac{1}{2^n}\right) \epsilon_a, | ||
|
|
||
| where :math:`n` is the number of qubits (see Ref. [7]). | ||
|
|
||
|
|
||
| Running a one-qubit mirror RB experiment | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. jupyter-execute:: | ||
|
|
||
| lengths = np.arange(2, 810, 200) | ||
| num_samples = 30 | ||
| seed = 1010 | ||
| qubits = (0,) | ||
|
|
||
| # Run a MRB experiment on qubit 0 | ||
| exp_1q = MirrorRB(qubits, lengths, backend=backend, num_samples=num_samples, seed=seed) | ||
| expdata_1q = exp_1q.run(backend).block_for_results() | ||
| results_1q = expdata_1q.analysis_results() | ||
|
|
||
| .. jupyter-execute:: | ||
|
|
||
| # View result data | ||
| print("Gate error ratio: %s" % expdata_1q.experiment.analysis.options.gate_error_ratio) | ||
| display(expdata_1q.figure(0)) | ||
| for result in results_1q: | ||
| print(result) | ||
|
|
||
|
|
||
| Running a two-qubit mirror RB experiment | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| In MRB experiments with :math:`n > 1` qubits, intermediate Clifford layers | ||
| are sampled according to the **edge grab** algorithm [7]. The Clifford layers | ||
| in :math:`\mathbb{L}` are constructed from a gate set consisting of | ||
| one-qubit Clifford gates and a single two-qubit Clifford gate (e.g., | ||
| CX) that can be applied to any two connected qubits. The user can specify | ||
| an expected two-qubit gate density | ||
| :math:`\xi \in \left[0, \frac{1}{2}\right]`, and each intermediate Clifford | ||
| layer will have approximately :math:`n \xi` CXs on average. | ||
|
|
||
| .. jupyter-execute:: | ||
|
|
||
| # Two-qubit circuit example | ||
| exp_2q_circ = MirrorRB((0,1), lengths=[4], backend=backend, num_samples=1, seed=1010, two_qubit_gate_density=.4) | ||
| qc2 = exp_2q_circ.circuits()[0].decompose()#gates_to_decompose=['Clifford*','circuit*']) | ||
| qc2.draw() | ||
|
|
||
| .. jupyter-execute:: | ||
|
|
||
| lengths = np.arange(2, 810, 200) | ||
| num_samples = 30 | ||
| seed = 1011 | ||
| qubits = (0,1) | ||
|
|
||
| # Run a MRB experiment on qubits 0, 1 | ||
| exp_2q = MirrorRB(qubits, lengths, backend=backend, num_samples=num_samples, seed=seed) | ||
| expdata_2q = exp_2q.run(backend).block_for_results() | ||
| results_2q = expdata_2q.analysis_results() | ||
|
|
||
| .. jupyter-execute:: | ||
|
|
||
| # View result data | ||
| print("Gate error ratio: %s" % expdata_2q.experiment.analysis.options.gate_error_ratio) | ||
| display(expdata_2q.figure(0)) | ||
| for result in results_2q: | ||
| print(result) | ||
|
|
||
|
|
||
| Selecting :math:`y`-axis values | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. jupyter-execute:: | ||
|
|
||
| lengths = [2, 52, 102, 152] | ||
| num_samples = 30 | ||
| seed = 42 | ||
| qubits = (0,) | ||
|
|
||
| exp = MirrorRB(qubits, lengths, backend=backend, num_samples=num_samples, seed=seed) | ||
| # select y-axis | ||
| exp.analysis.set_options(y_axis="Success Probability") # or "Adjusted Success Probability" or "Effective Polarization" | ||
| # y-axis label must be set separately | ||
| exp.analysis.options.curve_drawer.set_options( | ||
| # xlabel="Clifford Length", | ||
| ylabel="Success Probability", | ||
| ) | ||
| expdata = exp.run(backend).block_for_results() | ||
| results = expdata.analysis_results() | ||
|
|
||
| .. jupyter-execute:: | ||
|
|
||
| display(expdata.figure(0)) | ||
| for result in results: | ||
| print(result) | ||
|
|
||
|
|
||
| Mirror RB user options | ||
| ~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Circuit generation options can be specified when a ``MirrorRB`` experiment | ||
| object is instantiated: | ||
|
|
||
| - ``local_clifford`` (default ``True``): if ``True``, begin the circuit with | ||
| uniformly random one-qubit Cliffords and end the circuit with their inverses | ||
|
|
||
| - ``pauli_randomize`` (default ``True``): if ``True``, put layers of uniformly | ||
| random Paulis between the intermediate Clifford layers | ||
|
|
||
| - ``two_qubit_gate_density`` (default ``0.2``): expected fraction of two-qubit | ||
| gates in each intermediate Clifford layer | ||
|
|
||
| - ``inverting_pauli_layer`` (default ``False``): if ``True``, put a layer of | ||
| Paulis at the end of the circuit to set the output to | ||
| :math:`\left\vert0\right\rangle^{\otimes n}`, up to a global phase | ||
|
|
||
|
|
||
| Mirror RB implementation in ``pyGSTi`` | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| The ``MirrorRBPyGSTi`` subclass of ``MirrorRB`` uses the circuit generation in | ||
| ``pyGSTi`` but the circuit transpilation in Qiskit Experiments. It is primarily | ||
| used for testing and comparison, and an instance of such an experiment is | ||
| constructed in the same way as described above. ``MirrorRBPyGSTi`` uses Qiskit's | ||
| transpilation because ``pyGSTi`` transpiles circuits slightly differently, | ||
| producing small discrepancies in fit parameters between the two codes. To | ||
| illustrate, consider the two circuits below, both of which were generated in | ||
| ``pyGSTi``. The first circuit was transpiled in ``pyGSTi``, | ||
|
|
||
| .. image:: pygsti-data-pygsti-transpiled-circ.png | ||
|
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. Why this cannot be generated here? You have hidden cell option.
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. pyGSTi is required to generate these circuits, and we don't want to require pyGSTi to accurately render the documentation. |
||
|
|
||
| and the second was transpiled in Qiskit. | ||
|
|
||
| .. image:: pygsti-data-qiskit-transpiled-circ.png | ||
|
|
||
| Note the different implementations of the same Clifford on | ||
| qubit 0 in the fifth layer. | ||
|
|
||
|
|
||
| Running a simultaneous RB experiment | ||
| ------------------------------------ | ||
|
|
@@ -369,6 +579,14 @@ A. Ohki, Mark B. Ketchen, and M. Steffen, *Characterization of | |
| addressability by simultaneous randomized benchmarking*, | ||
| https://arxiv.org/pdf/1204.6308 | ||
|
|
||
| [6] Timothy Proctor, Stefan Seritan, Kenneth Rudinger, Erik Nielsen, Robin | ||
| Blume-Kohout, Kevin Young, *Scalable randomized benchmarking of quantum | ||
| computers using mirror circuits*, https://arxiv.org/pdf/2112.09853.pdf | ||
|
|
||
| [7] Timothy Proctor, Kenneth Rudinger, Kevin Young, Erik Nielsen, and Robin | ||
| Blume-Kohout, *Measuring the Capabilities of Quantum Computers*, | ||
| https://arxiv.org/pdf/2008.11294.pdf | ||
|
|
||
| .. jupyter-execute:: | ||
|
|
||
| import qiskit.tools.jupyter | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that "more scalable" needs to be qualified a bit, and that crosstalk detection needs to be discussed as an application of the protocol rather than a central aspect. Indeed, standard randomized benchmarking in parallel can do some types of crosstalk detection.