QASM: A Quantum Programming Language

QASM originated as a language for formally defining a quantum circuit to render images for visualisation purposes. As quantum computation evolved, the language was adopted as a way to specify quantum circuits as input to a quantum computer.

A QASM program declares the classical bits and qubits, describes the operations (gates) on those qubits and the measurements needed to obtain the classical result by inspecting the qubits. Many variants of QASM have seen the light since its inception as a mark-up language for generating images. Quantum Inspire uses cQASM 1.0. Whenever this site mentions QASM, it is referring to cQASM 1.0 unless explicitly stated otherwise.

QASM is used to describe relatively simple circuits, which is fine for the current generation of quantum computers. In the future, a higher level of abstraction will be required to deal with the billions of qubits needed to make up a practical quantum computer.

Basic Example

Let's start with an example where we create a Bell state to get a feel for the language:

        
          version 1.0

# a basic cQASM example
qubits 2

.prepare
    prep_z q[0:1]

.entangle
    H q[0]
    CNOT q[0], q[1]

.measurement
    measure_all
        
      
prepare entangle measurement
q[0]
 
 
 
 
 
 
q[1]
 
 
 
 
 
 

The file starts with the specification of the cQASM version on line 1. This line is always present.

Line 3 is a comment. Comments start with a hash (#), and the hash and everything after it until the end of current line is ignored by the cQASM parser. Use comments to document your code, so that someone else can understand what you were trying to do (note: someone else could also be your future self).

Line 4 defines the size of the qubit register (and by extension, the size of the corresponding classical register). In this simple example, two qubits are defined. Each qubit in the register is identified by its index. The first qubit has index 0 and the second qubit has index 1. When displaying qubits or bits, the (qu)bit with index 0 is the right-most one.

Lines 6, 9 and 13 mark the beginning of a sub-circuit. A sub-circuit starts with a dot and the name of the sub-circuit and ends with the definition of another sub-circuit. The example defines three sub-circuits: prepare, entangle and measurement.

Sub-circuits are discussed in more detail down below. For now just think of sub-circuits as a way of structuring your code.

Line 7 contains the first quantum instruction, to prepare both qubits in their ground state. The Single-Gate Multiple-Qubits (SGMQ) syntax is used to address both qubits at once. Alternatively, we could have written line 7 as two lines, prep_z q[0] and prep_z q[1]. The detailed SGMQ syntax discusses additional ways of specifying multiple qubits in a single operation.

Line 10 and 11 describe the quantum gates that form the circuit. First, a Hadamard gate is applied to the qubit with index 0, followed by a CNOT where the qubit with index 0 is the control qubit and the qubit with index 1 is the target qubit.

Finally, at line 14 the state of all qubits is measured along the Z-axis to obtain the final result.

Note that the example uses a mix of lower-case and upper-case. This is by convention only, cQASM itself is case-insensitive. The statement H q[0] could have been written as h Q[0] without changing the meaning of the statement.

Qubit aliases

To make cQASM more readable, it is possible to assign a mnemonic name to a qubit or a classical bit. For this, the map instruction is used:

        
          version 1.0

qubits 2

map q[0], Control
map q[1], Target
map b[0], MeasuredControl

prep_z Control
prep_z Target
H Control
measure_z Control
c-X MeasuredControl, Target
measure_z Target
        
      

This example shows the map instruction, along with qubit state preparation instructions and measurement feedback.

Sub-circuits

A cQASM file defines a quantum circuit. By defining sub-circuits, lines of code can be grouped together to improve the readability of the code. A sub-circuit starts with a line that starts with a single period (.) followed by a label or name for that sub-circuit.

The name of a subcircuit can not be any of the reserved keywords, such as measure or the name of a gate (X, Y, CNOT, et cetera). Note that a sub-circuit ends with the definition of another sub-circuit OR at the end of the code.

Here is an example that defines three sub-circuits named prepare, entangle and measurement:

        
          version 1.0

qubits 2

.prepare
    prep_z q[0:1]
 
.entangle
    H q[0]
    CNOT q[0], q[1]

.measurement
    measure_all
        
      
prepare entangle measurement
q[0]
 
 
 
 
 
 
q[1]
 
 
 
 
 
 

Static loops

Repeating a sub-circuit is an essential part of certain algorithms, such as the Grover algorithm. cQASM enables a simple for-loop construction: by appending an integer KK between brackets right after a sub-circuit name, that sub-circuit is repeated KK times. In the example code below, the sub-circuit called .grover is repeated two times. Note: If you would include a measure statement at the end of this code, it would be included in the .grover sub-circuit and repeated twice! To avoid this, you should first add another sub-circuit label (e.g. .final_measurement) and then add a measurement statement in the next line.

        
          version 1.0
qubits 3
# Grover's algorithm for searching the decimal number 6 in a database of size 2^3

.init
H q[2]
H q[1]
H q[0]

.grover(2)
# oracle
{X q[0] | H q[2] }
Toffoli q[0], q[1], q[2]
{ H q[2] | X q[0] }

# diffusion
{H q[0] | H q[1] | H q[2]}
{X q[1] | X q[0] | X q[2] }
H q[2]
Toffoli q[0], q[1], q[2]
H q[2]
{X q[1] | X q[0] | X q[2] }
{H q[0] | H q[1] | H q[2]}

# Measurement not required on simulation backend
        
      
init grover(2)
q[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
q[1]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
q[2]