Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/itsubaki/qasm-playground/llms.txt

Use this file to discover all available pages before exploring further.

The playground runs OpenQASM 3.0, the third major version of the Open Quantum Assembly Language. This page documents the syntax constructs you can use, with examples drawn from the built-in example programs.

Version declaration

Every program must begin with a version declaration on the first non-comment line.
OPENQASM 3.0;

Qubit declarations

Declare a register of qubits with a size, or a single named qubit without brackets.
qubit[2] q;    // register of 2 qubits
qubit psi;     // single qubit named psi
You can use a const int as the register size:
const int n = 3;
qubit[n] c;

Reset

reset initializes one or more qubits to the |0⟩ state. Always reset qubits before use.
reset q;
reset psi;
reset a;

Built-in gate: U

U(theta, phi, lambda) is the universal single-qubit gate. All other gates are defined in terms of it.
U(pi/2.0, 0, pi) q;    // Hadamard
U(pi, 0, pi) q;        // Pauli-X
U(0, 0, pi/4) q;       // T gate (phase)

Gate definitions

Define reusable gates with the gate keyword. The body expresses the gate in terms of U or other already-defined gates.
gate h q { U(pi/2.0, 0, pi) q; }
gate x q { U(pi, 0, pi) q; }
gate cx c, t { ctrl @ U(pi, 0, pi) c, t; }
gate cz c, t { ctrl @ U(0, pi, 0) c, t; }
gate cr(theta) c, t { ctrl @ U(0, 0, theta) c, t; }
Parameterized gates accept angle arguments:
gate Rx(theta) q { U(theta, -pi/2, pi/2) q; }
gate W(theta) q  { Rx(-2*theta) q; }
gate S(phi) q    { U(0, 0, -2*phi) q; }

Controlled gates

Use ctrl @ to add a control qubit to any gate. Use ctrl(n) @ to add n control qubits.
gate cx c, t    { ctrl    @ U(pi, 0, pi) c, t; }
gate ccx c0, c1, t { ctrl(2) @ U(pi, 0, pi) c0, c1, t; }
gate cccz c0, c1, c2, t { ctrl(3) @ U(0, 0, pi) c0, c1, c2, t; }
The Shor’s algorithm example uses a Toffoli gate (ccx) and a 4-controlled X gate:
gate ccx c0, c1, t    { ctrl(2) @ U(pi, 0, pi) c0, c1, t; }
gate ccccx c0, c1, c2, c3, t { ctrl(4) @ U(pi, 0, pi) c0, c1, c2, c3, t; }

Gate applications

Apply a gate by naming it followed by its qubit arguments. Use bracket notation to address individual qubits in a register.
h q[0];
cx q[0], q[1];
cr(-pi/2) q[2], q[1];
U(pi/4, pi/4, pi/4) psi;
You can also apply a gate to an entire register in one statement:
h c;       // applies h to every qubit in register c
reset r;   // resets every qubit in register r

Measurement

measure collapses qubits and records outcomes. Measured qubits remain in the circuit; subsequent gates still apply.
measure q;       // measure entire register
measure psi;     // measure single qubit
measure a;
The quantum teleportation example measures two qubits mid-circuit, then the remaining qubit is acted on by classical corrections:
cx a, t;
cz psi, t;

measure psi;
measure a;

Subroutine definitions

Use def to define reusable subroutines. Parameters are typed with qubit or qubit[n].
def oracle(qubit q0, qubit q1) {
    balanced(q0, q1);
}

def balanced(qubit q0, qubit q1) {
    cx q0, q1;
}

def constant(qubit q0, qubit q1) {
    x q1;
}
Subroutines can also accept fixed-size qubit registers:
def inv_qft(qubit[3] q) {
    h q[2];
    cr(-pi/2) q[2], q[1];
    h q[1];
    cr(-pi/4) q[2], q[0];
    cr(-pi/2) q[1], q[0];
    h q[0];
}
Call subroutines by name:
oracle(q0, q1);
inv_qft(c);
modexp(q, a);

Constants

Declare compile-time integer or float constants with const.
const int n = 3;
const float theta = pi/6;
Constants can be used as register sizes and in expressions:
qubit[n] c;
cr(1*pi/4) c[0], a;

Variables and expressions

Declare runtime integer variables and use arithmetic expressions:
int N = 2**n;
int M = 2;
int R = int(pi/4 * sqrt(float(N)/float(M)));

For loops

Iterate over an integer range with for int:
for int i in [0:R-1] {
    G(r, s, a);
}
Nested loops are supported:
for int i in [0:n-1] {
    for int j in [0:(1<<i)-1] {
        controlledG(r, s, c[i], a);
    }
}

Comments

Single-line comments start with //. There are no block comments.
// Bell State
// The final state is (|00> + |11>)/sqrt(2).

Complete example: Bell state

The Bell state program demonstrates version declaration, gate definitions, qubit declarations, reset, gate application, and the structure of a minimal program.
// Bell State
//
// Prepares two qubits in the entangled state.
// The final state is (|00> + |11>)/sqrt(2).

OPENQASM 3.0;

gate h q { U(pi/2.0, 0, pi) q; }
gate cx c, t { ctrl @ U(pi, 0, pi) c, t; }

qubit[2] q;
reset q;

h q[0];
cx q[0], q[1];

Complete example: Grover’s algorithm

This example shows constants, integer variables, for loops, complex subroutines, and multi-register operations.
OPENQASM 3.0;

gate x q { U(pi, 0, pi) q; }
gate h q { U(pi/2.0, 0, pi) q; }
gate cx q0, q1 { ctrl @ U(pi, 0, pi) q0, q1; }
gate xor q0, q1, q2 { cx q0, q2; cx q1, q2; }
gate cccz c0, c1, c2, t { ctrl(3) @ U(0, 0, pi) c0, c1, c2, t; }
gate ccccx c0, c1, c2, c3, t { ctrl(4) @ U(pi, 0, pi) c0, c1, c2, c3, t; }

def oracle(qubit[4] r, qubit[4] s, qubit a) {
    xor r[0], r[1], s[0];
    xor r[2], r[3], s[1];
    xor r[0], r[2], s[2];
    xor r[1], r[3], s[3];
    ccccx s[0], s[1], s[2], s[3], a;
    xor r[1], r[3], s[3];
    xor r[0], r[2], s[2];
    xor r[2], r[3], s[1];
    xor r[0], r[1], s[0];
}

def diffuser(qubit[4] r) {
    h r;
    x r;
    cccz r[0], r[1], r[2], r[3];
    x r;
    h r;
}

def G(qubit[4] r, qubit[4] s, qubit a) {
    oracle(r, s, a);
    diffuser(r);
}

const int n = 4;
qubit[n] r;
qubit[4] s;
qubit a;

reset r;
reset s;
reset a;

h r;
x a;
h a;

int N = 2**n;
int M = 2;
int R = int(pi/4 * sqrt(float(N)/float(M)));

for int i in [0:R-1] {
    G(r, s, a);
}

measure s;
measure a;

Build docs developers (and LLMs) love