Quantum Volume¶
Introduction¶
Quantum Volume (QV) is a method to verify device performance and a metric to quantify the computational power of a quantum device. The method is based on the paper “Validating quantum computers using randomized model circuits” (https://arxiv.org/abs/1811.12926).
This notebook gives an example for how to use the ignis.verification.quantum_volume
module. This particular example shows how to run up to depth 6 quantum volume circuits and will run them using the noisy Aer simulator.
[1]:
#Import general libraries (needed for functions)
import numpy as np
import matplotlib.pyplot as plt
from IPython import display
#Import Qiskit classes classes
import qiskit
from qiskit.providers.aer.noise import NoiseModel
from qiskit.providers.aer.noise.errors.standard_errors import depolarizing_error, thermal_relaxation_error
#Import the qv function.
import qiskit.ignis.verification.quantum_volume as qv
Select the Parameters of the QV Run¶
In this example we have 6 qubits Q0,Q1,Q3,Q5,Q7,Q10. We are going to look at subsets up to the full set.
[2]:
#Qubit list
qubit_lists = [[0,1,3],[0,1,3,5],[0,1,3,5,7],[0,1,3,5,7,10]]
ntrials = 50
Generate QV sequences¶
We generate the quantum volume sequences. We start with a small example (so it doesn’t take too long to run).
[3]:
qv_circs, qv_circs_nomeas = qv.qv_circuits(qubit_lists, ntrials)
[4]:
#pass the first trial of the nomeas through the transpiler to illustrate the circuit
qv_circs_nomeas[0] = qiskit.compiler.transpile(qv_circs_nomeas[0], basis_gates=['u1','u2','u3','cx'])
As an example, we print the circuit corresponding to the first QV sequence. Note that the ideal circuits are run on the first n qubits (where n is the number of qubits in the subset).
[5]:
print(qv_circs_nomeas[0][0])
┌────────────────────────────┐ »
qr_0: |0>─┤ U3(0.88109,-3.974,0.67573) ├────────────────────────────────────»
┌┴────────────────────────────┤┌───┐ ┌───────────────────┐ ┌───┐»
qr_1: |0>┤ U3(2.6224,-0.97915,-4.0992) ├┤ X ├──┤ U3(pi/2,0,3.6893) ├───┤ X ├»
└─┬──────────────────────────┬┘└─┬─┘┌─┴───────────────────┴──┐└─┬─┘»
qr_2: |0>──┤ U3(1.3211,3.3206,1.9445) ├───■──┤ U3(0.76663,pi/2,-pi/2) ├──■──»
└──────────────────────────┘ └────────────────────────┘ »
cr_0: 0 ═══════════════════════════════════════════════════════════════════»
»
cr_1: 0 ═══════════════════════════════════════════════════════════════════»
»
cr_2: 0 ═══════════════════════════════════════════════════════════════════»
»
« ┌───┐»
«qr_0: ─────────────────────────────────────────────────────────────┤ X ├»
« ┌───────────────────┐ ┌───┐ ┌───────────────────────────┐ └─┬─┘»
«qr_1: ──┤ U3(pi/2,-pi,pi/2) ├──┤ X ├─┤ U3(2.3258,0.16961,1.9883) ├───■──»
« ┌─┴───────────────────┴─┐└─┬─┘┌┴───────────────────────────┴┐ »
«qr_2: ┤ U3(0.069147,pi,-pi/2) ├──■──┤ U3(2.6257,-0.40966,-4.1229) ├─────»
« └───────────────────────┘ └─────────────────────────────┘ »
«cr_0: ══════════════════════════════════════════════════════════════════»
« »
«cr_1: ══════════════════════════════════════════════════════════════════»
« »
«cr_2: ══════════════════════════════════════════════════════════════════»
« »
« ┌──────────────────┐ ┌───┐┌───────────────────┐ ┌───┐»
«qr_0: ───┤ U3(pi/2,0,3.648) ├───┤ X ├┤ U3(pi/2,-pi,pi/2) ├─┤ X ├»
« ┌──┴──────────────────┴──┐└─┬─┘├───────────────────┴┐└─┬─┘»
«qr_1: ┤ U3(0.67876,pi/2,-pi/2) ├──■──┤ U3(0.39769,0,pi/2) ├──■──»
« └────────────────────────┘ └────────────────────┘ »
«qr_2: ──────────────────────────────────────────────────────────»
« »
«cr_0: ══════════════════════════════════════════════════════════»
« »
«cr_1: ══════════════════════════════════════════════════════════»
« »
«cr_2: ══════════════════════════════════════════════════════════»
« »
« ┌───────────────────────────┐ ┌───┐ ┌───────────────────┐ ┌───┐»
«qr_0: ┤ U3(1.6714,0.26184,5.8406) ├─┤ X ├──┤ U3(pi/2,0,3.3447) ├──┤ X ├»
« ├───────────────────────────┴┐└─┬─┘ └───────────────────┘ └─┬─┘»
«qr_1: ┤ U3(2.0587,-0.39667,5.1684) ├──┼─────────────────────────────┼──»
« └────────────────────────────┘ │ ┌───────────────────────┐ │ »
«qr_2: ────────────────────────────────■──┤ U3(0.8297,pi/2,-pi/2) ├──■──»
« └───────────────────────┘ »
«cr_0: ═════════════════════════════════════════════════════════════════»
« »
«cr_1: ═════════════════════════════════════════════════════════════════»
« »
«cr_2: ═════════════════════════════════════════════════════════════════»
« »
« ┌───────────────────┐ ┌───┐┌──────────────────────────┐
«qr_0: ─┤ U3(pi/2,-pi,pi/2) ├─┤ X ├┤ U3(2.673,3.0342,0.69813) ├
« └───────────────────┘ └─┬─┘└──────────────────────────┘
«qr_1: ─────────────────────────┼──────────────────────────────
« ┌─────────────────────┐ │ ┌──────────────────────────┐
«qr_2: ┤ U3(0.032719,0,pi/2) ├──■──┤ U3(1.14,-1.5329,-1.9038) ├
« └─────────────────────┘ └──────────────────────────┘
«cr_0: ════════════════════════════════════════════════════════
«
«cr_1: ════════════════════════════════════════════════════════
«
«cr_2: ════════════════════════════════════════════════════════
«
Simulate the ideal circuits¶
The quantum volume method requires that we know the ideal output for each circuit, so use the statevector simulator in Aer to get the ideal result.
[6]:
#The Unitary is an identity (with a global phase)
backend = qiskit.Aer.get_backend('statevector_simulator')
ideal_results = []
for trial in range(ntrials):
print('Simulating trial %d'%trial)
ideal_results.append(qiskit.execute(qv_circs_nomeas[trial], backend=backend, optimization_level=0).result())
Simulating trial 0
Simulating trial 1
Simulating trial 2
Simulating trial 3
Simulating trial 4
Simulating trial 5
Simulating trial 6
Simulating trial 7
Simulating trial 8
Simulating trial 9
Simulating trial 10
Simulating trial 11
Simulating trial 12
Simulating trial 13
Simulating trial 14
Simulating trial 15
Simulating trial 16
Simulating trial 17
Simulating trial 18
Simulating trial 19
Simulating trial 20
Simulating trial 21
Simulating trial 22
Simulating trial 23
Simulating trial 24
Simulating trial 25
Simulating trial 26
Simulating trial 27
Simulating trial 28
Simulating trial 29
Simulating trial 30
Simulating trial 31
Simulating trial 32
Simulating trial 33
Simulating trial 34
Simulating trial 35
Simulating trial 36
Simulating trial 37
Simulating trial 38
Simulating trial 39
Simulating trial 40
Simulating trial 41
Simulating trial 42
Simulating trial 43
Simulating trial 44
Simulating trial 45
Simulating trial 46
Simulating trial 47
Simulating trial 48
Simulating trial 49
Next, load the ideal results into a quantum volume fitter:
[7]:
qv_fitter = qv.QVFitter(qubit_lists=qubit_lists)
qv_fitter.add_statevectors(ideal_results)
Define the noise model¶
We define a noise model for the simulator. To simulate decay, we add depolarizing error probabilities to the CNOT and U gates.
[8]:
noise_model = NoiseModel()
p1Q = 0.002
p2Q = 0.02
noise_model.add_all_qubit_quantum_error(depolarizing_error(p1Q, 1), 'u2')
noise_model.add_all_qubit_quantum_error(depolarizing_error(2*p1Q, 1), 'u3')
noise_model.add_all_qubit_quantum_error(depolarizing_error(p2Q, 2), 'cx')
#noise_model = None
Execute on Aer simulator¶
We can execute the QV sequences either using a Qiskit Aer Simulator (with some noise model) or using an IBMQ provider, and obtain a list of results, result_list
.
[9]:
backend = qiskit.Aer.get_backend('qasm_simulator')
basis_gates = ['u1','u2','u3','cx'] # use U,CX for now
shots = 1024
exp_results = []
for trial in range(ntrials):
print('Running trial %d'%trial)
exp_results.append(qiskit.execute(qv_circs[trial], basis_gates=basis_gates, backend=backend, noise_model=noise_model, backend_options={'max_parallel_experiments': 0}).result())
Running trial 0
Running trial 1
Running trial 2
Running trial 3
Running trial 4
Running trial 5
Running trial 6
Running trial 7
Running trial 8
Running trial 9
Running trial 10
Running trial 11
Running trial 12
Running trial 13
Running trial 14
Running trial 15
Running trial 16
Running trial 17
Running trial 18
Running trial 19
Running trial 20
Running trial 21
Running trial 22
Running trial 23
Running trial 24
Running trial 25
Running trial 26
Running trial 27
Running trial 28
Running trial 29
Running trial 30
Running trial 31
Running trial 32
Running trial 33
Running trial 34
Running trial 35
Running trial 36
Running trial 37
Running trial 38
Running trial 39
Running trial 40
Running trial 41
Running trial 42
Running trial 43
Running trial 44
Running trial 45
Running trial 46
Running trial 47
Running trial 48
Running trial 49
Load the experimental data into the fitter. The data will keep accumulating if this is re-run (unless the fitter is re-instantiated).
[10]:
qv_fitter.add_data(exp_results)
[11]:
plt.figure(figsize=(10, 6))
ax = plt.gca()
# Plot the essence by calling plot_rb_data
qv_fitter.plot_qv_data(ax=ax, show_plt=False)
# Add title and label
ax.set_title('Quantum Volume for up to %d Qubits \n and %d Trials'%(len(qubit_lists[-1]), ntrials), fontsize=18)
plt.show()
![../../_images/tutorials_noise_5_quantum_volume_21_0.png](../../_images/tutorials_noise_5_quantum_volume_21_0.png)
Quantum Volume¶
List statistics for each depth. For each depth list if the depth was successful or not and with what confidence interval. For a depth to be successful the confidence interval must be > 97.5%.
[12]:
qv_success_list = qv_fitter.qv_success()
qv_list = qv_fitter.ydata
for qidx, qubit_list in enumerate(qubit_lists):
if qv_list[0][qidx]>2/3:
if qv_success_list[qidx][0]:
print("Width/depth %d greater than 2/3 (%f) with confidence %f (successful). Quantum volume %d"%
(len(qubit_list),qv_list[0][qidx],qv_success_list[qidx][1],qv_fitter.quantum_volume()[qidx]))
else:
print("Width/depth %d greater than 2/3 (%f) with confidence %f (unsuccessful)."%
(len(qubit_list),qv_list[0][qidx],qv_success_list[qidx][1]))
else:
print("Width/depth %d less than 2/3 (unsuccessful)."%len(qubit_list))
Width/depth 3 greater than 2/3 (0.791562) with confidence 0.985155 (successful). Quantum volume 8
Width/depth 4 greater than 2/3 (0.707090) with confidence 0.735022 (unsuccessful).
Width/depth 5 greater than 2/3 (0.710508) with confidence 0.752867 (unsuccessful).
Width/depth 6 less than 2/3 (unsuccessful).
[13]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
Qiskit | 0.14.0 |
Terra | 0.11.0 |
Aer | 0.3.4 |
Ignis | 0.2.0 |
Aqua | 0.6.1 |
IBM Q Provider | 0.4.4 |
System information | |
Python | 3.7.5 (default, Oct 25 2019, 10:52:18) [Clang 4.0.1 (tags/RELEASE_401/final)] |
OS | Darwin |
CPUs | 4 |
Memory (Gb) | 16.0 |
Tue Dec 10 17:04:56 2019 EST |
This code is a part of Qiskit
© Copyright IBM 2017, 2019.
This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.
[ ]: