Prev Tutorial: OriginIR
Next Tutorial: Quantum Visualization
Overview
OpenQASM (Open Quantum Assembly Language) is an imperative programming language with characteristics similar to a Hardware Description Language (HDL). It was launched by IBM in July 2017 as part of its quantum computing platform. OpenQASM can describe general quantum computations using circuit models, measurement-based models, and recent quantum computing experiments.
It is currently one of the most widely used quantum assembly languages and has been updated to version 3.0. However, QPanda3 currently only supports OpenQASM 2.0 syntax rules.
- Note
- Currently, the new release of QPanda3 has the following updates compared to the older version of QPanda2 regarding the OpenQASM module:
- First, QPanda3's OpenQASM interface for translating QProg supports program comment parsing.
- Second, the OpenQASM part of QPanda3 only supports operations such as applying quantum bit and register, quantum logic gate, Custom Gate, and measurement, but not operations such as quantum conditional judgment (QIF), quantum cyclic control (QWHILE), classical expressions, and RESET.
- Finally, when executing large quantum program translations, compared to QPanda2's translation interface, QPanda3's translation interface is executed about 4.0 times more efficiently (located in Ubuntu 22.04 environment).
def convert_qasm_to_qprog(file_path: str, machine: QuantumMachine) -> list
def convert_qasm_string_to_qprog(qasm_str: str, machine: QuantumMachine) -> list
def convert_qasm_file_to_qprog(file_path: str) -> QProg
def convert_qasm_string_to_qprog(qasm_str: str) -> QProg
OpenQASM Program Example
Similar to the syntax rules in the OriginIR introduction, here is an example of OpenQASM:
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];
OpenQASM is a quantum programming language based on the style of C and assembly languages, designed for writing quantum algorithms. It provides a basic syntax for quantum computing, supporting the declaration of quantum and classical registers, invocation of common quantum gates (such as CNOT and single-qubit transformation gates), and execution of measurement operations, among others. Users can define quantum algorithms and perform quantum computing programming using these fundamental constructs.
Version String
The first non-comment line of an OpenQASM program should specify OPENQASM M.m
, where M
represents the major version and m
represents the minor version. An example is as follows:
- Note
- The version string should not appear multiple times (outside of comments), nor should it appear anywhere other than the first non-comment line.
Included file
In OpenQASM programs, when using built-in quantum gates and quantum instructions, it is necessary to import standard library files beforehand. In this case, the standard library qelib1.inc
for OpenQASM 2 is used. An example is as follows:
The statement include "filename";
will parse the file name as if the content of the file is inserted at the location of the include
statement. This statement can only be used in the global scope.
Quantum Bit
OpenQASM typically uses qubit
or qreg
to allocate quantum bits and registers. The statement qubit name
declares a reference to a quantum bit, and the statement qubit[size] name
or qreg name[size]
declares a quantum register of size size
. The size parameter size
must always be a non-negative integer that is constant at compile time, and the quantum register cannot be resized after declaration. An example is as follows:
qubit q0;
qubit[5] q1;
qreg q2[5];
The above statements declare one quantum bit and two quantum registers, each of size 5.
- Note
- Quantum-type variables must be declared and initialized one variable at a time. No type allows comma-separated declarations/initializations. An example is as follows:
qubit q0;
qubit q1;
qubit q2;
Classical Scalar Type
OpenQASM supports classical scalar types as well as type-related operations, where types include classical bit type, integer, float-point number, boolean, classical angle, and so on. The following is a brief introduction to types.
- Note
- Classical-type variables must be declared and initialized one variable at a time. No type allows comma-separated declarations/initializations. An example is as follows:
Classical Bit and Register
Classical bit type has values of 0 or 1. Classical register is an static array of bit. Classical register simulates the state of certain controllers in an OpenQASM program.
OpenQASM typically uses bit
or creg
to allocate classical bits and registers. The statement bit name
declares a classical bit, and the statement bit[size] name
or creg name[size]
declares a classical register of size size
. The size parameter size
must always be a non-negative integer that is constant at compile time, and the classical register cannot be resized after declaration. An example is as follows:
bit c0;
bit[5] c1;
creg c2[5];
The above statements declare one classical bit and two classical registers, each of size 5.
Other Classical Type
OpenQASM also supports n-bit signed integers int
and unsigned integers uint
, floating-point numbers float
, the type angle
for representing classical angles, Boolean type bool
, compile-time constants const
, and others. An example is as follows:
uint[32] integer0 = 10;
int[16] integer1;
integer1 = int[16](integer0);
int integer2;
float[32] floatnum0 = π;
float floatnum1 = 2.3;
angle[2] anglnum0 = π/2;
angle anglnum1;
bit bit0 = 0;
bool boolean0;
boolean0 = bit0;
const uint SIZE = 32;
qubit[SIZE] q;
int[SIZE] integer3;
Quantum Logic Gate
The standard library files in OpenQASM categorize the built-in gates as follows:
- Single-qubit gates: Their keywords include
p
, x
, y
, z
, h
, s
, sdg
, t
, tdg
, sx
, rx
, ry
, rz
, phase
, id
, u1
, u2
, u3
, and their usage format is gate(params) qbit
. An example is as follows: qubit[4] q;
h q;
sdg q[0];
rx(3.14 / 2) q[2];
h q[1];
t q[3];
- Two-qubit gates: Their keywords include
cx
, cy
, cz
, cp
, crx
, cry
, crz
, ch
, cu
, swap
, cphase
, and their usage format is gate(params) qbit1, qbit2
. An example is as follows: qubit[4] q;
h q;
U3(0, 0, 3.14 / 2) q[0];
CX q[0], q[1];
U3(0, 0, -3.14 / 2) q[1];
CX q[2], q[3];
U3(0, 0, 3.14 / 2) q[2];
- Three-qubit gates: Their keywords include
cxx
and cswap
, and their usage format is gate(params) qbit1, qbit2, qbit3
. An example is as follows: qubit[4] q;
x q[0];
y q[1];
z q[2];
cswap q[0], q[1], q[2];
- Note
- It is important to note that for all single-qubit gate operations, the target quantum bit can be either the entire quantum bit array or a single quantum bit. When it is the entire quantum bit array, for example: When the quantum bit array size is 3, it is equivalent to:
Measurement Operation
OpenQASM typically uses the keyword measure
to perform a measurement operation on the specified target quantum bit and assign the measurement result to the target classical bit or classical bit array. The usage format is measure qbit -> cbit
, where the target quantum bit qbit
can be either the entire quantum bit array or a single quantum bit, and the target classical bit cbit
can be either the entire classical bit array or a single classical bit. An example is as follows:
- Note
- If the number of allocated quantum bits and classical registers is the same, you can use
q
to represent all quantum bits and c
to represent all classical bits. An example is as follows: If both the number of quantum bits and classical bits is 3, it is equivalent to: measure q[0] -> c[0];
measure q[1] -> c[1];
measure q[2] -> c[2];
Custom Gate Operation
OpenQASM supports custom layered quantum gate operation with the keyword gate
. The usage format is gate name(params) qbits { ... }
. An example is as follows:
qubit[4] q;
gate my_gate01(param) qarg1, qarg2 {
U3(0, 0, param / 2) qarg1;
CX qarg2, qarg1;
U3(0, 0, - param / 2) qarg2;
CX qarg1, qarg2;
U3(0, 0, param / 2) qarg1;
}
gate my_gate02 qarg1, qarg2 {
h qarg2;
sdg qarg2;
CX qarg1, qarg2;
h qarg2;
t qarg2;
CX qarg1, qarg2;
t qarg2;
h qarg2;
}
my_gate01(3.14 / 2) q[2], q[3];
my_gate02 q[0], q[1];
OpenQASM Conversion Tool
QPanda provides a set of OpenQASM conversion tools, primarily used for the one-way translation of quantum programs from QProg to OpenQASM. OpenQASM is a quantum assembly language used to represent quantum program information. QProg is a container class for quantum programming and represents the highest unit of a quantum program. The following will provide a detailed introduction to the interface definitions and usage of these conversion tools.
- Translate the OpenQASM instruction set string into a QProg object.
- Translate the OpenQASM instruction set file into a QProg object.
OpenQASM String Translation to QProg
The compilation module of QPanda defines convert_qasm_string_to_qprog for translating the OpenQASM instruction set string into a QProg object.
The following is a simple example of an interface call that demonstrates the process of converting an OpenQASM instruction set string into a quantum program QProg:
Python
if __name__ == "__main__":
qasm_str = """
// quantum teleportation example
OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[3];
// optional post-rotation for state tomography
gate post q {
h q;
}
u3(0.3,0.2,0.1) q[0];
h q[1];
cx q[1],q[2];
barrier q;
cx q[0],q[1];
h q[0];
measure q[0] -> c[0];
measure q[1] -> c[1];
if(c==1) z q[2];
if(c==2) x q[2];
if(c==3) y q[2];
post q[2];
measure q[2] -> c[2];
"""
prog = convert_qasm_string_to_qprog(qasm_str)
machine = CPUQVM()
machine.run(prog=prog, shots=1)
res_lis = machine.result().get_state_vector()
print("Result(stv) of running qprog:\n")
for val in res_lis:
print("(", val.real, ",", val.imag, ")")
print(draw_qprog(prog, PIC_TYPE.TEXT, {}, param_show=True))
The output is as follows:
Result(stv) of running qprog:
( 0.010496566630281416 , -0.4013645559739494 )
( -0.010496566630281416 , -0.2978021782757585 )
( 0.010496566630281416 , -0.4013645559739494 )
( -0.010496566630281416 , -0.2978021782757585 )
( -0.010496566630281416 , -0.2978021782757585 )
( 0.010496566630281416 , -0.4013645559739494 )
( 0.010496566630281416 , 0.2978021782757585 )
( -0.010496566630281416 , 0.4013645559739494 )
┌─────────────────┐ ┌─┐ ┌─┐
q_0: |0>─┤U3(0.3, 0.2, 0.1)├ ────── ───*── ┤H├─── ─┤M├── ─── ────
├─┬───────────────┘ ┌──┴─┐ └┬┴┐ └╥┘
q_1: |0>─┤H├──────────────── ───*── ┤CNOT├ ─┤M├── ──╫─── ─── ────
└─┘ ┌──┴─┐ ├─┬──┘ └╥┼─┐ ║┌─┐ ┌─┐ ┌─┐
q_2: |0>──────────────────── ┤CNOT├ ┤Z├─── ──╫┤X├ ──╫┤Y├ ┤H├ ─┤M├
└────┘ └─┘ ║└─┘ ║└─┘ └─┘ └╥┘
c : / ═════════════════════════════════════╩══════╩══════════╩═
1 0 2
- Note
- For unsupported operation types, errors may occur during the conversion of OpenQASM to a quantum program.
OpenQASM File Translation to QProg
The compilation module of QPanda defines convert_qasm_file_to_qprog for translating the OpenQASM instruction set file into a QProg object.
The following is a simple example of an interface call that demonstrates the process of converting an OpenQASM instruction set file into a quantum program QProg:
Python
"""sample_QASM.qasm
// quantum teleportation example
OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[3];
// optional post-rotation for state tomography
gate post q {
h q;
}
u3(0.3,0.2,0.1) q[0];
h q[1];
cx q[1],q[2];
barrier q;
cx q[0],q[1];
h q[0];
measure q[0] -> c[0];
measure q[1] -> c[1];
if(c==1) z q[2];
if(c==2) x q[2];
if(c==3) y q[2];
post q[2];
measure q[2] -> c[2];
"""
if __name__ == "__main__":
qasm_file_path = "Test/Compiler/QASM/ToQProg/sample_QASM.qasm"
prog = convert_qasm_file_to_qprog(qasm_file_path)
machine = CPUQVM()
machine.run(prog=prog, shots=1)
res_lis = machine.result().get_state_vector()
print("Result(stv) of running qprog:\n")
for val in res_lis:
print("(", val.real, ",", val.imag, ")")
print(draw_qprog(prog, PIC_TYPE.TEXT, {}, param_show=True))
The output is as follows:
Result(stv) of running qprog:
( 0.010496566630281416 , -0.4013645559739494 )
( -0.010496566630281416 , -0.2978021782757585 )
( 0.010496566630281416 , -0.4013645559739494 )
( -0.010496566630281416 , -0.2978021782757585 )
( -0.010496566630281416 , -0.2978021782757585 )
( 0.010496566630281416 , -0.4013645559739494 )
( 0.010496566630281416 , 0.2978021782757585 )
( -0.010496566630281416 , 0.4013645559739494 )
┌─────────────────┐ ┌─┐ ┌─┐
q_0: |0>─┤U3(0.3, 0.2, 0.1)├ ────── ───*── ┤H├─── ─┤M├── ─── ────
├─┬───────────────┘ ┌──┴─┐ └┬┴┐ └╥┘
q_1: |0>─┤H├──────────────── ───*── ┤CNOT├ ─┤M├── ──╫─── ─── ────
└─┘ ┌──┴─┐ ├─┬──┘ └╥┼─┐ ║┌─┐ ┌─┐ ┌─┐
q_2: |0>──────────────────── ┤CNOT├ ┤Z├─── ──╫┤X├ ──╫┤Y├ ┤H├ ─┤M├
└────┘ └─┘ ║└─┘ ║└─┘ └─┘ └╥┘
c : / ═════════════════════════════════════╩══════╩══════════╩═
1 0 2
- Note
- For unsupported operation types, errors may occur during the conversion of OpenQASM to a quantum program.