docs/verdicts.md gives the ladder, what a verdict records, the intents, the repair rules and every surface; the reader's diagnostics page points at the job layer's codes. The crate's, the command line's, the service's, the Python package's and the Studio's READMEs, and the changelog, describe them. Co-Authored-By: Claude Opus 5.5 <[email protected]>
134 lines
12 KiB
Markdown
134 lines
12 KiB
Markdown
# OpenQASM reader: diagnostic codes
|
|
|
|
Every refusal and warning the reader gives (`wai_quantum::qasm`), and every
|
|
construct it lowers, carries or keeps verbatim, has a code. A refusal or a
|
|
warning reads, on every surface:
|
|
|
|
```text
|
|
line 3: unknown gate foo [Q103]
|
|
```
|
|
|
|
and, as data (`wai-quantum lint --json`, the MCP servers' `lint_qasm`, the
|
|
job service, the Studio), carries its `code`, its `outcome`, its `message`
|
|
and where it stands: `line`, `column` and `length`, in characters.
|
|
|
|
**Stability.** A code never changes meaning once released. A construct that
|
|
comes to be supported gets a new code for what now happens to it; the old
|
|
code keeps its row, marked retired, so a code in an old log or receipt still
|
|
means what it meant then. New codes are only ever added.
|
|
|
|
**Outcomes.**
|
|
|
|
- `refused`: the program is not read, and nothing runs.
|
|
- `lowered`: read and lowered exactly to the engine's gates and steps.
|
|
- `carried`: kept in the program as written (its timing, its outputs),
|
|
changing nothing a method computes unless the method says it uses it.
|
|
- `preserved`: kept verbatim for export, never executed.
|
|
- `warned`: read, with something the person should know; the job's result
|
|
lists it under `diagnostics`.
|
|
|
|
What is asked of a program (the request, the method, an intent, a repair,
|
|
the host) has codes of its own, `J…`: [job-refusals.md](job-refusals.md).
|
|
The verdict ([verdicts.md](verdicts.md)) carries a refusal's codes, and the
|
|
repair (`wai-quantum repair`, `repair_qasm`) makes the fixes that are
|
|
mechanical on the lines a diagnostic flags.
|
|
|
|
The table is also served as data: `wai_quantum::qasm::diag::codes()` in Rust,
|
|
`wai-quantum diagnostics [--json]` on the command line, the `qasm_diagnostics`
|
|
tool of both MCP servers, and `engine_diagnostic_codes()` in the browser
|
|
engine. A test holds this page to the code's table.
|
|
|
|
| Code | Outcome | Meaning |
|
|
|---|---|---|
|
|
| `Q001` | refused | A character that is not part of the language. |
|
|
| `Q002` | refused | A number that does not read: a malformed literal, or one too large to hold. |
|
|
| `Q003` | refused | A string, a block comment, a bracket or a calibration block that is not closed. |
|
|
| `Q004` | refused | Something else was expected here: a `;`, a name, an expression or a statement (the message says which). |
|
|
| `Q005` | refused | A statement in a place the language does not allow it: `else` with no `if`, `case` outside `switch`, a declaration inside a gate. |
|
|
| `Q010` | warned | An `OPENQASM` version other than 2.x or 3.x: the program is read as OpenQASM 3. |
|
|
| `Q011` | warned | An `include` of a file other than the standard libraries (`stdgates.inc`, `qelib1.inc`): its definitions are not read, so a gate it defines is unknown. |
|
|
| `Q012` | lowered | `include "stdgates.inc"` or `"qelib1.inc"`: the standard gates, `U`, `gphase` and OpenQASM 2's names are built in. |
|
|
| `Q013` | warned | A `pragma` or annotation the reader does not act on: kept, not applied. |
|
|
| `Q100` | refused | The program declares no qubits. |
|
|
| `Q101` | refused | A name declared twice in one scope, or given to two kinds of thing (a register and an integer). |
|
|
| `Q102` | refused | A name that is not declared: a register, a variable, an alias or a subroutine. |
|
|
| `Q103` | refused | A gate that is neither in the standard library nor defined in the program. |
|
|
| `Q104` | refused | A gate or subroutine given the wrong number of parameters, qubits or arguments. |
|
|
| `Q105` | refused | A declaration only the top level may make (qubits, a gate, a subroutine, an `extern`) inside a block. |
|
|
| `Q106` | refused | A word of the language, or a built-in constant (`pi`, `tau`, `euler`), used as a name. |
|
|
| `Q107` | refused | An index or slice outside its register or array. |
|
|
| `Q108` | refused | Registers of different lengths in one statement that applies to whole registers. |
|
|
| `Q109` | refused | One qubit named twice in one gate. |
|
|
| `Q110` | refused | A value of the wrong type here: a float where an integer is needed, a complex gate parameter, a qubit where a value is needed. |
|
|
| `Q111` | refused | More qubits than the reader takes (65 536). |
|
|
| `Q112` | refused | An integer outside its type's range (a negative `uint`, a value too wide for `int[n]`), or integer arithmetic that overflows. |
|
|
| `Q113` | refused | Division, or a remainder, by zero. |
|
|
| `Q114` | refused | An `input` given no value, or a value given for an input the program does not declare. |
|
|
| `Q115` | refused | An `input` of a type the reader takes no value for: only `int` and `uint` inputs are given values. |
|
|
| `Q116` | refused | A value that depends on a measurement used where the reader needs it on reading: a gate parameter, an index, a size, a loop's range. |
|
|
| `Q117` | refused | A gate parameter that is not a finite number. |
|
|
| `Q118` | refused | Integers divided with a remainder where a real number is wanted: OpenQASM 3 truncates `1/2` to 0 and OpenQASM 2 reads it as 0.5, so write `1.0/2`. |
|
|
| `Q119` | refused | `^` between integers in a program that does not say `OPENQASM 3`: OpenQASM 3 reads it as exclusive or, OpenQASM 2 as a power; write `**` for a power. |
|
|
| `Q120` | warned | `^` between real numbers, read as a power as OpenQASM 2 reads it; OpenQASM 3 writes `**`. |
|
|
| `Q121` | warned | A value rounded to its declared width, as the language defines (`angle[n]` to n bits of a turn, `float[32]` and `float[16]` to single and half precision); the message gives the amount. |
|
|
| `Q122` | refused | A type width the reader does not hold: a float other than `float[16]`, `float[32]` and `float[64]`, an integer or an angle wider than 64 bits. |
|
|
| `Q123` | refused | A cast the language does not allow, or one whose value does not fit. |
|
|
| `Q124` | refused | Physical qubits (`$0`) in a program that also declares qubits. |
|
|
| `Q125` | refused | A call of an `extern` function, whose body is outside the program. |
|
|
| `Q126` | refused | A call of an `opaque` gate, or of a gate with only a calibration: its matrix is not known. |
|
|
| `Q127` | refused | An assignment to a constant, an input or a loop variable. |
|
|
| `Q128` | refused | A measurement where a value is needed that is not a bit (measurement gives bits, into a bit register). |
|
|
| `Q200` | lowered | A `gate` the program defines, inlined at each call with its parameters bound. |
|
|
| `Q201` | lowered | `ctrl @` and `negctrl @` on any gate, lowered exactly to standard gates (a negative control is a control between two `x`). |
|
|
| `Q202` | lowered | `inv @` on any gate, user gates included: each gate's exact inverse, in reverse order. |
|
|
| `Q203` | lowered | `pow(k) @` with an integer `k`: angles scaled, or the gate repeated; a negative `k` repeats the inverse. |
|
|
| `Q204` | lowered | `pow(r) @` with a fractional `r` where an exact gate exists: the principal power (`pow(1/2) @ x` is `sx`, `pow(r) @ rz(θ)` is `rz(rθ)` for \|θ\| < 2π). |
|
|
| `Q205` | refused | `pow(r) @` with a fractional `r` where no exact gate exists here: a user gate, `u`, `cu`, or a rotation by 2π or more. |
|
|
| `Q206` | lowered | `gphase(θ)`: a global phase, which no measurement sees, dropped; under controls it is a phase on the controls. |
|
|
| `Q207` | refused | A control modifier that adds no control: `ctrl(0) @`. |
|
|
| `Q208` | refused | Modifiers that add more controls than the reader lowers (16). |
|
|
| `Q209` | refused | Gate definitions or subroutine calls nested deeper than 32. |
|
|
| `Q210` | refused | A program that expands to more gates than the reader holds (2 000 000). |
|
|
| `Q211` | refused | A modifier on something that is not a gate. |
|
|
| `Q212` | refused | A statement a gate's body may not hold: a gate holds gate calls, `gphase`, `barrier`, loops and conditions known on reading. |
|
|
| `Q300` | lowered | An `if`, `while` or `switch` whose condition is known on reading: decided then. |
|
|
| `Q301` | lowered | A condition on measured bits (`c[0]`, `c == 3`, `c >= 2`, `&&`, `\|\|`, `!`), compiled to steps that branch on them. |
|
|
| `Q302` | refused | A condition that reads neither measured bits nor values known on reading. |
|
|
| `Q303` | refused | A bit register of more than one bit used as a condition: compare it with a number, as `c == 3`. |
|
|
| `Q304` | refused | A comparison with a number that does not fit in the bits compared. |
|
|
| `Q305` | refused | A negated operand compared with `==` or `!=` (`!c == 1`): write `c != 1`. |
|
|
| `Q306` | refused | Classical arithmetic on measured bits at run time, beyond a condition, or a comparison between two measured values: the program's steps branch on bits and hold no other run-time values. |
|
|
| `Q307` | refused | A condition that reads more than 64 bits. |
|
|
| `Q308` | lowered | `for` over a range, a set or an array: unrolled, once per value. |
|
|
| `Q309` | lowered | `while` whose condition is known on reading: unrolled until it fails. |
|
|
| `Q310` | refused | A `while` whose condition reads measured bits and that declares no bound: add `@wai.max_iterations N` before it. |
|
|
| `Q311` | warned | A `while` on measured bits run at most its declared bound (`@wai.max_iterations N`): a run that still meets its condition after N iterations stops looping there. |
|
|
| `Q312` | refused | A program that does not finish unrolling within the reader's bound (20 000 000 statements and loop iterations). |
|
|
| `Q313` | refused | A range with a zero step, or that does not read as `[start:end]` or `[start:step:end]`. |
|
|
| `Q314` | refused | `break` or `continue` outside a loop, or `return` outside a subroutine. |
|
|
| `Q315` | refused | A `return` with a value under a condition on measured bits. |
|
|
| `Q316` | lowered | `break`, `continue`, `return` and `end`: under a condition on measured bits, a jump forward in the steps. |
|
|
| `Q317` | lowered | `switch`: decided on reading, or a chain of conditions on measured bits. |
|
|
| `Q318` | lowered | A `def` subroutine, inlined at each call: classical arguments by value, qubits by reference, its `return` value given back. |
|
|
| `Q319` | refused | A bit given anything but a measurement at run time: bits are written by measurement (a declaration may give them 0). |
|
|
| `Q320` | refused | A measurement whose result goes nowhere: `measure q;` while bit registers are declared (write `c = measure q;`). |
|
|
| `Q321` | refused | Qubits measured into a different number of bits. |
|
|
| `Q322` | lowered | A bit declared inside a block or a subroutine: a bit of its own, which the steps read and the results do not show. |
|
|
| `Q400` | warned | The method applies no durations: the program's delays, boxes and stretches change nothing it computes, and the result says so. |
|
|
| `Q401` | carried | `delay[d]` on qubits, carried in the program's timing. |
|
|
| `Q402` | carried | `box` (with or without a duration), carried in the timing around the gates it holds. |
|
|
| `Q403` | carried | `stretch`: a duration a scheduler would solve, carried by name. |
|
|
| `Q404` | carried | `barrier`, carried in the timing; it changes no gate. |
|
|
| `Q405` | refused | `durationof(…)`: it needs gate durations, which the program does not give the reader. |
|
|
| `Q406` | refused | A duration that does not read: no unit, negative, or not known on reading. |
|
|
| `Q407` | carried | A gate's duration (`x[20ns] q;`), carried in the timing, not applied. |
|
|
| `Q450` | preserved | `defcal`: kept verbatim for export, never executed; the gate's matrix comes from its `gate` definition or the standard library. |
|
|
| `Q451` | preserved | `cal { … }`: kept verbatim for export, never executed. |
|
|
| `Q452` | preserved | `defcalgrammar`: kept verbatim for export. |
|
|
| `Q500` | refused | An angle that is not a dyadic multiple of 2π (2πm/2^k, k ≤ 32): the bit-exact method refuses it, never rounds it; the methods in double precision take it. |
|
|
| `Q501` | refused | More than 255 qubits for the bit-exact circuit. |
|
|
| `Q502` | refused | A program that measures a qubit and then acts on it, resets one after its first gate, or acts on measured bits: the bit-exact circuit takes programs whose measurements all come at the end. |
|
|
| `Q600` | carried | An `output` declaration, carried into the result: its bits (their places in each outcome) or its value. |
|
|
| `Q601` | refused | An `output` that is not a bit and whose value depends on a measurement at the end. |
|
|
|
|
See `qasm-feature-matrix.md` for each construct of OpenQASM 3.1 and its code.
|