3 Quantum program information
3.1 NodeIter
NodeIter is QProg or QCircuit iterator externally provided by pyQPanda. We can control our quantum programs conveniently through NodeIter.
3.1.1 Interface introduction
At present, NodeIter has the main operations below:
obtaining the next node
iter = iter.get_next()
obtaining the previous node
iter = iter.get_pre()
obtaining the node type
type = iter.get_node_type()
configuring QProg through iterator
type = iter.get_node_type()
if pq.NodeType.PROG_NODE == type:
prog = pq.QProg(iter)
configuring the quantum circuit QCircuit through iterator
type = iter.get_node_type()
if pq.NodeType.CIRCUIT_NODE == type:
cir = pq.QCircuit(iter)
configuring QGate through iterator
type = iter.get_node_type()
if pq.NodeType.GATE_NODE == type:
gate = pq.QGate(iter)
configuring QIfProg through iterator
type = iter.get_node_type()
if pq.NodeType.QIF_START_NODE == type:
if_prog = pq.QIfProg(iter)
configuring QWhileProg through iterator
type = iter.get_node_type()
if pq.NodeType.WHILE_START_NODE == type:
while_prog = pq.QWhileProg(iter)
configuring QMeasure through iterator
type = iter.get_node_type()
if pq.NodeType.MEASURE_GATE == type:
measure_gate = pq.QMeasure(iter)
3.1.2 Example
The following example program has the function to browse one QProg through NodeIter and output the types of node logic gates:
import pyqpanda.pyQPanda as pq
import math
machine = pq.init_quantum_machine(pq.QMachineType.CPU)
q = machine.qAlloc_many(8)
c = machine.cAlloc_many(8)
prog = pq.QProg()
prog << pq.H(q[0]) << pq.S(q[2]) << pq.CNOT(q[0], q[1])\
<< pq.CZ(q[1], q[2]) << pq.CR(q[1], q[2], math.pi/2)
iter = prog.begin()
iter_end = prog.end()
while iter != iter_end:
if pq.NodeType.GATE_NODE == iter.get_node_type():
gate = pq.QGate(iter)
print(gate.gate_type())
iter = iter.get_next()
else:
print('Traversal End.\n')
pq.destroy_quantum_machine(machine)
Reverse browsing:
import pyqpanda.pyQPanda as pq
import math
machine = pq.init_quantum_machine(pq.QMachineType.CPU)
q = machine.qAlloc_many(8)
c = machine.cAlloc_many(8)
prog = pq.QProg()
prog << pq.H(q[0]) << pq.S(q[2]) << pq.CNOT(q[0], q[1])\
<< pq.CZ(q[1], q[2]) << pq.CR(q[1], q[2], math.pi/2)
iter_head = prog.head()
iter = prog.last()
while iter != iter_head:
if pq.NodeType.GATE_NODE == iter.get_node_type():
gate = pq.QGate(iter)
print(gate.gate_type())
iter = iter.get_pre()
else:
print('Traversal End.\n')
3.2 Logic gate statistics
3.2.1 Introduction
Logic gate statistics refers to a method for counting the number of the quantum logic gates (including measurement gates) in quantum programs, quantum circuits, quantum cycle control or quantum condition control.
3.2.2 Interface introduction
We create one quantum program firstly through pyqpanda:
prog = QProg()
prog << X(qubits[0]) << Y(qubits[1])\
<< H(qubits[0]) << RX(qubits[0], 3.14)\
<< Measure(qubits[0], cbits[0])
invoke get_qgate_num
to count the number of quantum logic gates;
number = get_qgate_num(prog)
Note
The method of counting the number of quantum logic gates in QCircuit
, QWhileProg
and QIfProg
is similar to the method of counting QProg
.
3.2.3 Example
from pyqpanda import *
if __name__ == "__main__":
qvm = init_quantum_machine(QMachineType.CPU)
qubits = qvm.qAlloc_many(2)
cbits = qvm.cAlloc_many(2)
prog = QProg()
# Building quantum programs
prog << X(qubits[0]) << Y(qubits[1])\
<< H(qubits[0]) << RX(qubits[0], 3.14)\
<< Measure(qubits[0], cbits[0])
# Statistics the number of logical gates
number = get_qgate_num(prog)
print("QGate number: " + str(number))
qvm.finalize()
Output results are as follows:
QGate number: 4
Warning
The interface name in the new version is changed, and the old interface count_gate
is replaced by get_qgate_num
. Please note that count_gate
will be removed in the next version.
3.3 Counting quantum program clock cycle
3.3.1 Introduction
Estimate the running time of a quantum program under the known running
time of the quantum logic gates. The time of the quantum logic gates is
set to the item metadata configuration file QPandaConfig.xml
; a default
is given if such time is not set, where the time of single quantum gate
is defaulted as 2, and that of the double quantum gates is defaulted as
5.
The configuration file can be set according to the following example:
"QGate": {
"SingleGate":{
"U3":{"time":1}
},
"DoubleGate":{
"CNOT":{"time":2},
"CZ":{"time":2}
}
}
3.3.2 Interface introduction
We create one quantum program firstly through pyqpanda:
prog = QProg()
prog << H(qubits[0]) << CNOT(qubits[0], qubits[1])\
<< iSWAP(qubits[1], qubits[2]) << RX(qubits[3], np.pi / 4)
invoke get_qprog_clock_cycle
interface to get the clock cycle of the
quantum program
clock_cycle = get_qprog_clock_cycle(qvm, prog)
3.3.3 Example
from pyqpanda import *
import numpy as np
if __name__ == "__main__":
qvm = init_quantum_machine(QMachineType.CPU)
qubits = qvm.qAlloc_many(4)
cbits = qvm.cAlloc_many(4)
# Building quantum programs
prog = QProg()
prog << H(qubits[0]) << CNOT(qubits[0], qubits[1])\
<< iSWAP(qubits[1], qubits[2]) << RX(qubits[3], np.pi / 4)
# Statistical quantum program clock cycle
clock_cycle = get_qprog_clock_cycle(prog, qvm)
print(clock_cycle)
destroy_quantum_machine(qvm)
Output results are as follows:
5
Warning
The interface name in the new version is changed, and the old interface get_clock_cycle
will be replaced by get_qprog_clock_cycle
. Please note that get_clock_cycle
will be removed in the next version.
3.4 Get the corresponding matrix of the quantum circuit
The get_matrix
interface can get the corresponding matrix of the input
circuit and has three output parameters, where one parameter is quantum
circuit QCircuit (or Qprog), and other two parameters are optional
parameters: the starting and ending positions of the iterator are used
for designating one circuit interval to get corresponding matrix
information; if the parameters are null, the matrix information of the
entire quantum circuit is obtained.
Note
It should be noted in use of get_matrix
that the quantum circuit does not involve measurement.
3.4.1 Example
import pyqpanda.pyQPanda as pq
import math
class InitQMachine:
def __init__(self, quBitCnt, cBitCnt,\
machineType = pq.QMachineType.CPU):
self.m_machine = pq.init_quantum_machine(machineType)
self.m_qlist = self.m_machine.qAlloc_many(quBitCnt)
self.m_clist = self.m_machine.cAlloc_many(cBitCnt)
self.m_prog = pq.QProg()
def __del__(self):
pq.destroy_quantum_machine(self.m_machine)
def test_get_matrix(q, c):
prog = pq.QProg()
# Building quantum programs
prog << pq.H(q[0]) \
<< pq.S(q[2]) \
<< pq.CNOT(q[0], q[1]) \
<< pq.CZ(q[1], q[2]) \
<< pq.CR(q[1], q[2], math.pi/2)
# Obtain the line corresponding matrix
result_mat = pq.get_matrix(prog)
# Print matrix information
pq.print_matrix(result_mat)
if __name__=="__main__":
init_machine = InitQMachine(16, 16)
qlist = init_machine.m_qlist
clist = init_machine.m_clist
machine = init_machine.m_machine
test_get_matrix(qlist, clist)
print("Test over.")
The specific steps are as follows:
Initialize a quantum simulator object with
init_quantum_machine
(pq.QMachineType.CPU) in order to manage a series of subsequent behaviorsInitialize the number of qubits and classical registers with
machine.qAlloc_many()
andmachine.cAlloc_many()
, where respective 8 qubits and classical register are applied.Create prog
Determine the circuit interval of computing matrix information, namely setting of
iter_start
anditer_end
Invoke
get_matrix
interface to output the corresponding matrix of the quantum circuit, and print obtained matrix information throughprint_mat
interface.
3.5 Judge whether quantum logic gate matches with the quantum topology
Each quantum chip has its own particular qubit topology, for example,
ibmq_16_melbourne
provided by IBMQ:
It can be seen from the Figure that the qubits in the quantum chip are not connected in pairs, and those not interconnected cannot directly execute multi-gate operations. Therefore, it is necessary to judge whether the double-gate (multi-gate) operation in the quantum program is in conformity with the qubit topology prior to the execution of the quantum program.
3.5.1 Interface introduction
The is_match_topology
is to judge whether the quantum logic gate is in
conformity with the qubit topology. The first input parameter is the
target quantum logic gate QGate, the second input parameter is the qubit
topology, and the returned value is Boolean value. This indicates
whether the target quantum logic gate is in conformity with the qubit
topology. True means that the target quantum logic gate is in conformity
with the qubit topology. False means that the target quantum logic gate
is not in conformity with the qubit topology.
import pyqpanda.pyQPanda as pq
import math
class InitQMachine:
def __init__(self, quBitCnt, cBitCnt,\
machineType = pq.QMachineType.CPU):
self.m_machine = pq.init_quantum_machine(machineType)
self.m_qlist = self.m_machine.qAlloc_many(quBitCnt)
self.m_clist = self.m_machine.cAlloc_many(cBitCnt)
self.m_prog = pq.QProg()
def __del__(self):
pq.destroy_quantum_machine(self.m_machine)
def test_is_match_topology(q, c):
cx = pq.CNOT(q[1], q[3])
# Building a Topology
qubits_topology = \
[[0,1,0,0,0],[1,0,1,1,0],[0,1,0,0,0],[0,1,0,0,1],[0,0,0,1,0]]
# Determine whether the logic gate conforms to the quantum topology
if (pq.is_match_topology(cx,qubits_topology)) == True:
print('Match !\n')
else:
print('Not match.')
if __name__=="__main__":
init_machine = InitQMachine(16, 16)
qlist = init_machine.m_qlist
clist = init_machine.m_clist
machine = init_machine.m_machine
test_is_match_topology(qlist, clist)
print("Test over.")
Prior to the use of is_match_topology
, the adjacency matrix
qubits_topology
of the qubit topology of the designated quantum chip
should be created.
It can be seen from the above example, qubits_topology
includes 5
qubits. The qubit topological diagram is shown below:
CNOT logic gate operates qubits 1# and 3#. However, it can be seen from the topological diagram that qubits 1# and 3# are interconnected, and therefore the result should be true.
3.6 Get adjacent quantum logic gates at the designated position.
The get_adjacent_qgate_type
interface can get designated adjacent
quantum logic gates in the quantum program. The first input parameter is
the target quantum program QProg, the second input parameter is the
iterator of the target quantum logic gate in the quantum program, and
the returned result is a set of iterators of adjacent target quantum
logic gates.
3.6.1 Example
import pyqpanda.pyQPanda as pq
import math
class InitQMachine:
def __init__(self, quBitCnt, cBitCnt, machineType = pq.QMachineType.CPU):
self.m_machine = pq.init_quantum_machine(machineType)
self.m_qlist = self.m_machine.qAlloc_many(quBitCnt)
self.m_clist = self.m_machine.cAlloc_many(cBitCnt)
self.m_prog = pq.QProg()
def __del__(self):
pq.destroy_quantum_machine(self.m_machine)
def test_get_adjacent_qgate_type(qlist, clist):
prog = pq.QProg()
# Building quantum programs
prog << pq.T(qlist[0]) \
<< pq.CNOT(qlist[1], qlist[2]) \
<< pq.Reset(qlist[1]) \
<< pq.H(qlist[3]) \
<< pq.H(qlist[4])
iter = prog.begin()
iter = iter.get_next()
type =iter.get_node_type()
if pq.NodeType.GATE_NODE == type:
gate = pq.QGate(iter)
print(gate.gate_type())
# Gets the types of logical gates before and after the specified location
list = pq.get_adjacent_qgate_type(prog,iter)
print(len(list))
print(len(list[0].m_target_qubits))
print(list[1].m_is_dagger)
node_type = list[0].m_node_type
print(node_type)
if node_type == pq.NodeType.GATE_NODE:
gateFront = pq.QGate(list[0].m_iter)
print(gateFront.gate_type())
node_type = list[1].m_node_type
print(node_type)
if node_type == pq.NodeType.GATE_NODE:
gateBack = pq.QGate(list[1].m_iter)
print(gateBack.gate_type())
if __name__=="__main__":
init_machine = InitQMachine(16, 16)
qlist = init_machine.m_qlist
clist = init_machine.m_clist
machine = init_machine.m_machine
test_get_adjacent_qgate_type(qlist, clist)
print("Test over.")
The above example shows how to use get_adjacent_qgate_type
interface:
Create one quantum program prog;
Designate position information, namely setting of iter
Invoke
get_adjacent_qgate_type
interface to get a set of iterators of adjacent iter logic gates. The types of obtained logic gates are respectively printed in the last four rows of the example code
When using get_adjacent_qgate_type
interface, we need to note the
following points:
A set of the iterators of adjacent target quantum logic gates always includes two elements; The first element is an iterator of the previous quantum logic gate, and the second element is an iterator of the next logic gate.
If the target quantum logic gate is the first node of the quantum program, only the iterator of the following target quantum logic gate can be obtained in a set of iterators of adjacent target quantum logic gates (as the output parameter), and the first element in the set is the null iterator.
If the target quantum logic gate is the last quantum logic gate in the quantum program, only the iterator of the previous target quantum logic gate can be obtained in a set of iterators of adjacent target quantum logic gates (as the output parameter), and the second element in the set is the null iterator.
If the previous node of the target quantum logic gate is QIf or QWhile, only the iterator of the following target quantum logic gate can be obtained in a set of iterators of adjacent target quantum logic gates (as the output parameter), and the first element in the set is the null iterator.
If the following node of the target quantum logic gate is QIf or QWhile, only the iterator of the previous target quantum logic gate can be obtained in a set of iterators of adjacent target quantum logic gates (as the output parameter), and the second element in the set is the null iterator.
If the target quantum logic gate is the first quantum logic gate of QWhile, only the iterator of the following target quantum logic gate can be obtained in a set of iterators of adjacent target quantum logic gates (as the output parameter), and the first element in the set is the null iterator.
If the target quantum logic gate is the last quantum logic gate of QWhile, only the iterator of the previous target quantum logic gate can be obtained in a set of iterators of adjacent target quantum logic gates (as the output parameter), and the second element in the set is the null iterator.
3.7 Judge whether two quantum logic gates are interchanged for their positions
The is_swappable
interface can judge whether two designated quantum
logic gates in the quantum program are interchanged for their positions.
The first input parameter is the quantum program QProg; the second and
third input parameters are the iterators of two quantum logic gates to
be judged. The returned value is Boolean value; True represents the
interchangeable position; and False represents the non-interchangeable
position.
3.7.1 Example
The following example demonstrates how to use is_swappable
interface.
Create a quantum program prog. Here, a slightly complex quantum program with nested nodes is enumerated;
Get iterators at two designated positions of the nested node cir: iter_first and iter_second;
Invoke
is_swappable
interface to judge whether two designated logic gates are interchanged for their positions, and output changeable judgement results on the console.
import math
class InitQMachine:
def __init__(self, quBitCnt, cBitCnt,\
machineType = pq.QMachineType.CPU):
self.m_machine = pq.init_quantum_machine(machineType)
self.m_qlist = self.m_machine.qAlloc_many(quBitCnt)
self.m_clist = self.m_machine.cAlloc_many(cBitCnt)
self.m_prog = pq.QProg()
def __del__(self):
pq.destroy_quantum_machine(self.m_machine)
# Test interface: judge whether two designated logic gates are interchanged
# for their positions
def test_is_swappable(q, c):
prog = pq.QProg()
cir = pq.QCircuit()
cir2 = pq.QCircuit()
cir2 << pq.H(q[3]) << pq.RX(q[1], math.pi/2) << pq.T(q[2])\
<< pq.RY(q[3], math.pi/2) << pq.RZ(q[2], math.pi/2)
cir2.set_dagger(True)
cir << pq.H(q[1]) << cir2 << pq.CR(q[1], q[2], math.pi/2)
prog << pq.H(q[0]) << pq.S(q[2]) \
<< cir\
<< pq.CNOT(q[0], q[1]) << pq.CZ(q[1], q[2]) << pq.measure_all(q,c)
iter_first = cir.begin()
iter_second = cir2.begin()
#iter_second = iter_second.get_next()
#iter_second = iter_second.get_next()
#iter_second = iter_second.get_next()
type =iter_first.get_node_type()
if pq.NodeType.GATE_NODE == type:
gate = pq.QGate(iter_first)
print(gate.gate_type())
type =iter_second.get_node_type()
if pq.NodeType.GATE_NODE == type:
gate = pq.QGate(iter_second)
print(gate.gate_type())
if (pq.is_swappable(prog, iter_first, iter_second)) == True:
print('Could be swapped !\n')
else:
print('Could NOT be swapped.')
if __name__=="__main__":
init_machine = InitQMachine(16, 16)
qlist = init_machine.m_qlist
clist = init_machine.m_clist
machine = init_machine.m_machine
test_is_swappable(qlist, clist)
print("Test over.")
3.8 Judge whether the logic gates are of a set of quantum logic gates supported by the quantum chip
A set of quantum logic gates supported by the quantum chip can be configured in the metadata configuration file QPandaConfig.xml. If we do not set the configuration files, QPanda sets a default set of quantum logic gates.
The default collection is as follows:
single_gates.push_back("RX");
single_gates.push_back("RY");
single_gates.push_back("RZ");
single_gates.push_back("X1");
single_gates.push_back("H");
single_gates.push_back("S");
double_gates.push_back("CNOT");
double_gates.push_back("CZ");
double_gates.push_back("ISWAP");
The configuration file can be set according to the following example:
"QGate": {
"SingleGate":{
"U3":{"time":1}
},
"DoubleGate":{
"CNOT":{"time":2},
"CZ":{"time":2}
}
}
It can be seen from the above examples that the quantum chip supports
RX, RY, RZ, S, H, X1, CNOT, CZ and ISWAP gates. We may call the
interface is_supported_qgate_type
upon the configuration of the
configuration file, to determine whether the logic gate falls into the
quantum logic gate set that the quantum chip supports. The interface
is_supported_qgate_type
only has one parameter: target quantum logic
gate.
import pyqpanda.pyQPanda as pq
import math
class InitQMachine:
def __init__(self, quBitCnt, cBitCnt,\
machineType = pq.QMachineType.CPU):
self.m_machine = pq.init_quantum_machine(machineType)
self.m_qlist = self.m_machine.qAlloc_many(quBitCnt)
self.m_clist = self.m_machine.cAlloc_many(cBitCnt)
self.m_prog = pq.QProg()
def __del__(self):
pq.destroy_quantum_machine(self.m_machine)
def test_support_qgate_type():
machine = pq.init_quantum_machine(pq.QMachineType.CPU)
q = machine.qAlloc_many(8)
c = machine.cAlloc_many(8)
prog = pq.QProg()
prog << pq.H(q[1])
result = pq.is_supported_qgate_type(prog.begin())
if result == True:
print('Support !\n')
else:
print('Unsupport !')
if __name__=="__main__":
init_machine = InitQMachine(16, 16)
qlist = init_machine.m_qlist
clist = init_machine.m_clist
machine = init_machine.m_machine
test_support_qgate_type()
print("Test over.")
Note
The user may access the default configuration file QPandaConfig.json through the following link, and place it under the same directory as the executive program, which will automatically parse the file.
3.9 Character drawing of quantum circuit
At present, PyQPanda provides three visualization methods of quantum circuit. Please refer to the following examples for specific usage methods.
3.9.1 Example
import pyqpanda.pyQPanda as pq
from pyqpanda.Visualization.circuit_draw import *
import math
class InitQMachine:
def __init__(self, quBitCnt, cBitCnt, machineType = pq.QMachineType.CPU):
self.m_machine = pq.init_quantum_machine(machineType)
self.m_qlist = self.m_machine.qAlloc_many(quBitCnt)
self.m_clist = self.m_machine.cAlloc_many(cBitCnt)
def __del__(self):
pq.destroy_quantum_machine(self.m_machine)
def test_print_qcircuit(q, c):
# Building quantum programs
prog = pq.QCircuit()
prog << pq.CU(1, 2, 3, 4, q[0], q[5]) << pq.H(q[0]) << pq.S(q[2])\
<< pq.CNOT(q[0], q[1]) << pq.CZ(q[1], q[2])\
<< pq.CR(q[2], q[1], math.pi/2)
prog.set_dagger(True)
print('draw_qprog:')
# Through print directly outputs the character drawing of quantum
# circuit. This method will output the quantum circuit in the console,
# and the output format is uft8 encoding. Therefore, in the console
# with non-uft8 encoding, the character drawing of output will be
# garbled.
# At the same time, this method will save the current quantum circuit
#character drawing information to the file named QCircuitTextPic.txt
# the file is encoded with uft8 and saved under the face path.
# Therefore, users can also view quantum circuit information through
# this file. Note that the file must be opened in uft8 format,
# otherwise garbled characters will appear.
print(prog)
# Output quantum circuit character drawing through draw_qprog
# interface. The function of this method is the same as print method,
# but the difference is that this interface can specify the console
# encoding type to ensure that the quantum circuit character drawing
# output on the console can be displayed normally.
# The "console_encode_type" parameter is used to specify the console
# type. Currently, two encoding modes are supported: utf8 and gbk. The
# default is utf8
draw_qprog(prog, 'text', console_encode_type='gbk')
# The draw_qprog interface can also save the quantum circuit as a
# picture, called as follows. The “filename” parameter is used to
# specify a filename to save.
draw_qprog(prog, 'pic', filename='D:/test_cir_draw.png')
if __name__=="__main__":
init_machine = InitQMachine(16, 16)
qlist = init_machine.m_qlist
clist = init_machine.m_clist
machine = init_machine.m_machine
test_print_qcircuit(qlist, clist)
The above example demonstrates the draw_qprog
interface, respectively.
The output from the above code is as follows:
The output quantum circuit picture effect is as follows:
The parameters of draw_qprog()
are described as follows:
"""Draw a quantum circuit to different formats (set by output parameter):
**text**: ASCII art TextDrawing that can be printed in the console.
**pic**: images with color rendered purely in Python.
Args:
prog : the quantum circuit to draw
scale (float): scale of image to draw (shrink if < 1). Only used by the ``pic`` outputs.
filename (str): file path to save image to
NodeIter_first: circuit printing start position.
NodeIter_second: circuit printing end position.
console_encode_type(str): Target console encoding type.
Mismatching of encoding types may result in character confusion, 'utf8' and 'gbk' are supported.
Only used by the ``pic`` outputs.
line_length (int): Sets the length of the lines generated by `text` output type.
Returns: no return
"""
def draw_qprog(prog, output=None, scale=0.7, filename=None, line_length=None, NodeIter_first=None, \
NodeIter_second=None, console_encode_type = 'utf8'):
As a demonstration, we change the test_print_qcircuit()
interface
implementation from the example code above to the following:
prog = pq.QCircuit()
prog << pq.CU(1, 2, 3, 4, q[0], q[5]) << pq.H(q[0]) << pq.S(q[2]) << pq.CNOT(q[0], q[1]) << pq.CZ(q[1], q[2]) << pq.CR(q[2], q[1], math.pi/2)
iter_start = prog.begin()
iter_end = iter_start.get_next()
iter_end = iter_end.get_next()
iter_end = iter_end.get_next()
prog.set_dagger(True)
draw_qprog(prog, 'text', NodeIter_first=iter_start, NodeIter_second=iter_end, console_encode_type='gbk')
draw_qprog(prog, 'pic', NodeIter_first=iter_start, NodeIter_second=iter_end, filename='D:/test_cir_draw.jpg')
The above example code will output only the first 4 logical gate nodes of prog, users can replace the above code to the previous example program, run to view the results, not repeated here.
3.10 Quantum volume
3.10.1 Introduction
Quantum volume is a protocol used to evaluate the performance of the quantum computing system. It represents the random circuit with the maximum equal width depth that can be performed on the system. The higher the operating fidelity of the quantum computing system is, the higher the correlation is; the larger the gate operation set calibrated is, the higher the quantum volume is. Quantum volume relates to the overall performance of the system, including the overall error rate of the system, potential physical qubit correlation, and gate operation parallelism. Generally speaking, quantum volume is practical method for making an overall evaluation of the quantum computing system in the near future; the higher the value is, the lower the overall error rate of the system is, the better the performance is.
To measure the quantum volume in a standard way is to perform random circuit operations for the system with specified quantum circuit model, entangle qubits as far as possible, and compare the experimental results with the simulated results. The statistical results are analyzed as required.
Quantum volume is defined in the exponential form:
Where n is the maximum logical depth of system operation under the given number of qubits m (m is greater than n) and the completion of computing tasks; if the maximum executive logical depth of the chip n is greater than the number of qubits m, the quantum volume of the system is
3.10.2 Interface description
The input parameters of calculate_quantum_volume
are the noise
simulator or quantum cloud machine, qubit to be measured, number of
random iterations, and number of measurements. The output is size_t,
which is the quantum volume size.
3.10.3 Example
from pyqpanda import *
if __name__=="__main__":
# Create a noise simulator and set noise parameters
qvm = NoiseQVM()
qvm.init_qvm()
qvm.set_noise_model(NoiseModel.DEPOLARIZING_KRAUS_OPERATOR, GateType.CZ_GATE, 0.005)
# You can also apply for cloud computing machines (using real chips), using real chips
# to consider the chip structure
#qvm = QCloud()
#qvm.init_qvm("898D47CF515A48CEAA9F2326394B85C6")
# Construct the qubit combination to be measured, where the qubit combination is two
# groups; the qubit 3 and 4 are a group, qubits 2, 3, and 5 are a group.
qubit_lists = [[3,4], [2,3,5]]
# Set the number of random iterations
ntrials = 100
# Set the measurement times, namely real chip or noise simulator shots value
shots = 2000
qv_result = calculate_quantum_volume(qvm, qubit_lists, ntrials, shots)
print("Quantum Volume : ", qv_result)
qvm.finalize()
Running results:
Quantum Volume : 8
3.11 Random benchmark
3.11.1 Introduction
Random benchmark (RB) is a benchmark test for quantum gates with a randomization method. Since the complete process tomography doesn’t work for the large system, more attention is paid to the extensible method, to characterize noise that affects the quantum system. An extensible and robust algorithm (a system comprising n qubits) is put forward in [1], i.e. benchmark test is performed for the whole Clifford gate by a single parameter with the randomizing technique.
3.11.2 Interface description
The input parameters of single_qubit_rb
are the noise simulator or
quantum cloud machine, qubit to be measured, a different number of
combinations of random circuit clifford gate sets, number of random
circuits, number of measurements, verification of basic logic gate
(default: none), output being std::map
data, key value being the number
of clifford gate sets, and value corresponding to the expected
probability.
The input parameters of double_qubit_rb
are the noise simulator or
quantum cloud machine, qubit 0 to be measured, qubit 1 to be measured, a
different number of combinations of random circuit clifford gate sets,
number of random circuits, number of measurements, verification of basic
logic gate (default: none), output being std::map
data, key value being
the number of clifford gate sets, and value corresponding to the
expected probability.
from pyqpanda import *
if __name__=="__main__":
# Build a noise simulator and adjust the noise to simulate the real chip
qvm = NoiseQVM()
qvm.init_qvm()
qvm.set_noise_model(NoiseModel.DEPOLARIZING_KRAUS_OPERATOR, GateType.CZ_GATE, 0.005)
qvm.set_noise_model(NoiseModel.DEPOLARIZING_KRAUS_OPERATOR, GateType.PAULI_Y_GATE,\ 0.005)
qv = qvm.qAlloc_many(4)
# You can also apply for cloud computing machines (with real chips)
# qvm = QCloud()
# qvm.init_qvm("898D47CF515A48CEAA9F2326394B85C6")
# Set the number of Clifford gates in a random line
range = [ 5,10,15 ]
# Measuring a single qubit random reference
res = single_qubit_rb(qvm, qv[0], range, 10, 1000)
# It is also possible to measure two-qubit random datum
#res = double_qubit_rb(qvm, qv[0], qv[1], range, 10, 1000)
# With the influence of noise, the larger the noise value is, the smaller the result
# is. And with the increase of Clifford gate set, the smaller the result is.
print(res)
qvm.finalize()
3.11.3 Example
Running results:
{5: 0.9996, 10: 0.9999, 15: 0.9993000000000001}
3.12 Cross-entropy benchmark
3.12.1 Introduction
Cross-entropy benchmark (xeb) is a method used to evaluate the gate performance by applying the random circuits and measuring the cross-entropy between the observed values of bit strings and the expected probability of such bit strings obtained from the simulation.
3.12.2 Interface description
The input parameters of double_gate_xeb
are the noise simulator or
quantum cloud machine, qubit 0 to be measured, qubit 1 to be measured,
different layers of circuits, number of random circuits, number of
measurements, verification of double-gate type (default: CZ gate),
output being std::map data, key value being the number of circuit
layers, and value corresponding to the expected probability.
3.12.3 Example
from pyqpanda import *
if __name__=="__main__":
# Build a noise simulator and adjust the noise to simulate the real chip
qvm = NoiseQVM()
qvm.init_qvm()
qv = qvm.qAlloc_many(4)
# Setting noise Parameters
qvm.set_noise_model(NoiseModel.DEPOLARIZING_KRAUS_OPERATOR, GateType.CZ_GATE, 0.1)
# You can also apply for cloud computing machines (with real chips)
# qvm = QCloud()
# qvm.init_qvm("898D47CF515A48CEAA9F2326394B85C6")
# Set different layer combinations
range = [2,4,6,8,10]
# Currently, the main testable dual-gate types are CZ CNOT SWAP ISWAP SQISWAP
res = double_gate_xeb(qvm, qv[0], qv[1], range, 10, 1000, GateType.CZ_GATE)
# With the influence of noise, the larger the noise value is, the smaller the result
# will be; and the number of layer increases, the smaller the result will be.
print(res)
qvm.finalize()
Running results:
{2: 0.9922736287117004, 4: 0.9303175806999207, 6: 0.7203856110572815, 8: 0.7342230677604675, 10: 0.7967881560325623}