4 Compiling of quantum program
4.1 Conversion of QASM by a quantum program
You may parse the quantum program created by QPanda2 with this function module, and extract the qubit information and quantum logic gate operation information contained therein, to obtain the QASM instruction set saved in a fixed form.
4.1.1 QASM introduction
Quantum Assembly Language is put forward by IBM, and is similar to the syntax rules in the QRunes introduction; a QASM code segment is as follows:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[10];
creg c[10];
x q[0];
h q[1];
tdg q[2];
sdg q[2];
cx q[0],q[2];
cx q[1],q[4];
u1(pi) q[0];
u2(pi,pi) q[1];
u3(pi,pi,pi) q[2];
cz q[2],q[5];
ccx q[3],q[4],q[6];
cu3(pi,pi,pi) q[0],q[1];
measure q[2] -> c[2];
measure q[0] -> c[0];
It should be noted that the syntax formats of QASM and QRunes are alike but different, with the following differences:
For quantum logic gates and quantum circuits requiring the transposed conjugate, QRunes needs to place the target between DAGGER and ENDAG-GER sentences; QASM does the conversion directly.
QRunes supports the control operation of the quantum logic gates and quantum circuits, but QASM doesn’t. Before the conversion of QASM by a quantum program, the control operation contained therein will be decomposed.
QPanda2 provides the QASM conversion tool interface
convert_qprog_to_qasm
, which is easy to use. Reference can be made to
the following example program.
4.1.2 Example
The following routine demonstrates the process of converting QASM instruction set by a quantum program through a simple interface call.
from pyqpanda import *
if __name__ == "__main__":
qvm = init_quantum_machine(QMachineType.CPU)
q = qvm.qAlloc_many(6)
c = qvm.cAlloc_many(6)
prog = QProg()
cir = QCircuit()
cir << T(q[0]) << S(q[1]) << CNOT(q[1], q[0])
prog << cir
prog << X(q[0]) << Y(q[1]) << CU(1.2345, 3, 4, 5, q[5], q[2])\
<< H(q[2]) << RX(q[3], 3.14)\
<< Measure(q[0], c[0])
qasm = convert_qprog_to_qasm(prog, qvm)
print(qasm)
qvm.finalize()
The specific steps are as follows:
Firstly, initialize a quantum simulator object with
init_quantum_machine
in the main program, in order to manage a series of subsequent behaviorsThen, initialize the number of qubits and classical registers with
qAlloc_many
andcAlloc_many
.Next, call
QProg
to create the quantum program.Finally, the interface
convert_qprog_to_qasm
is called to output the QASM instruction set;finalize ()
is used to release system resources
The running results are as follows:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[6];
creg c[6];
u3(0,0.78539816339744828,0) q[0];
u3(0,1.5707963267948966,0) q[1];
cx q[1],q[0];
u3(3.1415926535897931,0,3.1415926535897931) q[0];
u3(3.1415926535897931,0,0) q[1];
u3(0,-0.33629632679489674,0) q[5];
u3(0,-0.67259265358979359,0) q[2];
cx q[5],q[2];
u3(0,0.33629632679489674,0) q[2];
cx q[5],q[2];
u3(1.1415926535897929,3.1415926535897931,2.8672963267948974) q[2];
u3(0,1.5707963267948963,0) q[5];
cx q[5],q[2];
u3(1.1415926535897929,-1.1947036732051033,0) q[2];
cx q[5],q[2];
u3(1.5707963267949034,0,-1.3362963267948968) q[2];
u3(3.1400000000000001,-1.5707963267948966,1.5707963267948966) q[3];
measure q[0] -> c[0];
4.2 Conversion into a quantum program by QASM
You may parse the QASM text file with this function module, and extract the quantum logic gate operation information therein, to obtain the quantum program that is operable in QPanda 2.
4.2.1 QASM introduction
Reference can be made to the QASM introduction in the module of converting QASM by a quantum program for the writing format specifications and routines of QASM.
QPanda 2 provides the QASM file conversion tool interface
convert_qasm_to_qprog()
, which is easy to use. Reference can be made
to the following example program.
4.2.2 Example
The following demonstrates the process of converting the quantum program by QASM instruction set through a simple interface call.
from pyqpanda import *
if __name__=="__main__":
machine = init_quantum_machine(QMachineType.CPU)
# Write QASM files
f = open('testfile.txt', mode='w',encoding='utf-8')
f.write("""// test QASM file
OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[3];
x q[0];
x q[1];
z q[2];
h q[0];
tdg q[1];
measure q[0] -> c[0];
""")
f.close()
# QASM converts quantum programs and returns quantum programs, quantum bits,
# and classical registers
prog_trans, qv, cv = convert_qasm_to_qprog("testfile.txt", machine)
# Quantum program conversion QASM
qasm = convert_qprog_to_qasm(prog_trans,machine)
# Print and compare the conversion results
print(qasm)
destroy_quantum_machine(machine)
The specific steps are as follows:
Firstly, compile QASM and save it in a designated file
Then, initialize a quantum simulator object with
init_quantum_machine
in the main program, in order to manage a series of subsequent behaviorsNext, call the
convert_qasm_to_qprog
interface to convert QASM into a quantum programFinally, call the
convert_qprog_to_qasm
interface to convert the quantum program into QASM, decide whether QASM is converted into the quantum program correctly by comparing the execution results of the quantum program, and release system resources bydestroy_quantum_machine
The running results are as follows:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[3];
u3(1.5707963267949037,3.1415926535897931,3.1415926535897931) q[0];
u3(3.1415926535897931,2.3561944901923386,0) q[1];
u3(0,3.1415926535897931,0) q[2];
measure q[0] -> c[0];
Note
In the above example, since QASM supports U3 gate, the quantum circuit is optimized when QProg is converted to QASM, and only U3 gate is in the output QASM, which can effectively reduce the quantum circuit depth. For the types that are not supported temporarily, errors may occur during the process of converting QASM into a quantum program.
4.3 Conversion into Quil by a quantum program
4.3.1 Introduction
Quil can directly describe quantum programs and quantum algorithms from a very low level, which is similar to the hardware description language or assembly language in classical computers. Quil basically adopts the design method of “instruction + parameter list”. An example of a simple quantum program is as follows:
X 0
Y 1
CNOT 0 1
H 0
RX(-3.141593) 0
MEASURE 1 [0]
● The purpose of X
is to perform Pauli-X
gate operations on target qubits.
Similar keywords include Y
, Z
, H
, etc.
● The purpose of Y
is to perform Pauli-Y
gate operations on target
qubits.
● The purpose of CNOT
is to perform CNOT
operations on two qubits. The
input parameters are the control qubit serial number and target qubit
serial number.
● The purpose of H
is to perform Hadamard
gate operations on target
qubits.
● The purpose of MEASURE
is to measure target qubits and save the
measuring results in a classical register. The input parameters are
serial numbers of target qubits and classical registers where the
measuring results are saved.
The above is just a small part of Quil instruction set syntax. Reference can be made to pyQuil for more details.
4.3.2 Interface introduction
We create a quantum program with pyqpanda at first:
prog = QProg()
prog << X(qubits[0]) << Y(qubits[1])\
<< H(qubits[2]) << RX(qubits[3], 3.14)\
<< Measure(qubits[0], cbits[0])
Then ,call the convert_qprog_to_quil
for the transformation
quil = convert_qprog_to_quil(prog, qvm)
4.3.3 Example
from pyqpanda import *
if __name__ == "__main__":
qvm = init_quantum_machine(QMachineType.CPU)
qubits = qvm.qAlloc_many(4)
cbits = qvm.cAlloc_many(4)
prog = QProg()
# Building quantum programs
prog << X(qubits[0]) << Y(qubits[1])\
<< H(qubits[2]) << RX(qubits[3], 3.14)\
<< Measure(qubits[0], cbits[0])
# The quantum program converts the Quil and prints the Quil
quil = convert_qprog_to_quil(prog, qvm)
print(quil)
qvm.finalize()
Running results:
X 0
Y 1
H 2
RX(3.140000) 3
MEASURE 0 [0]
Warning
The new interface convert_qprog_to_quil()
is provided with the same function as the old one transform_qprog_to_quil()
.
4.4 Serialization of quantum programs
4.4.1 Introduction
A protocol is defined to serialize quantum programs to binary data for the convenience of saving and transmitting quantum programs.
4.4.2 Interface introduction
We create a quantum program with pyqpanda at first:
prog = QProg()
prog << H(qubits[0]) \
<< CNOT(qubits[0], qubits[1]) \
<< CNOT(qubits[1], qubits[2]) \
<< CNOT(qubits[2], qubits[3])
Next, call the convert_qprog_to_binary
interface for serialization.
prog_str = convert_qprog_to_binary(prog, qvm)
Note
Quantum program serialization is a two-step process that first serializes a quantum program into a binary and then converts the binary into a string encoded in base 64 format.
4.4.3 Example
from pyqpanda import *
import base64
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]) \
<< CNOT(qubits[1], qubits[2]) \
<< CNOT(qubits[2], qubits[3])
# Quantum program serialization
binary_data = convert_qprog_to_binary(prog, qvm)
# The resulting binary data is encoded in Base64 and printed
str_base64_data = base64.encodebytes(bytes(binary_data))
print(str_base64_data)
destroy_quantum_machine(qvm)
Running results:
b'AAAAAAQAAAAEAAAABAAAAA4AAQAAAAAAJAACAAAAAQAkAAMAAQACACQABAACAAMA\n'
Note
The binary data cannot be output directly and should be subject to base64 encoding, to obtain corresponding character strings.
Warning
The new interface convert_qprog_to_binary()
is provided with the same function as the old one transform_qprog_to_binary()
.
4.5 Parse quantum program binary files
4.5.1 Introduction
Parse quantum programs that are serialized by the quantum program serialization method.
4.5.2 Interface introduction
We create a quantum program with pyqpanda at first:
prog = QProg()
prog << H(qubits[0]) \
<< CNOT(qubits[0], qubits[1]) \
<< CNOT(qubits[1], qubits[2]) \
<< CNOT(qubits[2], qubits[3])
After the serialization and base64 encoding, the result is (refer to the quantum program serialization for specific serialized method).
b'AAAAAAQAAAAEAAAABAAAAA4AAQAAAAAAJAACAAAAAQAkAAMAAQACACQABAACAAMA\n'
Now, deserialized this result. Firstly, decode the base64 result into binary data:
str_base64_data =b'AAAAAAQAAAAEAAAABAAAAA4AAQAAAAAAJAACAAAAAQAkAAMAAQACACQABAACAAMA\n'
data = [int(x) for x in bytes(base64.decodebytes(str_base64_data))]
We may use one interface encapsulated by QPanda2:
convert_binary_data_to_qprog(qvm, data, qubits_parse, cbits_parse, parseProg);
4.5.3 Example
from pyqpanda import *
import base64
if __name__ == "__main__":
qvm = init_quantum_machine(QMachineType.CPU)
# Base64 decoding of the way to get binary data
str_base64_data =\ b'AAAAAAQAAAAEAAAABAAAAA4AAQAAAAAAJAACAAAAAQAkAAMAAQACACQABAACAAMA\n';
data = [int(x) for x in bytes(base64.decodebytes(str_base64_data))]
# Parse binary data, get quantum programs
parseProg = QProg()
parseProg = convert_binary_data_to_qprog(qvm, data)
# The quantum program converts OriginIR and prints it
print(convert_qprog_to_originir(parseProg,qvm))
destroy_quantum_machine(qvm)
Running results:
QINIT 4
CREG 4
H q[0]
CNOT q[0],q[1]
CNOT q[1],q[2]
CNOT q[2],q[3]
Note
If the running results are correct, serialized quantum programs can beparsed correctly
Warning
The new interface convert_binary_data_to_qprog()
is provided with the same function as the old one transform_binary_data_to_qprog()
.
4.6 Conversion into a quantum program by OriginIR
You may parse the OriginIR text file with this function module, and extract the quantum logic gate operation information therein, to obtain the quantum program that is operable in QPanda 2.
4.6.1 OriginIR
Reference can be made to the OriginIR introduction in the module of converting OriginIR by a quantum program for the writing format specifications and routines of OriginIR.
QPanda 2 provides the OriginIR file conversion tool interface
convert_originir_to_qprog()
,which is easy to use. Reference can be
made to the following example program.
4.6.2 Example
The following demonstrates the process of converting the quantum program by OriginIR through a simple interface call.
from pyqpanda import *
if __name__=="__main__":
machine = init_quantum_machine(QMachineType.CPU)
# Write OriginIR files
f = open('testfile.txt', mode='w',encoding='utf-8')
f.write("""QINIT 4
CREG 4
DAGGER
X q[1]
X q[2]
CONTROL q[1], q[2]
RY q[0], (1.047198)
ENDCONTROL
ENDDAGGER
MEASURE q[0], c[0]
QIF c[0]
H q[1]
H q[2]
RZ q[2], (2.356194)
CU q[2], q[3], (3.141593, 4.712389, 1.570796, -1.570796)
CNOT q[2], q[1]
ENDQIF
""")
f.close()
# OriginIR converts a quantum program and returns the converted quantum
# program, the quantum bits used by the quantum program, and the classical
# registers
prog, qv, cv = convert_originir_to_qprog("testfile.txt", machine)
# The quantum program converts OriginIR, prints and compares the conversion
# results
print(convert_qprog_to_originir(prog,machine))
destroy_quantum_machine(machine)
The specific steps are as follows:
● Firstly, compile OriginIR and save it in a designated file
● Then, initialize a quantum simulator object with
init_quantum_machine
in the main program in order to manage a series
of subsequent behaviors
● Next, call convert_originir_to_qprog()
for the conversion
● Finally, call the convert_qprog_to_originir()
to convert the
quantum program into OriginIR, decide whether OriginIR is converted into
the quantum program correctly by comparing whether the QASMs input and
generated are the same, and release system resources by
destroy_quantum_machine
The running results are as follows:
QINIT 4
CREG 4
DAGGER
X q[1]
X q[2]
CONTROL q[1],q[2]
RY q[0],(1.047198)
ENCONTROL
ENDDAGGER
MEASURE q[0],c[0]
QIF c[0]
H q[1]
H q[2]
RZ q[2],(2.356194)
CU q[2],q[3],(3.141593,4.712389,1.570796,-1.570796)
CNOT q[2],q[1]
ENDQIF
Note
For the types that are not supported temporarily, errors may occur during the process of converting OriginIR into a quantum program.
Warning
The new interface convert_originir_to_qprog()
is provided with the same function as the old one transform_originir_to_QProg()
.
4.7 Conversion of OriginIR by a quantum program
You may parse the quantum program created by pyqpanda with this function module, and extract the qubit information and quantum logic gate operation information contained therein, to obtain the OriginIR saved in a fixed form.
4.7.1 OriginIR introduction
OriginIR is an intermediate representation of quantum programs based on QPanda, and plays an important role in supporting properties of QPanda. OriginIR not only indicates most of the quantum logic gate types, indicates dagger operation for quantum circuits, and adds control qubits for quantum circuits, but also supports Qif and QWhile unique to QPanda and implements classical programs where quantum programs are embedded.
OriginIR mainly includes qubit, classical register, quantum logic gate, transposed conjugate operation, adding control qubit operation, QIf, QWhile, and classical expression.
4.7.1.1 Qubit
OriginIR applies for qubits with QINIT. The format is QINIT followed by space + the total number of qubits, like QINIT 6. It should be noted that QINIT must be at the first row of the OriginIR program, except notes. When qubits are used, OriginIR uses q[i] to indicate a certain specific qubit; i is the No. of the qubit, and can be a unsigned numerical constant or a variable; it can also use an alternate expression comprising c[i], like q[1], q[c[0]], q[c[1]+c[2]+c[3]].
4.7.1.2 Classical register
OriginIR applies for classical registers with CREG. The format is CREG followed by space + the total number of classical registers, like CREG 6; when the classical registers are used, OriginIR uses c[i] to indicate a certain specific classical register; i is the No. of the classical register, and must be an unsigned numeric constant, like c[1].
4.7.1.3 Quantum logic gate
OriginIR divides quantum logic gates into the following categories: keywords of the single-gate without parameters, single-gate with one parameter, single-gate with two parameters, single-gate with three parameters, single-gate with four parameters, double-gate without parameters, double-gate with one parameter, double-gate with four parameters, and tri-gate without parameters. It should be noted that for all single-gate operations, the target qubit can be the entire qubit array or a single qubit. In case of the entire qubit array, for example:
H q
When the qubit array size is 3, it is equivalent to:
H q[0]
H q[1]
H q[2]
1.Keywords of the single-gate without parameters: H, T, S, X, Y, Z, X1, Y1, Z1, and I; indicating the single-quantum logic gate without parameters; the format is quantum logic gate keyword + space + target qubit. Example:
H q[0]
2.Keywords of the single-gate with one parameter: RX, RY, RZ, and U1; indicating the single-quantum logic gate with one parameter; the format is quantum logic gate keyword + space + target qubit + comma + (deflection angle). Example:
RX q[0],(1.570796)
3.Keywords of the single-gate with two parameters: U2 and RPhi; indicating the single-quantum logic gate with two parameters; the format is quantum logic gate keyword + space + target qubit + comma + (two deflection angles). Example:
U2 q[0],(1.570796,-3.141593)
4.Keyword of the single-gate with three parameters: U3; indicating the single-quantum logic gate with three parameters; the format is quantum logic gate keyword + space + target qubit + comma + (three deflection angles). Example:
U3 q[0],(1.570796,4.712389,1.570796)
5.Keyword of the single-gate with four parameters: U4; indicating the single-quantum logic gate with four parameters; the format is quantum logic gate keyword + space + target qubit + comma + (four deflection angles). Example:
U4 q[1],(3.141593,4.712389,1.570796,-3.141593)
6.Keywords of the double-gate without parameters: CNOT, CZ, ISWAP, SQISWAP, and SWAP; indicating the double-quantum logic gate without parameters; the format is quantum logic gate keyword + space + control qubit + comma + target qubit. Example:
CNOT q[0],q[1]
7.Keywords of the double-gate with one parameter: ISWAPTHETA and CR; indicating the single-quantum logic gate with one parameter; the format is quantum logic gate keyword + space + control qubit + comma + target qubit + comma + (deflection angle). Example:
CR q[0],q[1],(1.570796)
8.Keyword of the double-gate with four parameters: CU; indicating the single-quantum logic gate with four parameters; the format is quantum logic gate keyword + space + control qubit + comma + target qubit + comma + (four deflection angles). Example:
CU q[1],q[3],(3.141593,4.712389,1.570796,-3.141593)
9.Keyword of the tri-gate without parameters: TOFFOLI; indicating the tri-quantum logic gate without parameters; the format is quantum logic gate keyword + space + control qubit 1 + comma + control qubit 2 + comma + target qubit. Example:
TOFFOLI q[0],q[1],q[2]
4.7.1.4 Transposed conjugate operation
The transposed conjugate operation can be performed for one or more quantum logic gates in OriginIR, which defines the range of transposed conjugate operation with keywords, i.e. DAGGER and ENDDAGGER. One DAGGER must match with one ENDDAGGER; for example:
DAGGER
H q[0]
CNOT q[0],q[1]
ENDDAGGER
4.7.1.5 Adding control qubit operation
The control qubits can be added for one or more quantum logic gates in OriginIR, which defines the range of adding control qubits with keywords, i.e. CONTROL and ENDCONTROL. CONTROL is followed by space + control qubit list; Example:
CONTROL q[2],q[3]
H q[0]
CNOT q[0],q[1]
ENDCONTROL
4.7.1.6 QIF
The judgment programs for quantum conditions can be indicated in OriginIR, which determines the range of different ranches of judgment programs for quantum conditions by QIF, ELSE, and ENDIF. QIF must match with one ENDIF; if QIF has two branches, ELSE is required; if QIF only has one branch, ELSE is not required; QIF is followed by space + judgment expression. Example:
1、QIF There's only one conditional branch
QIF c[0]==c[1]
H q[0]
CNOT q[0],q[1]
ENDIF
2、QIF There are two conditional branches
QIF c[0]+c[1]<5
H q[0]
CNOT q[0],q[1]
ELSE
H q[0]
X q[1]
ENDIF
4.7.1.7 QWHILE
The judgment programs for quantum loops can be indicated in OriginIR, which determines the range of judgment programs for loops by QIF, ELSE, and ENDIF; QWHILE is followed by space + judgment expression. Example:
QWHILE c[0]<5
H q[c[0]]
c[0]=c[0]+1
ENDQWHILE
4.7.1.8 Classical expression
OriginIR can embed a classical expression in the quantum program, like c[0]==c[1]+c[2]; Example:
QWHILE c[0]<5
H q[c[0]]
c[0]=c[0]+1
ENDQWHILE
The expression indicates the H gate operation performed for q[0]~q[4] qubit; the classical expression must be comprised of classical registers and constants; the operators of the classical expression include.
{PLUS , "+"},
{MINUS, "-"},
{MUL, "*"},
{DIV, "/"},
{EQUAL, "==" },
{ NE, "!=" },
{ GT, ">" },
{ EGT, ">=" },
{ LT, "<" },
{ ELT, "<=" },
{AND, "&&"},
{OR, "||"},
{NOT, "!"},
{ASSIGN, "=" }
4.7.1.9 MEASURE operation
MEASURE indicates the measurement operation performed for designated qubits, and saving the results to the designated classical register. MEASURE is followed by space + target qubit + ‘,’ + target classical register. Example:
MEASURE q[0],c[0]
If the number of qubits applied is the same as that of the classical registers, q can be used to indicate all qubits, and c indicates all classical bits. Example:
MEAUSRE q,c
If the number of qubits and the number of classical bits are 3 respectively, it is equivalent to
MEAUSRE q[0],c[0]
MEAUSRE q[1],c[1]
MEAUSRE q[2],c[2]
4.7.1.10 RESET operation
RESET operation is to reset the quantum state of qubits operated to zero. The format is RESET + space + target qubit where the target qubit can be the entire qubit array or a single qubit. Example:
RESET q
RESET q[1]
4.7.1.11 BARRIER operation
BARRIER operation is to block the qubits operated, so as to prevent the optimization and execution on the circuit. The format is BARRIER + space + target qubit where the target qubit can be the entire qubit array or a single qubit or multiple qubits. Example:
BARRIER q
BARRIER q[0]
BARRIER q[0],q[1],q[2]
4.7.1.12 QGATE operation
QGATE is user-defined logic gate operation, during which multiple logic gates can be combined into a new one. The scope of user-defined logic gates is framed through QGATE and ENDQGATE. It should be noted that the parameter name of the user-defined logic gate can not conflict with any of the related keywords as described above.
The rules for declaration of user-defined logic gates are as below:
QGATE UserDefinedeGateName BitParameter,(angle)
//UserDefinedeGateName, user-defined logical gate name,string
//BitParameter, user-defined logical gate parameter information,string
//angle, angle information,string
// Other relevant information[","、"(" etc.]It must be written in the defined format
// Among them ",” and subsequent information can be blank, the angle information can be null
A simplified example is shown below:
QGATE new_H a
H a
X a
ENDQGATE
QGATE new_RX a,(b)
RX a,(PI/2+b)
CONTROL q[0]
RX a,(-3.141593)
DAGGER
H a
ENDDAGGER
ENDCONTROL
DAGGER
H a
DAGGER
H a
ENDDAGGER
ENDDAGGER
ENDQGATE
The user, after applying for qubits and classical registers, can call user-defined logic gates in the following format:
UserDefinedeGateName argue,(angle)
//UserDefinedeGateName, user-defined logical gate name,string, be consistent with the definition section above
//BitParameter, user-defined logical gate parameter information,string,It must be q[x], and x needs to be less than the number of qubits requested
//angle, angle information,string,it can be a number, or an expression related to PI
A simplified example is shown below:
new_H q[0]
new_RX q[1],(PI/4)
4.7.1.13 OriginIR program example
OPE algorithm
QINIT 3
CREG 2
H q[2]
H q[0]
H q[1]
CONTROL q[1]
RX q[2],(-3.141593)
ENCONTROL
CONTROL q[0]
RX q[2],(-3.141593)
RX q[2],(-3.141593)
ENCONTROL
DAGGER
H q[1]
CR q[0],q[1],(1.570796)
H q[0]
ENDDAGGER
MEASURE q[0],c[0]
MEASURE q[1],c[1]
QPanda2 provides an OriginIR conversion interface (std::string
convert_qprog_to_originir()
which is easy to use. See the following
example program for details.
4.7.2 Example
The following example demonstrates the process of converting OriginIR by a quantum program through a simple interface call.
from pyqpanda import *
if __name__ == "__main__":
machine = init_quantum_machine(QMachineType.CPU)
qlist = machine.qAlloc_many(4)
clist = machine.cAlloc_many(4)
prog = create_empty_qprog()
prog_cir = create_empty_circuit()
# Building quantum circuits
prog_cir << Y(qlist[2]) << H(qlist[2]) << CNOT(qlist[0],qlist[1])
# Build a QWhile that uses quantum circuitry for loop branching
qwhile = create_while_prog(clist[1], prog_cir)
# Build the quantum program and insert QWhile into the quantum program
prog << H(qlist[2]) << Measure(qlist[1],clist[1]) << qwhile
# The quantum program converts the QriginIR and prints the OriginI
print(convert_qprog_to_originir(prog,machine))
destroy_quantum_machine(machine)
The specific steps are as follows:
● Firstly, initialize a quantum simulator object with
init_quantum_machine
in the main program in order to manage a series
of subsequent behaviors.
● Then, initialize the number of qubits and classical registers with
qAlloc_many
and cAlloc_many
.
● Next, call create_empty_qprog
to create the quantum program.
● Finally, Call the convert_qprog_to_originir
interface to output the
OriginIR,string and use destroy_quantum_machine
to release system
resources.
The running results are as follows:
QINIT 4
CREG 4
H q[2]
MEASURE q[1],c[1]
QWHILE c[1]
Y q[2]
H q[2]
CNOT q[0],q[1]
ENDQWHILE
Note
For operations which are not currently supported, OriginIR will display UnSupported XXXNode where XXX indicates the type of nodes.
Warning
The new interface convert_qprog_to_originir()
is provided with the same function as the old one transform_qprog_to_originIR()
.
4.8 Quantum program matching topology
A quantum computing device has finite connections between qubits, allowing only two qubit gates to be applied to finite pairs of qubits. When the quantum program is applied to the target device, the original quantum program must be converted to adapt to the hardware restriction to allow the two qubits in the double qubit gates in compliance with the physical topology, thus to ensure normal operation of the double qubit gates. Most of the existing solutions require inserting additional SWAP operations between two qubits failing to interact in order to “move” the logic qubits to a position where they can interact. This solution is called quantum program matching topology.
4.8.1 Interface description
Two matching topology methods are available in the current version:
Interface topology_match
By adopting circuit layering and A* search algorithms, the number of inserted SWAP operations is approximately minimized in the process of matching thus to minimize the overall approximate consumption of the algorithms. The interface requires input of 5 parameters: the quantum program constructed, the set of qubits used, the simulator pointer initialized, the mode of SWAP operation used, and the type of topology. And also the interface can return to the mapped quantum program.
4.8.2 Example
from pyqpanda import *
if __name__=="__main__":
qvm = CPUQVM()
qvm.init_qvm()
qv = qvm.qAlloc_many(16)
c = qvm.cAlloc_many(16)
src_prog = QProg()
# Building quantum programs
src_prog << CNOT(qv[0], qv[3]) \
<< CNOT(qv[0], qv[2]) \
<< CNOT(qv[1], qv[3]) \
<< CZ(qv[1], qv[2]) \
<< CZ(qv[0], qv[2]) \
<< T(qv[1]) \
<< S(qv[2]) \
<< H(qv[3])
# The probability measurement of src_prog results in results_1
qvm.directly_run(src_prog)
results_1 = qvm.pmeasure_no_index(qv)
# The quantum program out_prog matching IBM_QX5_ARCH topology is obtained
# by topology matching src_prog
out_prog, out_qv = topology_match(src_prog, qv, qvm, CNOT_GATE_METHOD,\ IBM_QX5_ARCH)
# The probability of out_prog is measured and the result is results_2
qvm.directly_run(out_prog)
results_2 = qvm.pmeasure_no_index(out_qv)
# Compare the probability measurement results_1 and Results_2, and print
# the same result
len = min(len(results_1), len(results_2))
for index in range(len):
if abs(results_1[index] - results_2[index]) < 1.0e-6 :
print(results_1[index])
else:
print("The results are different")
destroy_quantum_machine(qvm)
The specific steps are as follows:
● Firstly, create a quantum simulator, a quantum register and a classical register.
● Then, write the quantum program src_prog
, and measure the probability
of the program to obtain the result_1
.
● Next, call topology_match()
to map src_prog
to a circuit in
compliance with the specific physical structure thus to get the quantum
program out_prog
matching with the specific physical structure.
● Finally, measure the probability of the program out_prog
to obtain
the result_2
.
● The mapping of quantum program, as an additional SWAP
operation to the
original circuit to adapt to the physical topology, does not affect the
structure of the circuit. Therefore, the mapping of the circuit is
correct if result_1
and result_2
are the same.
The results are as below:
0.49999999999999645
The results are different
0.0
0.0
0.0
0.0
0.0
0.0
The results are different
0.0
0.0
0.0
0.0
0.0
0.0
0.0