open-standards/wai/wai-quantum/docs/qasm-feature-matrix.md
Transaction Science 0460ae3a39 wai-quantum: the library's job codes in a decade of their own, J050 to J053
The table groups its codes in tens by theme, and J040 and J041 go to
another branch's codes. PARAMS is now J050, GRADIENT J051, OPTIMIZE J052
and BUILD J053, in the table and its page, every message and test, the
service's OpenAPI and tool descriptions, the job schema, the reference
page, the feature matrix, the changelog entry and the regenerated agent
docs. No released code changes: these four were never released.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-31 09:48:42 -04:00

12 KiB
Raw Permalink Blame History

OpenQASM 3.1: what the reader does with each construct

The reader (wai_quantum::qasm) is the one grammar every surface takes: the job service, the command line, both MCP servers, the Studio, the desktop app, the edge component and the in-browser IDE. This page lists every construct of OpenQASM 3.1, and the OpenQASM 2 forms in common use, with what the reader does with it and the diagnostic code it gives (qasm-diagnostics.md has the table of codes).

  • supported: read as the language defines it.
  • lowered: read and lowered exactly to the engine's gates and steps.
  • carried: kept in the program as written (timing, outputs); it changes nothing a method computes, and the result says so where it matters.
  • preserved: kept verbatim for export, never executed.
  • refused: the program is not read; the refusal names the line, says what to write instead, and ends with its code.

The conformance corpus (wai/quantum-conformance/qasm3/) holds the specification's example programs and a program for each construct below, each with what the reader must do with it; CI runs it natively, under wasm32-wasip2 and in the browser build.

Program structure

Construct Status Codes
OPENQASM 3.1;, OPENQASM 3;, OPENQASM 2.0;, or none supported; another version is read as OpenQASM 3 Q010
include "stdgates.inc", include "qelib1.inc" supported: the libraries are built in Q012
include of any other file warned: its definitions are not read Q011
Comments // and /* */ supported; an unclosed block comment is refused Q003
Identifiers, Unicode letters included (θ, π) supported
Statements and blocks { }, scopes supported; qubits, gates, subroutines and externs are declared at the top level Q105
pragma …, #pragma …, annotations @keyword … warned: kept, not applied; @wai.max_iterations N bounds the while after it Q013

Literals

Construct Status Codes
Integers: decimal, 0x, 0o, 0b, with _ supported Q002
Floats, exponents, .5 supported Q002
Imaginary 2.5im supported
true, false supported
Bit strings "0101" supported Q110
Durations ns, us, µs, ms, s, dt supported Q406
pi π, tau τ, euler ℯ supported; not redeclarable Q106

Declarations and types

Construct Status Codes
qubit q;, qubit[n] q;, qreg q[n]; supported (at most 65 536 qubits) Q101, Q105, Q111
Physical qubits $0, $1 supported, in a program that declares none Q124
bit c;, bit[n] c;, creg c[n]; supported: written by measurement; a value known on reading (bit[2] f = "11";) is held until a measurement writes the bit Q319
A bit declared inside a block or a subroutine lowered: a bit of its own, which the steps read and the results do not show Q322
int, int[n], uint, uint[n] (n ≤ 64) supported; range-checked Q112, Q122
float, float[16], float[32], float[64] supported, rounded to the width as defined; float[128] refused Q121, Q122
angle, angle[n] (n ≤ 64) supported: angle[n] holds n bits of a turn, so it is dyadic and the bit-exact method takes it Q121
complex, complex[float[n]] supported; a complex gate parameter is refused Q110
bool supported
duration supported: SI units and dt, not mixed Q406
stretch carried by name, or as the expression that holds it, for a scheduler Q403
array[T, d1, d2, …], nested values, sizeof supported Q107, Q110
const supported: known on reading; not assignable Q127
input int n;, input uint n; supported: given when the program is read (a generator) Q114
input float theta;, input angle phi; a parameter: a job's params binds it as a const at exactly the double given before the program is read (left without a value, the job is refused with Q114 and J050); the reader alone gives it no value Q115
a parameter followed into a gradient supported through arithmetic, the built-in functions, loops and gate definitions into gates' arguments; refused under a modifier, in a classical variable, a condition, an index, a size, a loop's range, a subroutine, or a type that rounds it Q129
output carried into the result: a bit register's places in each outcome, or a value Q600, Q601
let a = q[0:2] ++ r; supported; a let that reuses an enclosing scope's name is refused Q101
extern f(…) -> T; supported as a declaration; a call is refused Q125

Indexing

Construct Status Codes
q[i], negative q[-1] supported Q107
Slices q[a:b], q[a:s:b], q[a:], q[:] supported Q107, Q313
Index sets q[{0, 2, 5}] supported Q107
Multi-dimensional m[i, j], m[i][j], array slices and slice assignment supported Q107, Q110
An integer's bits k[i] supported

Expressions

Construct Status Codes
+ - * / % **, unary - supported; integer overflow refused Q112, Q113
Integer division with a remainder used as a real (1/2 in a gate) refused: OpenQASM 3 truncates it, OpenQASM 2 does not Q118
`& ~ << >>` supported on integers and bits
^ exclusive or in an OpenQASM 3 program; a power in OpenQASM 2; between integers with no version stated it is refused, between reals read as a power with a warning Q119, Q120
== != < <= > >=, `&& !`
Casts int[8](x), float(x), angle[n](b), bit[n](i), bool(x) supported (a cast to int truncates; bits to a signed integer of their width read as two's complement) Q123
sin cos tan arcsin arccos arctan exp log ln sqrt ceiling floor mod pow popcount rotl rotr real imag sizeof supported, computed with the crate's own functions, the same bits on every platform Q104
durationof({ … }) refused: it needs gate durations the program does not give Q405
Arithmetic on measured bits at run time (int k = c;) refused: the steps branch on bits and hold no other run-time value Q306
A value that depends on a measurement where one is needed on reading refused Q116

Gates

Construct Status Codes
U(θ, φ, λ), gphase(θ) supported; a global phase is dropped, and under controls is a phase on the controls Q206
The standard library: p x y z h s sdg t tdg sx rx ry rz cx cy cz cp crx cry crz ch swap ccx cswap cu CX phase cphase id u1 u2 u3, and sxdg iswap rxx ryy rzz ccz cnot toffoli fredkin u cu1 cu3 supported, each checked against its definition in U and CX (cu(θ, φ, λ, γ) is controlled e^{iγ}U(θ, φ, λ)) Q012
gate name(params) qubits { … } lowered: inlined at each call; a redefinition of a standard gate keeps the standard one Q200, Q212
opaque gates refused at a call: no matrix Q126
A call on whole registers (broadcast) supported Q108
A gate's duration x[20ns] q; carried in the timing Q407
Wrong parameters or qubits, a qubit named twice, an unknown gate refused Q103, Q104, Q109

Modifiers

Construct Status Codes
ctrl @, ctrl(n) @, negctrl @, negctrl(n) @ on any gate, user gates included lowered exactly (a negative control is a control between two x); at most 16 added controls Q201, Q207, Q208
inv @ on any gate lowered exactly: each gate's inverse, in reverse order Q202
pow(k) @, k a whole number lowered exactly: angles scaled or the gate repeated; negative k repeats the inverse Q203
pow(r) @, r fractional lowered where an exact principal root exists (pow(1/2) @ x is sx; rotations by less than 2π; phases; controlled forms); refused otherwise (u, cu, user gates) Q204, Q205
A modifier on a subroutine, or nested as deep as 32 refused Q211, Q209

Measurement and reset

Construct Status Codes
c = measure q;, c[0] = measure q[0];, bit c = measure q; supported Q321
measure q -> c; supported Q321
measure q; supported where no bit register is declared Q320
Mid-circuit measurement, measurement again, a gate after it lowered: the program runs as steps (counts by shot splitting, exact expectation values)
reset q; supported: before a qubit's first gate it changes nothing; after it, the program runs as steps
barrier, barrier q; carried in the timing Q404

Classical control

Construct Status Codes
if/else known on reading decided on reading Q300
if/else on measured bits: c[0], c == 3, c >= 2, int[2](c) != 0, with &&, ` , !`
for over a range, a set or an array lowered: unrolled Q308, Q313, Q312
while known on reading lowered: unrolled until it fails (at most 1 000 000 times) Q309, Q312
while on measured bits lowered under @wai.max_iterations N, with a warning that runs still meeting the condition stop there; refused with no bound Q310, Q311
switch / case / default decided on reading, or a chain of conditions on measured bits Q317
break, continue supported; under a condition on measured bits, jumps forward Q316, Q314
end supported Q316

Subroutines

Construct Status Codes
def f(T x, qubit q, qubit[n] r) -> T { … } lowered: inlined, classical arguments by value, qubits by reference Q318, Q104
return v;, return measure q; supported; a returned measurement writes the caller's bit Q315
readonly / mutable array arguments, #dim supported
Bits declared in a subroutine lowered: bits of its own, fed forward Q322
A subroutine called as a gate (f(1) q, r;) supported
Recursion refused past 32 calls deep Q209

Timing

Construct Status Codes
delay[d] q; carried Q401
box, box [d] carried, around the gates it holds Q402
stretch carried Q403
Durations in a result no method applies them; a result of a program that states durations says so (timing.applied: false) Q400

Calibration (OpenPulse)

Construct Status Codes
defcalgrammar "openpulse"; preserved; in a pulse run, read (another grammar is refused) Q452, Q454
cal { … } preserved, never run by the circuit methods; in a pulse run, read as OpenPulse and run in order Q451, Q453
defcal … preserved, never run by the circuit methods; the gate's matrix comes from its definition or the library. In a pulse run, read as OpenPulse and run at each call on its physical qubits Q450, Q126, Q453, Q459
Ports, frames, waveforms (constant, gaussian, sech, gaussian_square, drag, sine, explicit samples) in a pulse run, lowered to the schedule Q453, Q455 to Q458
play, delay, shift_phase, set_phase, shift_frequency, set_frequency, capture_v0 to capture_v4, barrier in a pulse run, lowered to the schedule on frames Q453, Q457, Q458, Q461
Plays on a measurement port in a pulse run, scheduled and timed; the readout is not simulated Q462

A pulse run is the job method pulse; the pulse page gives the model, the bound and the options.

The bit-exact method

The bit-exact state vector takes the reader's program under its own restriction, refusing with a code: dyadic angles only (Q500), at most 255 qubits (Q501), and measurements all at the end (Q502). A controlled gate the modifiers write is held whole, under all its controls. The methods in double precision take any angle.