Skip to content
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

Cleanup RB module #762

Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
833621e
- remove backend and raw data dependency from RB
nkanazawa1989 Apr 4, 2022
f214707
Merge branch 'main' of github.com:Qiskit/qiskit-experiments into clea…
nkanazawa1989 Apr 4, 2022
0350cef
deprecate public methods
nkanazawa1989 Apr 4, 2022
8acb0be
update handling of gate_error_ratio
nkanazawa1989 Apr 5, 2022
7785cff
code formatting
nkanazawa1989 Apr 5, 2022
72641ac
minor bug fix
nkanazawa1989 Apr 5, 2022
8db7f10
create gate error ratio for all basis gates
nkanazawa1989 Apr 6, 2022
e98e42a
replace "skip" with False
nkanazawa1989 Apr 6, 2022
a3540b3
fix json serialization of metadata
nkanazawa1989 Apr 6, 2022
ae71972
fix gate counting bug
nkanazawa1989 Apr 6, 2022
15187b7
lint
nkanazawa1989 Apr 6, 2022
533a0c5
add more test
nkanazawa1989 Apr 6, 2022
b7c0e94
add reno
nkanazawa1989 Apr 6, 2022
e9c66b5
lint
nkanazawa1989 Apr 6, 2022
e53521b
remove redundant internal state for gate error ratio
nkanazawa1989 Apr 6, 2022
50e1269
upgrade EPG computation
nkanazawa1989 Apr 8, 2022
d55185a
replace warning with logging
nkanazawa1989 Apr 8, 2022
f8bd014
update test of deprecated methods
nkanazawa1989 Apr 9, 2022
b78fd2c
Merge branch 'main' into cleanup/rb_remove_rawdata_dependency
nkanazawa1989 Apr 9, 2022
1a33224
review comment1; cleanup utils
nkanazawa1989 Apr 20, 2022
676047b
fix doc of gate_error_ratio
nkanazawa1989 Apr 20, 2022
de07ff4
update reno
nkanazawa1989 Apr 20, 2022
3ab25f5
update documentation and move API docs to tutorial
nkanazawa1989 Apr 20, 2022
4fdc2b3
move helper function after the class
nkanazawa1989 Apr 20, 2022
5f47780
remove gate counts from analysis options
nkanazawa1989 Apr 20, 2022
357f0a4
replace baseclass of IRB analysis.
nkanazawa1989 Apr 20, 2022
af231ec
cleanup tutorial
nkanazawa1989 Apr 20, 2022
c9becae
fix #727
nkanazawa1989 Apr 20, 2022
3a9c21a
Update qiskit_experiments/curve_analysis/guess.py
nkanazawa1989 Apr 21, 2022
71df88c
lint
nkanazawa1989 Apr 21, 2022
2b142df
Merge branch 'cleanup/rb_remove_rawdata_dependency' of github.com:nka…
nkanazawa1989 Apr 21, 2022
e246f71
Merge branch 'main' into cleanup/rb_remove_rawdata_dependency
nkanazawa1989 Apr 21, 2022
6197b3c
fix bug
nkanazawa1989 Apr 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 105 additions & 40 deletions docs/tutorials/randomized_benchmarking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Randomized Benchmarking
A randomized benchmarking (RB) experiment consists of the generation of
random Clifford circuits on the given qubits such that the unitary
computed by the circuits is the identity. After running the circuits,
the number of shots resulting in an error (i.e. an output different than
the number of shots resulting in an error (i.e. an output different than
the ground state) are counted, and from this data one can infer error
estimates for the quantum device, by calculating the Error Per Clifford.
See `Qiskit
Expand All @@ -15,8 +15,7 @@ for an explanation on the RB method, which is based on Ref. [1, 2].

import numpy as np
from qiskit_experiments.library import StandardRB, InterleavedRB
from qiskit_experiments.framework import ParallelExperiment
from qiskit_experiments.library.randomized_benchmarking import RBUtils
from qiskit_experiments.framework import ParallelExperiment, BatchExperiment
import qiskit.circuit.library as circuits

# For simulation
Expand Down Expand Up @@ -47,7 +46,7 @@ in order to generate the RB circuits and run them on a backend:
sequences are constructed by appending additional Clifford samples to
shorter sequences. The default is ``False``

The analysis results of the RB Experiment includes:
The analysis results of the RB Experiment may include:

- ``EPC``: The estimated Error Per Clifford

Expand All @@ -60,6 +59,40 @@ The analysis results of the RB Experiment includes:
Running a 1-qubit RB experiment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Standard RB experiment will provide you gate errors for every basis gates
constituting averaged Clifford gate. Note that you can only obtain a single EPC value :math:`\cal E`
from a single RB experiment. As such, computing the error values for multiple gates :math:`\{g_i\}`
requires some assumption of contribution of each gate to the total depolarizing error.
This is so called ``gate_error_ratio`` option you can find in analysis options.

Provided that we have :math:`n_i` gates with independent error :math:`e_i` per Clifford,
the total EPC is estimated by the composition of error from every basis gate,

.. math::

{\cal E} = 1 - \prod_{i} (1 - e_i)^{n_i} \sim \sum_{i} n_i e_i + O(e^2),

where :math:`e_i \ll 1` and the higher order terms can be ignored.

We cannot distinguish :math:`e_i` with a single EPC value :math:`\cal E` as explained,
however by defining an error ratio :math:`r_i` with respect to
some standard value :math:`e_0`, we can compute EPG :math:`e_i` for each basis gate.

.. math::

{\cal E} \sim e_0 \sum_{i} n_i r_i

The EPG of :math:`i` th basis gate will be

.. math::

e_i \sim r_i e_0 = \dfrac{r_i{\cal E}}{\sum_{i} n_i r_i}.

Because EPGs are computed based on this simple assumption,
this is not necessary representing the true gate error on the hardware.
If you have multiple kinds of basis gates with unclear error ratio :math:`r_i`,
interleaved RB experiment will always give you accurate error value :math:`e_i`.

.. jupyter-execute::

lengths = np.arange(1, 800, 200)
Expand All @@ -73,6 +106,7 @@ Running a 1-qubit RB experiment
results1 = expdata1.analysis_results()

# View result data
print("Gate error ratio: %s" % expdata1.experiment.analysis.options.gate_error_ratio)
display(expdata1.figure(0))
for result in results1:
print(result)
Expand All @@ -82,55 +116,92 @@ Running a 1-qubit RB experiment
Running a 2-qubit RB experiment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Running a 1-qubit RB experiment and a 2-qubit RB experiment, in order to
calculate the gate error (EPG) of the ``cx`` gate:
In the same way we can compute EPC for two-qubit RB experiment.
However, the EPC value obtained by the experiment indicates a depolarization
which is a composition of underlying error channels for 2Q gates and 1Q gates in each qubit.
Usually 1Q gate contribution is small enough to ignore, but in case this
contribution is significant comparing to the 2Q gate error,
we can decompose the contribution of 1Q gates [3].

.. math::

\alpha_{2Q,C} = \frac{1}{5} \left( \alpha_0^{N_1/2} + \alpha_1^{N_1/2} +
3 \alpha_0^{N_1/2} \alpha_1^{N_1/2} \right) \alpha_{01}^{N_2},

where :math:`\alpha_i` is the single qubit depolarizing parameter of channel :math:`i`,
and :math:`\alpha_{01}` is the two qubit depolarizing parameter of interest.
:math:`N_1` and :math:`N_2` are total count of single and two qubit gates, respectively.

Note that the single qubit gate sequence in the channel :math:`i` may consist of
multiple kinds of basis gates :math:`\{g_{ij}\}` with different EPG :math:`e_{ij}`.
Therefore the :math:`\alpha_i^{N_1/2}` should be computed from EPGs,
rather than directly using the :math:`\alpha_i`, which is usually a composition of
depolarizing maps of every single qubit gate.
As such, EPGs should be measured in the separate single-qubit RBs in advance.

.. math::

\alpha_i^{N_1/2} = \alpha_{i0}^{n_{i0}} \cdot \alpha_{i1}^{n_{i1}} \cdot ...,

where :math:`\alpha_{ij}^{n_{ij}}` indicates a depolarization due to
a particular basis gate :math:`j` in the channel :math:`i`.
Here we assume EPG :math:`e_{ij}` corresponds to the depolarizing probability
of the map of :math:`g_{ij}`, and thus we can express :math:`\alpha_{ij}` with EPG.

.. math::

e_{ij} = \frac{2^n - 1}{2^n} (1 - \alpha_{ij}) = \frac{1 - \alpha_{ij}}{2},

for the single qubit channel :math:`n=1`. Accordingly,

.. math::

\alpha_i^{N_1/2} = \prod_{j} (1 - 2 e_{ij})^{n_{ij}},

as a composition of depolarization from every primitive gates per qubit.
This correction will give you two EPC values as a result of the two-qubit RB experiment.
The corrected EPC must be closer to the outcome of of interleaved RB.
The EPGs of two-qubit RB are analyzed with the corrected EPC if available.

.. jupyter-execute::

lengths = np.arange(1, 200, 30)
lengths_2_qubit = np.arange(1, 200, 30)
lengths_1_qubit = np.arange(1, 800, 200)
num_samples = 10
seed = 1010
qubits = (1,4)
qubits = (1, 4)

# Run a 1-qubit RB expriment on qubits 1, 4 to determine the error-per-gate of 1-qubit gates
expdata_1q = {}
epg_1q = []
lengths_1_qubit = np.arange(1, 800, 200)
for qubit in qubits:
exp = StandardRB([qubit], lengths_1_qubit, num_samples=num_samples, seed=seed)
expdata = exp.run(backend).block_for_results()
expdata_1q[qubit] = expdata
epg_1q += expdata.analysis_results()
single_exps = BatchExperiment(
[
StandardRB([qubit], lengths_1_qubit, num_samples=num_samples, seed=seed)
for qubit in qubits
],
flatten_results=True,
)
expdata_1q = single_exps.run(backend).block_for_results()


.. jupyter-execute::

# Run an RB experiment on qubits 1, 4
exp2 = StandardRB(qubits, lengths, num_samples=num_samples, seed=seed)
exp_2q = StandardRB(qubits, lengths_2_qubit, num_samples=num_samples, seed=seed)

# Use the EPG data of the 1-qubit runs to ensure correct 2-qubit EPG computation
exp2.analysis.set_options(epg_1_qubit=epg_1q)
exp_2q.analysis.set_options(epg_1_qubit=expdata_1q.analysis_results())

# Run the 2-qubit experiment
expdata2 = exp2.run(backend).block_for_results()

# View result data
results2 = expdata2.analysis_results()

.. jupyter-execute::
expdata_2q = exp_2q.run(backend).block_for_results()

# View result data
display(expdata2.figure(0))
for result in results2:
print("Gate error ratio: %s" % expdata_2q.experiment.analysis.options.gate_error_ratio)
display(expdata_2q.figure(0))
for result in expdata_2q.analysis_results():
print(result)

.. jupyter-execute::

# Compare the computed EPG of the cx gate with the backend's recorded cx gate error:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comparison is removed because it doesn't make sense. In IBM backend conventionally 2Q gate EPG is computed by just dividing EPC by 1.5.

expected_epg = RBUtils.get_error_dict_from_backend(backend, qubits)[(qubits, 'cx')]
exp2_epg = expdata2.analysis_results("EPG_cx").value

print("Backend's reported EPG of the cx gate:", expected_epg)
print("Experiment computed EPG of the cx gate:", exp2_epg)
Note that ``EPC_corrected`` value is smaller than one of raw ``EPC``, which indicates
contribution of depolarization from single-qubit error channels.


Displaying the RB circuits
Expand Down Expand Up @@ -253,12 +324,6 @@ different qubits (see Ref. [5])
par_exp = ParallelExperiment(exps)
par_expdata = par_exp.run(backend).block_for_results()
par_results = par_expdata.analysis_results()

# View result data
for result in par_results:
print(result)
print("\nextra:")
print(result.extra)


Viewing sub experiment data
Expand Down
1 change: 1 addition & 0 deletions qiskit_experiments/curve_analysis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
guess.constant_sinusoidal_offset
guess.constant_spectral_offset
guess.exp_decay
guess.rb_decay
guess.full_width_half_max
guess.frequency
guess.max_height
Expand Down
Loading