open-standards/wai/extensions/quantum-landscape.md
Transaction Science 000379329d
Some checks are pending
wai-audit collector and player integration / does this change touch it (push) Successful in 17s
WAI operation catalogue / does this change touch it (push) Successful in 18s
wai-quantum contract / does this change touch it (push) Successful in 22s
wai-quantum clippy / does this change touch it (push) Successful in 17s
wai-quantum pulse and dynamics / does this change touch it (push) Successful in 36s
wai-quantum error correction and mitigation / does this change touch it (push) Successful in 25s
wai-quantum for Python / does this change touch it (push) Successful in 28s
wai-quantum extension points / does this change touch it (push) Successful in 22s
wai-quantum variational and algorithm library / does this change touch it (push) Successful in 17s
wai-quantum service / does this change touch it (push) Successful in 14s
wai-quantum studio and desktop / does this change touch it (push) Successful in 14s
wai-quantum studio and desktop / desktop app · windows (push) Waiting to run
wai-sink-android native sink library / does this change touch it (push) Successful in 1m11s
wai-sink-swift native sink package / does this change touch it (push) Successful in 1m9s
wai-quantum views in agent hosts / does this change touch it (push) Successful in 1m14s
wai-quantum verdicts and repairs / does this change touch it (push) Successful in 1m24s
WAI Studio / does this change touch it (push) Successful in 23s
wai-quantum docs, course and locales / does this change touch it (push) Successful in 3m57s
wai-quantum-landscape-fpga reference design / does this change touch it (push) Successful in 3m43s
wai-quantum OpenQASM reader / does this change touch it (push) Successful in 3m43s
wai-quantum editors / does this change touch it (push) Successful in 4m0s
wai-quantum resource estimation / does this change touch it (push) Successful in 3m50s
wai-quantum other formats / does this change touch it (push) Successful in 3m49s
wai-quantum command line / does this change touch it (push) Successful in 4m9s
wai-quantum for JavaScript / does this change touch it (push) Successful in 3m48s
wai-quantum service / service energy · linux packages (push) Successful in 3m18s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 21s
WAI examples / WAI examples · does this change touch them (push) Successful in 20s
wai-quantum landscape energy to solution / does this change touch it (push) Successful in 16s
wai-quantum energy-landscape jobs / does this change touch it (push) Successful in 21s
wai-quantum landscape stage 0, the sampler against the exact law / does this change touch it (push) Successful in 22s
wai-quantum contract / the policy is linked, and the deprecations page reads (push) Successful in 12s
wai-quantum wasmQ / does this change touch it (push) Successful in 10s
wai-quantum pulse and dynamics / the same bits · linux-arm64 (push) Successful in 3m13s
wai-quantum-landscape-fpga reference design / the board's code on the board's processor's architecture · linux-arm64, release (push) Successful in 2m5s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux-arm64, release (push) Successful in 3m23s
wai-audit collector and player integration / collector · linux (push) Successful in 3m42s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs · linux, release (push) Successful in 3m4s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Successful in 7m14s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs under wasm32-wasip2 (wasmtime) (push) Successful in 2m12s
wai-quantum extension points / the registry and the example · linux-arm64 (push) Successful in 6m37s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 5m40s
wai-quantum clippy / clippy, warnings denied, every feature set · linux (push) Successful in 6m27s
wai-quantum extension points / the registry under wasm32-wasip2 (wasmtime) (push) Successful in 3m19s
wai-quantum contract / API compatibility · linux (push) Successful in 8m39s
wai-quantum error correction and mitigation / codes, decoders, texts and mitigation · linux, release (push) Successful in 5m38s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux, release (push) Successful in 5m37s
wai-quantum verdicts and repairs / the intent set and the verdict under wasm32-wasip2 (wasmtime) (push) Successful in 1m24s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 1m6s
wai-quantum contract / schemas and the committed tool lists · linux (push) Successful in 11m16s
wai-quantum extension points / the registry and the example · linux (push) Successful in 7m39s
wai-quantum docs, course and locales / the Studio's words in every locale · linux (push) Successful in 13s
WAI examples / WAI examples · android-app · linux-arm64 (push) Successful in 9m53s
wai-quantum views in agent hosts / views · a scripted host (push) Successful in 5m13s
wai-quantum verdicts and repairs / verdicts, repairs and the intent set · linux (push) Successful in 4m44s
wai-quantum docs, course and locales / the course and the command line's languages · linux (push) Successful in 3m34s
WAI operation catalogue / the catalogue and every door · linux (push) Successful in 14m21s
wai-quantum OpenQASM reader / reader and corpus · linux (push) Successful in 2m57s
wai-quantum views in agent hosts / views · the page and its engine (push) Successful in 7m15s
wai-quantum OpenQASM reader / corpus under wasm32-wasip2 (wasmtime) (push) Successful in 1m35s
wai-quantum studio and desktop / studio · browser (push) Successful in 9m40s
wai-quantum service / service · linux (push) Successful in 10m12s
wai-quantum energy-landscape jobs / the same bits · linux-arm64 (push) Successful in 13m45s
wai-quantum for Python / python · linux (push) Successful in 13m45s
wai-quantum other formats / the set under wasm32-wasip2 (wasmtime) (push) Successful in 3m34s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 3m59s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 12m41s
wai-quantum editors / editors · linux (push) Successful in 6m15s
wai-quantum other formats / readers, writers and the set · linux (push) Successful in 6m3s
wai-quantum pulse and dynamics / the same bits · macos (push) Successful in 1m18s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 2m25s
wai-quantum landscape energy to solution / the small tier, to the byte · linux (push) Successful in 2m52s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 6m56s
wai-quantum landscape stage 0, the sampler against the exact law / the small tier, to the byte · linux (push) Successful in 1m3s
wai-quantum resource estimation / estimation and calibration · linux, release (push) Successful in 8m37s
wai-quantum wasmQ / the reference modules rebuild to their modules of record · linux (push) Successful in 45s
wai-quantum for JavaScript / javascript · linux (push) Successful in 9m31s
wai-quantum for Python / python · macos (push) Successful in 3m21s
wai-quantum wasmQ / interpreter and vectors under wasm32-wasip2 (wasmtime) (push) Successful in 3m18s
wai-quantum editors / editors · macos (push) Successful in 1m48s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · linux (push) Successful in 5m34s
wai-quantum energy-landscape jobs / native against WebAssembly, over many seeds (push) Successful in 6m51s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 5m53s
wai-quantum service / service · macos (push) Successful in 7m45s
wai-quantum command line / command line · macos (push) Successful in 2m45s
wai-quantum landscape energy to solution / the small tier, to the byte · macos (push) Successful in 1m46s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 7m56s
wai-quantum landscape stage 0, the sampler against the exact law / the small tier, to the byte · macos (push) Successful in 25s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 9m9s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · macos (push) Successful in 2m35s
wai-quantum docs, course and locales / every command and snippet in the docs · linux (push) Successful in 25m27s
WAI Studio / Studio in WebKit · linux (push) Successful in 28m15s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Successful in 13m50s
wai-quantum energy-landscape jobs / the same bits · macos (push) Successful in 7m29s
wai-quantum energy-landscape jobs / the module under wasm32-wasip2 (wasmtime) (push) Successful in 18m45s
wai-quantum command line / command line · linux (push) Successful in 27m39s
wai-quantum energy-landscape jobs / reader, kernels, answers and the stated result · linux, release (push) Successful in 24m11s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (push) Successful in 15m21s
WAI examples / WAI examples · portable · linux (push) Successful in 28m38s
wai-quantum-landscape-fpga reference design / the member against the model of the logic, and the logic against the model · linux, release (push) Successful in 37m27s
wai-quantum: Stage 0 of the landscape emulator, run as registered: its data, its document and its CI job
The test registered in 382d96830, run at the registered seeds: the open energy-landscape emulator's sampling
kernel (a classical sampler emulating the cells of a planned processor) against the exact Boltzmann law over
every one of 3^10 to 3^12 states, 24 cells of eight landscapes at three temperatures, 1,048,576 samples a cell,
one sample a chain.

- The CPU reference passes all 24 cells, and so does the ideal sampler drawing from the exact law. Pearson's
  p-values for the reference run from 0.03 to 0.97, the divergence's from 0.07 to 0.96.
- Each negative control fails all 24 cells, by a wide margin in every one, as registered: every cell drawn at
  once from the old state by 65 to 39,958 times the excess the threshold allows (least on the dense
  ferromagnet), a field plus noise thresholded by 295 to 3,920, a three-colour cell by 455 to 45,195. The
  registered predictions of the last two, from their exact laws, are within a few percent of what came out.
- GPU members, on every first-version cell: through Metal and through WebGPU on the build host, and through
  WebGPU on Vulkan on a Linux server's integrated GPU, every one of 1,048,576 chains in each of 18 cells is the
  reference's; the coloured WebGPU kernel on both hosts, whose chains are its own on sparse couplings, passes all
  18. Not run here, so not certified by this: the CUDA member and the Vulkan members on its host, whose sign-in
  asks for a person, and the WebGPU member on the software Vulkan driver, left out of the Linux server's run. The
  nightly GPU workflow now runs the small tier through every member on its host. The FPGA member is not run and its board was not touched: it stays certified only by its
  hardware run of 2026-11-06.
- Mixing: each sample is its own chain's state after K sweeps (16 to 512), chosen before any sampling so that the
  exact law is within N chi2 <= 1 of the target; one long chain a cell gives the integrated autocorrelation times
  of the energy, the magnetisation, its size and the cells not at 0, and K against the longest. The dense
  ferromagnet at its coldest has a magnetisation time of 479 sweeps against K = 16: one chain rarely crosses
  between its ordered states, and the exact law shows the independent chains hold them in balance.

- quantum-conformance/landscape/stage0/: full/results.json, full/devices-build-host.json,
  full/devices-linux-server.json, small/results.json and small/report.md, README.md, reproduce.sh (both
  registrations, the small tier to its digest and both documents; --full, the full tier). Rebuilt to the byte on
  arm64 macOS and x86_64 Linux.
- wai-quantum/docs/landscape-stage0.md: the document, rendered from the data; listed in the docs check and the
  docs index.
- tests/landscape_stage0.rs: the small tier to the byte, the rule as registered on both tiers, the GPU members'
  chains, the documents as their data rendered.
- .github/workflows/wai-quantum-landscape-stage0.yml: the tests (13, pinned) and reproduce.sh on linux and macos.
  wai-quantum-landscape-devices.yml: a nightly step holding every member on its host to the small tier.
- landscape_stage0 devices --only PREFIX: run a subset of the members a host finds.
- extensions/quantum-landscape.md section 7.4 and quantum-landscape-2.md section 6: informative pointers.
- PREREGISTRATION.md, Changes after registration: none to the test; one note on a threshold's last binary place.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-11 14:10:29 -05:00

1127 lines
77 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WAI Extension: Energy-Landscape Jobs (`wai.quantum.landscape/1`)
Status: **Draft.** Reference: the `quantum_landscape` feature of `wai-quantum`
(`wai_quantum::quantum_landscape`), the command `wai-quantum landscape`, and
`QuantumEngine.landscape` in the browser build. Answer schema:
`wai-quantum/schemas/landscape.v1.json`. Conformance set:
`quantum-conformance/landscape/vectors.json`. Results:
`quantum-conformance/landscape/`. Verifying a sealed answer: §5.4, in
`wai_quantum::engine::landscape`. A job on a person's own device or service: the
provider protocol's §11 ([quantum-providers](quantum-providers.md#11-energy-landscape-jobs)).
The second version, `wai.quantum.landscape/2` ([quantum-landscape-2](quantum-landscape-2.md)), adds
a cost for each variable, so that one-hot, at-most-one and cardinality constraints can be
written, and prices joules only at a rate with evidence in this repository; this version is
unchanged by it.
Keywords **MUST**, **MUST NOT**, **SHOULD** and **MAY** are RFC 2119/8174.
## 0. What this extension adds
A job of this kind gives no circuit. It states an energy over variables of
three states and asks for a state of low energy. A machine that takes such a
job settles: each cell adds up the pull of the cells it is coupled to and moves
to the state that pull favours, with or without randomness, until the whole
comes to rest.
This text is the job, the answer and the seam between them and the device that
runs them. The same job can be run by the reference in software, by a GPU or by
an FPGA board, and its answer names what ran it, says how far that device is
held to the reference, and states its joules so that a priced figure can never
be read as a measured one.
The reference is a classical emulation. Its cells are three-state values
sampled with classical random draws. Nothing here is a quantum effect, and no
run of the reference involves any device but the machine it runs on.
## 1. The energy
```text
E(s) = − Σ_{i<j} W_ij s_i s_j − Σ_i b_i s_i + c · Σ_i |s_i|, s_i ∈ {−1, 0, +1}
```
The couplings `W_ij` are −1, 0 or +1 and symmetric, with none on the diagonal.
The fields `b_i` are whole numbers and the cost `c ≥ 0` is a whole number, each
at most 2⁴⁰ in size on the landscape a program finally gives, after pins (§2.1)
and quantisation (§2.2). The state 0 is "left out", with its own price, and is not a
third colour: this is the spin-1 model with a single-ion term.
A state is written as text, one character a variable, in order: `+`, `-` or `0`.
Every energy on this landscape is a whole number and exact. An energy on declared
weights (§2.2) is a double.
## 2. The job
A job is one JSON request and one operation. The request:
| field | | |
|---|---|---|
| `program` | required | the program's text (§2.1) |
| `seed` | optional, default 1 | a whole number, or a string of 1 to 20 ASCII digits, so that all 64 bits survive a language whose numbers are doubles |
| `temperature` | optional | the starting temperature, over the program's own; 0 is the deterministic mode. A JSON number, which a reader MUST read to the nearest double, or a string `[0-9]+(.[0-9]+)?` of at most 40 characters, read to the nearest double: no sign, no exponent, no other form |
| `seeds` | `sweep`, `compare`, `replay` | how many seeds, from `seed` up, 1 to 100,000; default 20 |
| `temperatures` | `sweep` | 1 to 64 of the same; by default 0, 0.25, 0.5, 1, 2, 4 and 8, with the default start (§4.3) and the largest row of couplings added where they are not already there, in increasing order |
| `parity` | optional, default `bit-exact` | `bit-exact`, or `statistical`, which lets a placing host give the job to a kernel graded `statistical` too (§5.1) |
| `protocol` | optional | if given, it MUST be this protocol's name |
An optional field given as `null` is absent.
The operations are `run`, `sweep` (the program at each temperature, with the
same budget at each), `compare` (§6), `replay` (many seeds, one line each) and
`examples`.
A host MUST refuse a request or a program it cannot run with one plain sentence,
and name the line where a line means anything: `Line 6: ...`. Nothing in a
program is silently dropped. A refusal is not an answer and carries no receipt.
### 2.0. Limits
Every quantity a job can ask for is bounded before any of it runs, and every host
applies the same bounds, so that a job answered on one host is answered on every
host, in a page as natively. A host MUST refuse, with one plain sentence:
- a program longer than 4,194,304 bytes; more than 4096 variables; `steps` outside 1
to 1,000,000; `restarts` outside 1 to 100,000; more than 16 `#! check` lines, or
more than 65,536 items between them (pairs; a grid's `M²` cells; numbers; cells);
a number in `#! check balance` above 2⁴⁰ in size; a field or cost, after pins and
quantisation, above 2⁴⁰ in size;
- a job whose operations, counted as below before anything runs, exceed 2×10¹⁰;
- a job whose memory, counted as below before anything runs, exceeds 268,435,456
bytes, or the host's own limit where it has a lower one (a page states its own).
With `n` variables, `P` coupled pairs, `C` items in the checks and a plan of `R`
starts of `S` sweeps, the operations of a job are `n²` (reading the couplings into
rows), plus, where `n ≤ 16`, `3ⁿ·(n + 1 + C)` (the exhaustive truth) and, for a
program with `weight`s, `3ⁿ·n²` more; plus, for each run, `(2P + n)·R·S` (the
sweeps) `+ (4P + n)·S·⌈R / D⌉` for a plan above temperature 0, with `D` the smaller of
4096 and `⌊1,048,576 / n⌋` (one sweep's cut points as a device works them out, §4.2,
once for each batch of starts, §5) `+ (2P + n)·R` (each start's energy) `+ n²`, or
`2n²` with weights (the answer's energy) `+ C` (its checks). A `run` is one run; a `replay` and each row of
a `sweep` are one run a seed, a settle row one run; a `compare` is five runs a seed
of its sampling plan. The memory is the program's bytes `+ n²`, `+ 8n²` with
weights, `+ 32P + 64n`, `+ 64P + 16n` (one sweep's cut points as a device holds
them, §4.2), `+ 2,359,296` (a batch of chains, §5), `+ 256` a line of a `replay`,
`+ 1,048,576`.
A host does not hold more than one batch of chains at once: at most 1,048,576 cells
and at most 4096 chains a call to a member.
### 2.1. The program: epuML
The grammar is ASCII and strict. Lines end at a line feed (U+000A), and a carriage
return just before one is dropped. `#` starts a comment, to the end of the line.
Tokens are separated by spaces (U+0020) and tabs (U+0009) and by nothing else, so
any other character, a no-break space or a byte-order mark among them, is part of
a token, and a token no statement takes is refused. Numbers:
| | grammar | |
|---|---|---|
| a variable, a count | `[0-9]+` | leading zeros allowed |
| a whole number | `-?[0-9]+` | within 64 bits; no `+` |
| a temperature | `[0-9]+(.[0-9]+)?` | at most 40 characters; no sign, no exponent |
| a weight | `-?[0-9]+(.[0-9]+)?(e-?[0-9]{1,3})?` | `E` for `e` too; at most 40 characters |
A decimal is read to the nearest double. One statement a line; the first statement
is `vars`, and the last is the run line.
```text
vars N N variables, at most 4096
agree I J coupling +1
oppose I J coupling −1
couple I J W a coupling given directly, W is −1, 0 or +1
weight I J W a real-valued coupling, quantised to its sign (§2.2)
pin I +|- hold I at + or −, with a field larger than anything else can outvote
lean I +|- a field of +1 or −1 on I
field I B a whole-number field on I
cost C the cost c
minimize [steps=S] temperature 0, from every variable at 0; S defaults to 60
solve [t0=T] [restarts=R] [steps=S] from R random starts, cooling from T to 0; R defaults to 8, S to 40
```
A reader MUST refuse an unknown statement or key, a statement after the run
line, `weight` together with `agree`, `oppose`, `couple` or `pin`, a variable
pinned both ways, and a `pin` on a variable that has a field. Setting a pair
twice is a warning, and the last one holds.
**A pin's size.** Once every line is read, each pinned variable gets the field
`±(D + B + c + 1)`, where `D` is the largest number of couplings any one variable
has (at least 1), `B` the largest `|b_i|` of every field set by `field` and `lean`,
and `c` the cost. If that is above 2⁴⁰ the program is refused, at the first `pin`'s line.
Lines beginning `#!` are comments to the language, so a program with them is
still a plain program. To a reader that knows them they say what the program
means and how to check an answer against the problem it was written for:
```text
#! title T #! about T #! expect works|fails
#! item NOUN #! plus NAME #! minus NAME #! zero NAME
#! check different 0-1 1-2 each pair ends up in different states
#! check permutation M an M×M grid holds one + in each row and column, and no −
#! check balance A B C … the numbers split into two equal piles, none left out
#! check matches +-0+ the state is this one, or its mirror image
```
### 2.2. Weights
A coupling is one sign. A program that gives real-valued `weight`s is quantised,
exactly so:
1. The scale `m` is the mean of `|w|` over the pairs given a weight other than 0,
summed in order of `i`, then `j > i`, as doubles; 1 if there are none.
2. A weight with `|w| > m/2` becomes the coupling of its sign; any other weight
becomes 0, and is dropped.
3. Each field `b_i` becomes `round(b_i / m)` and the cost `round(c / m)` (at least
0), dividing as doubles and rounding half away from zero. A result above 2⁴⁰ in
size is refused: the weights are too small beside the fields and the cost.
The answer MUST say what was lost (`declared.quantised`: the scale, how many were
declared, kept and dropped, and the relative error `√(Σ(w − m·t)² / Σw²)` with `t`
each weight's coupling), give the energy of its state on the weights as declared,
and where every arrangement can be checked say whether that state is the lowest on
them (`declared`, §3). Two energies on declared weights are equal within 10⁻⁹. A program whose sizes matter does
not run on this model, and its answer says so rather than reaching a low energy
on signs that mean something else.
## 3. The answer
A `run` answers with these fields (the schema has them all):
| field | |
|---|---|
| `protocol` | `wai.quantum.landscape/1` |
| `label` | what kind of run this is, in the member's own words (§5.3) |
| `member` | what ran it: `id`, `class`, `kernel`, `parity`, the `capacity` that parity holds within, absent where none is declared (§5), and `demoted`, why the host holds it at `uncertified`, where it does (§7.3) |
| `program_digest` | BLAKE3 of the program's bytes |
| `seed`, `mode`, `temperature`, `temperature_from`, `restarts`, `sweeps` | how it ran; `seed` is a decimal string; `mode` is `settle`, `quench` or `sample` |
| `state`, `energy` | the state of lowest energy found, and its energy from the program |
| `truth` | every arrangement checked (up to 16 variables), else null: `arrangements`, `lowest`, `at_lowest`, `at_lowest_passing` and `example` |
| `reached` | whether `energy` is `truth.lowest`; null where there is no truth |
| `declared` | for a program with `weight`s: §2.2; else null |
| `warnings` | what the reader found in the program: `code`, `line`, `text` |
| `checks` | each `#! check`, graded on `state` |
| `verdict`, `summary` | `solved`, `missed`, `failed` or `unchecked`, and the sentence that says why |
| `work` | `sweeps`, `accumulates`, `cell_updates`, `draws`, `ended`, `rests` |
| `joules` | §4.4 |
| `state_hash`, `replay` | §3.2 |
| `refusals` | each member that a placing host passed over, with why (§5); absent where there was none |
| `audit` | what the host's audit ran again on the reference, for an answer from a kernel graded `bit-exact`: `checked`, each run's `seed` with the `chains` of it checked, or how much of a `settle` (§7.3); absent where nothing was audited |
A `replay` answers with `protocol`, `label`, `member` (`id`, `class`, `kernel`,
`parity`, `capacity`, `demoted`), `seeds` and `lines`. A `sweep` and a `compare` give
`member` as `id`, `class`, `capacity`, `demoted` and `kernels`, each kernel the job used
with the parity the host found for it;
each row of a `sweep` gives its own `kernel` and `parity`, and each of a `compare` the
member's `parity`, null for a classical method. Each carries `refusals` and `audit` as a
`run` does.
An accumulate is one read of one coupling into one cell's field, and is the unit
of work. The accumulates of a sweep are the non-zero entries of `W`, counting each
pair twice, whatever device does it.
### 3.1. The verdict
`failed` means the answer does not solve what the program states. A host MUST
report it when: the deterministic mode never came to rest; it ran out of sweeps;
the answer fails a `#! check`; the lowest states of the landscape fail the
program's check, in which case the landscape itself does not express the problem,
whatever a run returns; or the answer misses the lowest energy on declared weights.
A host MUST grade every lowest state, not just the one it found: an answer can
pass by luck where the landscape is wrong. `at_lowest_passing` holds that count.
`missed` means the truth is known and the run did not reach it. `solved` means it
did, or that a check passed where the truth is out of reach, in which case the
summary says nothing shows the energy is the lowest. `unchecked` means neither a
truth nor a check exists. A job that ran exits as success on a command line,
whatever its verdict.
### 3.2. Replay
The digest's restarts are 1 for a settle, and its sweeps are the plan's sweeps,
the `steps` asked, not the sweeps a settle ran.
`state_hash` is FNV-1a over the state's cells, each the byte `s + 1`, printed as 16
hex digits. `replay` is BLAKE3 over, in order: the protocol's name and a zero byte;
the program's length (u64, little-endian) and its bytes; the seed (u64, little-endian);
the mode's name and a zero byte; above temperature 0, the bits of the starting
temperature (IEEE 754 binary64, as a u64, little-endian); the restarts (u64,
little-endian); the sweeps (u32, little-endian); the state's cells, each the byte
`s + 1`; the energy (i64, little-endian).
The digest leaves out the member and the work. Two members that give the same
bits give the same digest, and anyone can re-run a job on any member held to bits
and compare. For a member with draws of its own (§5.1) the digest identifies the
answer and cannot be reproduced from the seed. The energy can always be recomputed
from the program.
## 4. The kernels
A host's plan is one of three, from the run line and the request's temperature `T`:
| run line | `T` | plan | starts | sweeps |
|---|---|---|---|---|
| `minimize steps=S` | none, or 0 | `settle`: from every cell at 0, stopping when it comes to rest | 1 | at most `S` |
| `minimize steps=S` | above 0 | `sample`, cooling from `T` | 8 | `S` each |
| `solve restarts=R steps=S` | 0 | `quench`: chains at temperature 0, every sweep run | `R` | `S` each |
| `solve restarts=R steps=S` | above 0 | `sample`, cooling from `T` | `R` | `S` each |
| `solve t0=T₀ …` | none | `quench` if `T₀` is 0, else `sample`, cooling from `T₀` | `R` | `S` each |
| `solve …` without `t0` | none | `sample`, cooling from the default start (§4.3) | `R` | `S` each |
A `settle` runs the settle kernel; a `quench` and a `sample` run chains through the
sampling kernel, a quench's every sweep at 0. Of many starts the host keeps the first
state of lowest energy, in order of start.
### 4.1. `wai.quantum.landscape/settle`
Each cell adds up its field, `h_i = b_i + Σ_j W_ij s_j`, and moves to +1 when
`h_i > c`, to −1 when `h_i < −c`, and to 0 otherwise. A sweep reads all the fields
from the same state, then moves all the cells. A settle ends at a fixed point (the
state did not change), a two-cycle (the state returned to the one two sweeps back;
the state reported is the one the last sweep computed) or the bound. Everything here is whole-number arithmetic: the result cannot depend
on the order a field is added in, on how many lanes a device has or on how it
splits the cells. A settle kernel MUST give the reference's bits.
A workload's **field bound** is the largest `|h_i|` any state can give a cell:
`max_i (|b_i| + deg_i)`, with `deg_i` the number of cells coupled to `i`. It, and not
the largest `|b_i|`, says how wide a lane must be to hold every field.
A `quench` runs chains through the kernel of §4.2 at temperature 0, whose every
sweep is this one.
### 4.2. `wai.quantum.landscape/sample`
Cell by cell, in order, each reading the states the cells before it have just
taken, a cell draws its next state with the Boltzmann weights of its field:
```text
P(s) ∝ exp((h·s − c·|s|) / T), s ∈ {−1, 0, +1}
```
Updating every cell at once from one common old state does not sample this model's
joint distribution: two coupled cells would each follow the other's old value. A
kernel that does so fails the battery of §7.2 and is not granted `statistical`. A
kernel that colours its cells properly, so that no two coupled cells move at once,
can pass it.
**The schedule.** The host gives a member every sweep's temperature. A chain of `K`
sweeps cooling from `T₀` has, at sweep `k` (from 0), `q = k / (K − 1)` and
`T_k = T₀ − T₀·q`, each operation rounded to the nearest double in that order; a
chain of one sweep is at 0. So the last sweep is at 0, where a sweep is §4.1's. The
conformance set pins the schedule's bits (§7.1).
**One draw, two cut points.** For a field `h` at a temperature `T` above 0, with
`β = 1 / T`, `l₋ = −h − c`, `l₊ = h − c` (whole numbers, exact as doubles) and `m`
the largest of `l₋`, 0 and `l₊`:
```text
w₋ = exp(β · (l₋ − m)), w₀ = exp(β · (0 − m)), w₊ = exp(β · (l₊ − m))
z = (w₋ + w₀) + w₊
a = ⌊ (w₋ / z) · 2⁵³ ⌋, b = ⌊ ((w₋ + w₀) / z) · 2⁵³ ⌋
```
every operation a double rounded to the nearest, in the order the parentheses give,
and `exp` the function of Appendix A.
A 53-bit number `u` gives −1 if `u < a`, 0 if `u < b`, else +1. A device needs a table
of cut points for the fields it can see at each sweep's temperature and two comparisons
a cell. It needs no exponential and no floating point. The host may give it the table.
Cell `i` only ever sees `b_i − deg_i` to `b_i + deg_i`, so a table of those fields, where
two overlap taken once, holds at most `4P + n` entries a sweep however wide the fields
are, and at most `2B + 1` for a field bound `B`.
**The reference's draws.** They come from a counter, not from a state carried along:
```text
mix(x): x ^= x >> 30; x *= 0xBF58476D1CE4E5B9;
x ^= x >> 27; x *= 0x94D049BB133111EB; x ^= x >> 31
out(s, j) = mix(s + j · 0x9E3779B97F4A7C15) (64-bit, wrapping; j ≥ 1)
```
For a run's seed `S`, start `r` (from 0) has the chain seed `C = out(S, r + 1)`; its
cell `i` starts at `out(!C, i + 1) mod 3 − 1`; and the draw of cell `i` in sweep `k`
is `out(C, k·n + i + 1) >> 11`. Any draw can be computed alone, so chains may run
side by side and still give the reference's bits. The exponential of Appendix A uses
`+ − × ÷` alone, so it gives the same bits on every IEEE 754 platform; the conformance
set pins its values and the cut points it gives (§7.1). A device takes the table from
the host, or computes its own and is held to it.
A member MAY use draws of its own, and then its parity is `statistical` at most.
### 4.3. The default start
A `solve` with no `t0` starts at `max(1, √(2·P/n))`, where `P` is how many pairs are
coupled: the square root of the mean couplings a variable has. The answer's
`temperature_from` is `landscape`, and its words say this is the default. A starting
temperature set from the largest row of couplings is hotter than most instances
need, and at the same budget does worse on the larger instances of the published
table; the table's `start_temperature` section has the numbers.
### 4.4. How the joules are stated
`joules` is an object with `kind: "priced"`, always. It is this run's accumulates
multiplied by a rate measured elsewhere, with that rate's source named. A host:
- MUST state the figure as priced, and MUST NOT call it measured, read, or metered,
in `line` or anywhere an answer's reader sees it. `rate_source` may say the *rate*
was measured, and on what.
- MUST state its class in the terms of [energy-measurement](energy-measurement.md):
`ModelBased` for the figure, which describes the board the rate was calibrated on
and says nothing of what the machine that ran the job spent (`describes`), and
`Estimator` for the published add's figure (`published_add`).
- MUST price temperature 0 and sampling at separate rates. Sampling costs more.
- MUST say what the rate leaves out (`left_out`): a rate that is a difference
cancels the board's own draw, so a small job prices low, by an amount the answer
gives from the fewest clocks the work could take.
- MUST NOT print an uncertainty it does not have.
A member with a meter puts its reading in `joules.metered`: `{ "joules_micro": …,
"window_us": …, "class": …, "scope": … }`, with the class and the evidence
energy-measurement asks of that class. Over a run of several calls the figure and the
window are each the calls' added up, and so is the window of the class's uncertainty;
its relative part is the largest a call declared. `scope` says what the figure covers
where that is more than the run: a counter that reads a whole rail or board holds its
idle draw and any other work on the device in the window, and says so; null is the run
alone. The reading stands beside the priced figures and does not replace them, so the
two can be compared, and the answer's `label` says it is there and what it covers only
where it is. Where there is no meter or no reading, `metered` is null. No figure is `0`
for being unmeasured.
The reference's rates:
| | pJ per accumulate | from |
|---|---|---|
| temperature 0 | about 0.16 | one FPGA board, a dense 64-cell test design at 100 MHz, the slope of power against clock speed |
| sampling | about 0.41 | the same board: about 0.25 more, from paired readings at one temperature, 0.25, on a design that updates all its cells at once |
| for scale | about 0.03 | a published 2014 figure for one 8-bit integer add in 45 nm logic: a reference point, not a model of any processor, with no term for sampling |
| left out | about 3.1 W at every clock | the same board's own draw, at 100 MHz |
These are the numbers of one board and one meter. They are not part of the protocol:
another host MAY price at rates of its own, with their sources named.
What stands behind them, stated plainly (2026-11-10): the readings of the board the two rates
were read on are not in this repository. The sampling rate's increment was read on a design that
updates every cell at once, which does not sample this model (§4.2). And this project's own FPGA
member, `wai/wai-quantum-landscape-fpga`, measured its settle at about 0.88 pJ an accumulate (its
README, *What it measured*), more than five times the 0.16 above, so a priced line here is low
against this project's own hardware. The rates are kept as they are so that this version's
answers keep their bytes: the replay lines of §2 hash each whole answer, its joule line among
them. The second version ([quantum-landscape-2](quantum-landscape-2.md) §4.3) prices only at a rate
whose evidence is in this repository, never below what this project's hardware measured, and
leaves a run above temperature 0 unpriced, saying why.
## 5. Members
A member runs the two kernels and nothing else. The reader, the truth, the energy of the
state it returns, the checks, the verdict, the replay digest and the seal stay on the
host, and do not trust the member.
What the host gives a member: the lowered workload (`n`, the couplings as compressed
rows, the fields, the cost); for a settle, a start and a bound; for chains, each chain's
start and chain seed, and every sweep's temperature (§4.2). A host gives at most one
batch of chains at a time (§2.0).
What a member gives back, for a settle or each chain: the state, the sweeps, how it
ended, the accumulates and the draws.
**Declared capacity.** Real hardware holds so many cells, fields so wide, a table so large.
A member declares what its kernels hold, once and before anything runs, as fixed numbers
(`member.capacity`, each of them optional, none declared being no limit):
| number | what it bounds |
|---|---|
| `cells` | the cells of a workload |
| `couplings` | its couplings, each pair counted twice (`2P`) |
| `at_zero`: `field`, `field_bound`, `cost` | for a run with a sweep at temperature 0 (a settle, a quench, the end of a schedule): the largest `\|b_i\|`, field bound (§4.1) and cost |
| `above_zero`: `field`, `field_bound`, `cost` | the same, for a run with a sweep above temperature 0 |
| `table_entries` | above temperature 0: one sweep's cut points over the fields the cells can reach (§4.2) |
| `uncertain_span` | above temperature 0: the span, first to last, of the fields the cells can reach whose draw is uncertain at a sweep's temperature, where it is not the threshold's `(0, 0)`, `(0, 2⁵³)` or `(2⁵³, 2⁵³)`. Those fields at a temperature hold those at any lower one, so the hottest sweep's span is the widest, and it is the one held to the number |
| `sweeps` | the sweeps of one run: a settle's bound, a schedule's length |
| `chains_per_call` | the chains it takes in one call. Not a limit on a job: a host splits a job into calls of at most this many, and certification splits every vector the same way (§5.1), so no job goes elsewhere for it |
A workload fits when every declared number but `chains_per_call` holds for it. Whether it does is a function of
the workload, its schedule and the declared numbers alone: the host works it out, and
declines for the member exactly the workloads that do not fit, saying which number each
is past. A member declines nothing by choice, job by job, and is run on no workload past
its capacity, however it was reached. A member that refuses or fails a workload within
its capacity has failed it. The reference declares no capacity.
**The floor.** A member's declared numbers MUST be at least the floor's, or the host does
not certify it at all, so that no member is certified by declaring itself too small to
be held to anything. The floor is the least capacity that takes every case of the core
set (§7.1): the settle, chains and battery cases the set held before it grew to reach
large jobs. Its numbers are 32 cells and 992 couplings (the recall vector of 32 cells,
every pair coupled); on each side of temperature 0, fields to ±40, a field bound of 41
and a cost of 8 (the wide-fields chains, run cooling and quenched at 0); 31 entries of
cut points a sweep (the dense chains of 16 cells, every pair coupled, at their hottest);
an uncertain span of 61 (the wide-fields chains at their hottest); and a run of 5,000
sweeps (the core set's long schedule, §7.1). It declares no batch: any number of chains a
call is certified by splitting. A device that cannot hold these cannot be held to the
core set, and the grade would vouch for nothing.
**Generated vectors.** A finite set samples each axis of a workload at a few points,
and a declared number takes vectors out of it. So the host also holds a member to vectors
it generates from the member's capacity, by the rules of §7.1, with the reference's bits
as their expected bits and the same on every host. Some are generated for every
capacity, the reference's none among them, so that a member is held across each axis up
to what its capacity lets a workload reach: every cell count at and beside a power of
two, every call size to 32 chains and each band of a wavefront past that, the longest
row, fields at each lane's wrap points, a corner with every number at its most, and a
run past a 24-bit draw index. Others
are generated for each number a member declares below what a job can reach (§2.0: 4096
cells; 838,860 couplings, two for each ten bytes of the longest program; a field and a
cost of 2⁴⁰; a field bound of 2⁴⁰ + 4095; a table of twice the couplings and the cells;
a span of twice the field bound and one; 1,000,000 sweeps), at exactly that number, each
also within every other number declared. A table or a span is reached through couplings;
where the other declared numbers do not let a workload reach it, the vector reaches as
far as they do. Only vectors the capacity admits are run. So a grade is earned across a
capacity and at its edges, not only at the fixed vectors inside it. No finite set catches
every fault, so the host then audits every answer from a kernel it graded `bit-exact`
(§7.3).
**Placing a job.** A host offered several members gives the job to the first that can
take it: one whose kernel is certified for every kernel the job runs (§5.1), within
whose capacity the workload fits at every schedule the job runs, and that gives an
answer the host's checks keep. Each member
passed over, for any of those, is named under `refusals`, in the order offered, with
why; with none, `refusals` is absent. A member that took the job and failed it, or
whose answer the checks refused, is passed over the same way and the next is asked.
Where no member answers, the job is refused, naming each with why. Offering the
reference last gives every job an answer.
**Batches.** A host MAY give a member the starts of several seeds' runs in one call,
up to one batch (§2.0). Each run is the one it would be alone: the same chains, its
best state chosen in the same order. A meter's reading (§4.4) stands for a run only
where every call of that run carried that run alone, and a settle that answers several
seeds from one call carried none of them alone; elsewhere `metered` is null.
A host MUST check what comes back, and refuse the answer with one plain sentence if
any of these does not hold:
- the state has the right length and every cell is −1, 0 or +1;
- for a settle: 1 to `bound` sweeps; accumulates `2P` a sweep and no draws; a fixed
point that rests (no cell would move); a two-cycle of period exactly 2 (one sweep
moves the state, a second returns it), after at least 2 sweeps; a bound reached
only after `bound` sweeps;
- for a chain: every sweep of the schedule run; accumulates `2P` a sweep and `n`
draws a sweep above 0; and the ending a fixed point exactly when the state rests.
It MUST recompute the energy from the program. So a member can be wrong about a state
only by returning a worse one, and it cannot price itself low. How many sweeps a settle
took before it came to rest can be checked only by running it again: a `bit-exact`
certificate is what vouches for it.
The reference implementation has three GPU members besides the CPU reference, each
certified by the host on its own run of the conformance set within the capacity it
declares (informative): through WebGPU (a field bound of 2³¹ − 1 on both sides of
temperature 0, which its 32-bit lanes hold; cells and couplings within a 32nd of a
storage binding; 4,194,304 entries of cut points a sweep. It holds a cost above every
field at its lanes' top, where it holds every cell at 0 as it does at its own size, and
its coloured kernel can be `statistical` at most), and through CUDA and Metal (64-bit
fields, and 4,194,304 entries of cut points a sweep, which no job reaches). An FPGA board
(`wai/wai-quantum-landscape-fpga`) declares 64 cells and, above temperature 0, fields to
±524,287, a cost to 1,048,575 and an uncertain span of 8,192, its registers and its
table's window. All three run the sampling kernel one
chain a thread, the cells in the reference's order, with the reference's draws and the
host's cut points for the fields the cells can reach, a window of sweeps a dispatch, each
window waited for before the next is sent; and give its bits.
A member names itself `class:name`, with `class` one of the fabric's (`cpu`, `gpu`,
`fpga`) and the class it gives, and `name` lower-case letters, digits, `.`, `_` and `-`,
at most 64 characters in all. `cpu:reference` is the reference's, and no other member's.
### 5.1. Parity
A member does not state its parity: the host finds it, by running the member's kernels
on the conformance set (§7) within the member's declared capacity (§5) and at its edges,
and an answer
states what the host found for the kernel the run used (`member.kernel`,
`member.parity`) and the capacity it holds within (`member.capacity`, absent where none
is declared, so that the reference's answers are what they were). A parity is a statement about the jobs within that capacity, and no others.
| parity | granted when |
|---|---|
| `reference` | to the host's own reference kernels, and to nothing else |
| `bit-exact` | settle: the member gives every `settle` vector within its capacity, and every one generated for it (§5), exactly. Sample: it gives every `chains` vector within its capacity and every one generated for it exactly, each case's chains in calls of as many as a host would give it at run time: the batch of §2.0, or `chains_per_call` where it declares fewer |
| `statistical` | sample: not `bit-exact`, and every workload of the `statistical` battery within its capacity, and every battery workload generated for it, passes (§7.2), in calls of the same size |
| `uncertified` | anything else, or a member the host was asked to run by name without certifying it |
The host reads a member's capacity once, before anything runs: the floor is checked
against that reading, the vectors are held to it, and every answer states it. A member
is held to every vector within its capacity, and refusing one is failing it. A grade
holds while the host's audit finds nothing (§7.3): at the first answer from a kernel
graded `bit-exact` that differs from the reference's, the member is `uncertified` for
both kernels from then on.
The set holds vectors on both sides of a field bound of 2³¹ − 1, at it and just above it
by the couplings alone, so that a member that declares 32-bit lanes is held to their
edge. A capacity under the floor (§5) is not certified.
A settle kernel can earn `bit-exact` on any device. A sampling kernel can, if it uses the
reference's draws and order and the cut points of §4.2.
A host placing a job never places an uncertified kernel (§5). A host MAY still run one
when it is asked for that member by name, without placing it, which is how a board gets
its first answers; the answer says `uncertified`, and nothing should be concluded from
its state but its energy. Even then the host runs it on nothing past its capacity.
### 5.2. The receipt
A host seals an answer in the form of every engine result: the request, and the result
with `receipt` (`wai-quantum/schemas/receipt.v2.json`), a digest over both and an Ed25519
signature, verified by the rule every quantum receipt is ([quantum-providers](quantum-providers.md)
§8.2 *The signature, strictly*). `member` is inside what is signed. The receipt says which key vouched for the
answer and the answer says what ran it, so a board's answer sealed by the host that drove
it names the board and names the host's key. `wai-quantum verify` checks it: the seal, and
the answer's form by §5.4.
A job sent to a person's own provider travels in this form, its operation and its request,
and comes back as this answer; the client that sent it checks the answer by §5.4 and seals
it, naming the provider (quantum-providers §11).
### 5.3. The label
Every answer carries `label`, a sentence that says what kind of run this is. The
reference's, word for word:
> A classical emulator of the settling model of a planned energy-based processor, running on your machine.
> Energies are computed exactly. The joule line is this run's operation count priced at
> rates measured on an FPGA, with a published figure for one integer add beside it for
> scale. No photonic hardware, custom chip or quantum effect is involved in this run.
A member states its own, and MUST say what device ran the job, whether its joules are
priced or read from a meter, and that no quantum effect is involved where none is. It
calls a device what it is: a software driver that runs on the processor is not a GPU.
An answer adds that a reading stands beside the priced figures, and what it covers, only
where that answer carries one (§4.4); and, for a member that declares a capacity, that
the host runs it on no job past that capacity, in its numbers, and, where the host
certified it, that its parity holds within it (§5). A member run by name without
certification claims no grade, and one the audit demoted says so and why (§7.3).
### 5.4. Verifying an answer
A verifier holds a sealed job of this kind, its request and its answer, to the rules below,
and reports `landscape_form` (quantum-providers §8.4) when any of them fails. A job is of this
kind when its result's `protocol` or its `schema` is `wai.quantum.landscape/1`. Every rule is
checked from the job alone, without reading the program: the rules hold that the answer is of
its form, and that what anyone can work out from the request and the answer is what the answer
states. The state, the member, its parity, the audit and the truth stay the host's word; the
rules hold their form only. A number's value is its nearest double, and a whole number is one
whose value is whole, however it is written (quantum-providers §8.2, §8.4). In the request, a
member given as `null` is absent (§2); in the answer, `null` is a value.
1. The receipt's `canon` is `rfc8785`: no answer of this kind was sealed in the first form.
2. The result's `protocol` and `schema` are each `wai.quantum.landscape/1`, and its `engine`
is an object whose `name` is `wai-quantum` and whose `version` is a string.
3. The request is of §2's form: `program` is a string of at most 4,194,304 bytes; `seed`, where
given, is a whole number from 0 to 2⁶⁴ − 1, or a string of 1 to 20 ASCII digits whose value
is at most that; `temperature`, where given, is a number, or a string `[0-9]+(.[0-9]+)?` of
at most 40 characters, whose value is 0, or finite and at least 0.000001; `seeds`, where
given, is a whole number from 1 to 100,000; `temperatures`, where given, is an array of 1 to
64 temperatures of that form; `parity`, where given, is `bit-exact` or `statistical`;
`protocol`, where given, is `wai.quantum.landscape/1`; and `provider`, where given, is a
string, not empty (quantum-providers §11.3).
4. The answer's operation is read from its members: a `replay` where it has `lines`; else a
`compare` where it has `rows` and `target`; else a `sweep` where it has `rows`; else a `run`
where it has `state`. An answer with none of them is of no operation: this rule fails, and
the rules below that name an operation do not apply.
5. `label` is a string, not empty.
6. `member` is an object of exactly `id`, `class`, and `kernel` and `parity` for a `run` or a
`replay`, or `kernels` for a `sweep` or a `compare` (a non-empty array of objects of exactly
`kernel` and `parity`, no kernel twice), and optionally `capacity` and `demoted`. `class` is
`cpu`, `gpu` or `fpga`, and `id` is that class, a colon and a name, not empty, of lower-case
letters, digits, `.`, `_` and `-`, at most 64 characters in all. Each kernel is
`wai.quantum.landscape/settle` or `wai.quantum.landscape/sample`, and each parity is
`reference`, `bit-exact`, `statistical` or `uncertified`: `reference` exactly where `id` is
`cpu:reference`, and `statistical` only for the sampling kernel (§5.1). A `compare` names
the sampling kernel alone.
7. `demoted`, where present, is a string, and every parity the member states is `uncertified`
(§7.3).
8. `capacity`, where present, is on a member other than `cpu:reference`, and is an object, not
empty, whose members are among `cells`, `couplings`, `table_entries`, `uncertain_span`,
`sweeps` and `chains_per_call`, each a whole number of at least 0, and `at_zero` and
`above_zero`, each an object, not empty, whose members are among `field`, `field_bound` and
`cost`, each a whole number of at least 0. Where a parity the member states is `bit-exact` or
`statistical`, each of these numbers it gives is at least the floor's (§5): `cells` 32,
`couplings` 992, on each side `field` 40, `field_bound` 41 and `cost` 8, `table_entries` 31,
`uncertain_span` 61 and `sweeps` 5,000.
9. `audit` is present exactly where a parity the member states is `bit-exact` (§7.3), and is
then an object whose `checked` is a non-empty array. `refusals`, where present, is a
non-empty array of objects whose `member` and `why` are strings.
10. A `run`: `program_digest` is the BLAKE3 of the request's program, as 64 lower-case hex
digits; `seed` is the request's seed in decimal, with no leading zero (`1` where it gives
none); `mode` is `settle`, `quench` or `sample`, and the member's `kernel` is the settle
kernel for `settle` and the sampling kernel otherwise; `temperature` is a number, 0 for
`settle` and `quench` and above 0 for `sample`, and the request's value where it gives
one; `restarts` is a whole number from 1 to 100,000, and 1 for `settle`; `sweeps` is a
whole number from 1 to 1,000,000; `state` is a string of 1 to 4096 characters, each `+`,
`-` or `0`, and `variables` is its length; `energy` is a whole number from −2⁶³ to 2⁶³ − 1;
`state_hash` is the state's hash (§3.2), as 16 lower-case hex digits; `replay` is the
digest of §3.2 from the request's program, `seed`, `mode`, `temperature` (its bits, for
`sample`), `restarts`, `sweeps`, the state and `energy`, as 64 lower-case hex digits;
`joules` is an object whose `kind` is `priced` and whose `metered` is `null` or an object
whose `joules_micro` and `window_us` are whole numbers of at least 0 (§4.4); `verdict` is
`solved`, `missed`, `failed` or `unchecked`; `truth` is `null` or an object whose `lowest`
is a number; `reached` is `null` where `truth` is, and otherwise whether `energy` equals
`truth.lowest`; and the verdict is not `missed` without a truth and not `unchecked` with
one, and is `solved` or `failed` where `reached` is `true` and `missed` or `failed` where it
is `false` (§3.1).
11. A `replay`: `seeds` is the request's (20 where it gives none), and `lines` is a string of
exactly that many lines, each ending in a line feed and holding seven fields, one space
between each two: the line's seed in decimal (the request's seed, plus one for each line
before it, modulo 2⁶⁴), 16 lower-case hex digits, a state as rule 10 has it (every line's
of one length), its energy (`-?[0-9]+`), a verdict as rule 10 has it, the accumulates
(`[0-9]+`), and 16 lower-case hex digits.
12. A `sweep` or a `compare`: `rows` is a non-empty array of objects. Each row of a `sweep` has a
`kernel` the member names, the `parity` the member states for it, and a `mode` of rule 10
that kernel runs; each row of a `compare` has `classical`, `true` or `false`, and `parity`,
`null` exactly where `classical` is `true` and otherwise the member's parity for the
sampling kernel. A `compare`'s `target` is a whole number.
13. A provider's job (quantum-providers §11.3): the result has `provider`, `job` and `cost`
exactly where the request has `provider`. Then `provider` is an object of exactly `name`
(the request's `provider`), `kind` (`http` or `process`), `protocol`
(`wai.quantum.provider/1`), `device` (a string, not empty), `provenance` (`silicon`, or
`simulator` or `emulator`, alone or followed by `:` and more) and `describe` (64 lower-case
hex digits); `job` is an object of exactly `id` (a string, not empty) and `polls` (a whole
number of at least 0); and `cost` is an object of exactly `free` and `confirmed`, each `true`
or `false`, with `confirmed` `true` exactly where `free` is `false` (a run that is not free
runs only on the person's confirmation), `estimate`, an object, and `charged`, `null` or an
object of exactly `amount` (digits, and optionally `.` and digits) and `currency` (a string,
not empty).
A verifier that holds this text's reader also reads the program, and states whether the
answer's energy and plan are the program's: a `run`'s `energy` from its state, and its `mode`,
`temperature`, `restarts` and `sweeps` from the program and the request (§4); and each line of
a `replay`, its energy and its replay digest. `wai-quantum verify` states it
(`landscape.recomputed`) and gives a job whose answer the program does not bear out as not
valid, as it does a set whose programs it writes out otherwise (quantum-providers §8.6). That
is the engine's check, not a rule of the receipt: a verifier without the reader does not make
it.
## 6. The comparison
`compare` runs the program on the member and on three classical methods on the same
three-state energy: simulated annealing, tabu search and greedy descent. Each has the
same budget of operations a run: the sampling run's own count, where one operation is
one coupling read, one cell updated or one move considered, whoever does it. A host
gives each row's count of runs at the target, and its best energy. A table MUST be
published as it comes out, including where a classical method leads.
The operation count is not a machine's time. It says nothing of cells that settle side
by side, and the comparison is not a claim about any device.
## 7. Conformance
`quantum-conformance/landscape/vectors.json` is rebuilt by `wai-quantum landscape
vectors`, and a test holds the file to the code. Each part pins a rule of this text, so
that an implementation written from the text alone, which computes any of these another
way, is caught.
The **core set** is the part of it the set held before it grew to reach large jobs, and a
long schedule: the `settle` vectors but `fields-at-the-bound`, the first fifteen `chains`
vectors (three landscapes cooling at five schedules), `a-long-schedule-across-windows`,
and the first eight battery workloads. It sets the floor of a declared capacity (§5), so
no capacity a member may declare leaves out the long schedule. The vectors generated for
a capacity (§5) are not in the file: a host builds them from the capacity, by the rules
below.
### 7.1. Bits
- `settle`: whole workloads, starts and bounds, each with its field bound, and the state,
sweeps, ending, accumulates and state hash the settle kernel gives: the four recall
vectors, every ending, a two-cycle with fields, a bound of one sweep, fields at 2⁴⁰;
waves down paths of 65 to 300 cells, which run past one workgroup of cells and past
64 sweeps, one stopped at its bound in a later batch, a two-cycle of 70 cells and 1000
cells of mixed couplings; fields that only their full width tells apart past 16 and
32 bits; and field bounds at 2³¹ − 1 and just above it (§5.1). A settle kernel is
`bit-exact` when it gives every one it takes exactly and takes every one §5 does not
let it decline.
- `exp`: the bits of Appendix A's function at the arguments the cut points use and at its
edges, as `[x, exp(x)]` pairs of 16 hexadecimal digits.
- `schedule`: the bits of every sweep's temperature for starting temperatures and chain
lengths that tell `T₀ − T₀·q` from other ways of writing it.
- `cells`: the two cut points for fields from −40 to 40, costs from 0 to 8 and temperatures
from 0.25 to 25, the temperature given by its bits too.
- `draws`: the generator's outputs `out(s, j)` at several seeds, and at each seed of the
`a-draw` chains below.
- `chains`: whole chains from their starts and chain seeds, with every start of some runs,
cooling from starting temperatures that include one that is not a short decimal, or
held at temperatures given sweep by sweep (`held`), which need not end at 0, so that
the last sweep's draws are in the final state. Among them: one cell at seeds where a
port of the generator in 32-bit words first goes wrong (a carry out of the middle of a
product, a cut point compared by its high word alone); 16,384 draws in one sweep;
more chains than a workgroup; chains that stop hot, in which the order of the cells
shows; chains long enough to cross a device's windows of sweeps, by table and by
work, hot in every window: among them, in the core set, 5,000 sweeps on 32 cells each
coupled to 15 others, within the floor on every number, which cross windows of both
kinds, and 200,000 sweeps of two cells, across a window by work on the smallest
workload; and the same fields past 16 and 32 bits and at the line as the settle
vectors, at 0 and at a temperature of their own size. A sampling kernel is
`bit-exact` when it gives every case it takes exactly, each case's chains in calls of
as many as a host would give it (§5.1), and takes every one §5 does not let it
decline.
- Generated, by rule, from a member's capacity (§5), where `C` is the most cells it lets
a workload hold (4096 with none), `P` the most coupled pairs, `B` the chains of one call
(4096, or `chains_per_call` where fewer), and each vector run only where the capacity
admits it:
- cells: for each `n` of 1, 2 and 3, each power of two to `C` with one less and one
more, and `C` and `C − 1`: `n` cells, each with a field of 1 or 2 of either sign so
that every one moves in its first sweep, coupled each to the next (spread along the
whole line where `P` is fewer); settled for 4 sweeps, and held at 1.5 for 3; and,
where a last partial warp of 32 or workgroup of 64 holds more than half of it,
quenched at 0 for 3 sweeps; and a wave settling down as many cells as a workload can
hold (`C`, or `P + 1` where fewer), one cell a sweep, coming to rest within the most
sweeps a run may have (of fewer cells where those are fewer): as long as a wave can
be; and the same wave stopped at its bound one sweep before it would rest, its last
sweep moving a cell;
- the final sweep: a sweep at 0 straight after sweeps above 0, as an engine runs it at
the end of a job, on as many uncoupled cells as a last, partial warp of 32 or
workgroup of 64 holds past half of it: 17, 18, 24, 30 and 31, and 33, 34, 48, 62 and
63 (odd and even, at the band's edges and in its middle), each after two sweeps at
1.5, after three (the sweep at 0 at an odd index), and after two and one at 1/64 (a
cold sweep, as an annealing job ends); and, after two sweeps at 1.5, three quarters,
all but two and all but one of a group of 128, 256, 512 and 1,024. Each cell's field
equals the cost of 1, a tie between two states above 0 that the sweep at 0 settles to
0 however cold the sweep before it, so that the sweep moves cells;
- a settle that keeps moving: `u` units of three cells, each unit's third cell agreeing
with the other two and each unit coupled to the next two by fixed patterns (`13u − 16`
couplings), with fields `−2, 1, 6` on the first unit, `0, 3, −1` between and `0, −5, 0`
on the last, which from every cell at 0 moves a cell in every sweep to sweep `11u − 59`
and rests at `11u − 58` (for 10 units or more); or, where couplings are too few for
those to move longer, units of two, each cell opposed to its partner and to the other
cell of the next unit, with fields `0, −5` on the first unit, `1, 2` between and
`−4, 5` on the last, which move to sweep `4u − 10`. Stopped at its bound just past 2⁹,
2¹⁰, 2¹¹, 2¹² and 2¹³ sweeps, where a narrow sweep counter wraps, each on as few units
as still move there, and at its last moving sweep (or the most a run may have) on as
many cells as the capacity takes: with none, 1,365 units of three, 4,095 cells, moving
to sweep 14,956.
A search over units of three found these; no longest-moving settle within the rules is
known, and a sweep counter of 14 bits or more, which none of these wraps, or a stale
read at a bound past the sweeps they reach, is left to the audit (§7.3);
- two-cycles that end late: the same units of three beside two cells that alternate from
the start (agreeing, with fields 1 and −1), so that the whole comes to a two-cycle at
sweep `11u − 57`: with 46 units at sweep 449, the first sweep of a later batch of 64,
where a host that runs a settle in batches must carry the state two sweeps back from
the batch before; and with 378 units at sweep 4,101, past 2¹², where a sweep counter
of 9 to 12 bits read at the ending gives the other phase of the cycle (on as many
units as the capacity takes, to 378). A fault at a two-cycle ending later than these is
left to the audit;
- calls: one call of each number of chains from 1 to 32, of 33, 48, 63, 64, 65, 96, 127
and 128, and of `B` and `B − 1`;
- a row: one cell coupled to as many as a workload within the capacity can give it,
their fields holding them so that its whole row gives it a field of −1 and any
shorter part of the row 0 or more; settled, held at 0.5, and ending at 0;
- lanes: on each side of 0, a cell at each of `2^(L−1) − 1`, `2^(L−1)`, `3·2^(L−2)`
and `2^L`, for `L` of 16, 24 and 32, that the field reaches, of both signs, and a cell
whose field is reached exactly through two couplings at each one the field bound
reaches; and the same beside the largest cost (to `2¹⁵ − 2`), with a cell each side
of the threshold it sets: packed into as few workloads as the capacity takes, so that
a small capacity holds each in a workload of its own size. Each is settled for 3
sweeps and for 1 and quenched at 0; held at `2¹⁵` and at 1/64 above 0; and at `2¹⁵`,
at 1/64 and at 0, and at 1/64 and then 0, where both sides take it, the shape an
annealing job ends in;
- a corner on each side of 0, as the capacity takes it: the largest field of both
signs beside the largest cost under it, so that those cells move at 0, among as
many cells and couplings as the capacity allows (fewer where a table or span limit
asks); and a cell whose field is reached exactly through as many couplings as a cell
can have, the field bound at its most; and a cell at field 0 whose row of cells held
at +1 sums to 128, and to as many as a cell can have, past what a narrow lane holds.
Each at 0, cold above 0, and ending at 0;
- a span: where no span is declared, two hubs on shared cells as wide apart as the
other numbers let them reach (the widest a declared table takes, where it is the
narrower), held at a temperature of the span's size and ending at 0;
- draw indices: one run of `C` cells carried past `2²⁴` where `C` times the most sweeps
reaches it, at 0 until the sweeps that cross it and hot to the end. A run past `2³¹`
would be at least `2³¹` updates in one chain, minutes on a device that runs a chain a
thread, so a draw index narrower than 64 bits past 24 is left to the audit (§7.3);
- at each number declared below what a job can reach: a wave settling down `C` cells;
`P` couplings, each cell's as near as the field bounds allow; the field bound at 0
through couplings and by a field alone, settled to the end and for one sweep, and
above 0 alone, coupled and reached exactly; the field and the cost at 0, and above 0
hot, cold and ending at 0; a table of exactly that many entries and a span exactly as
wide, through hubs coupled to shared cells where the other numbers allow it (where a
declared table or the couplings do not take that span, the widest under it they do);
and a schedule of exactly that many sweeps;
- for the battery (§7.2), where `C` is past 24: `C` alike cells, every cell read in
blocks of three (the last block ending at the last cell), and, where `C` is not one
less than a power of two, as many alike cells as the largest such count under it
from 31 to 1,023, every cell read, so that a last, partial warp or workgroup holds as
many as it can; at declared couplings, alike triangles, every one read; at a declared
schedule length, one alike triangle warm and then cold, to 1,024 sweeps; at a
declared field bound, field and cost, three alike cells at it, and the field bound
through couplings; at a declared span, its two hubs where they hold no other cell.
Identical blocks cannot reach a table, so a table has none.
The rules bound what certification costs, whatever the capacity: at most 300 generated
vectors, at most 450 million cell sweeps hot or settled, and at most 20 million at
temperature 0 (the run past `2²⁴`, at a fixed point, which the reference skips). With no
capacity they come to about 262 million cell sweeps, two fifths of them battery
workloads, which run only for a kernel that is not `bit-exact`; the most, for a
capacity of 4,096 cells that declares every other number below what a job can reach, is
about 430 million, half of them battery workloads. A test holds the bounds over the
named capacities and over random ones, and prints each one's share.
- `jobs`: whole requests and what their answers hold, refusals included: every worked
example at seed 1, and requests that pin a rule each (a `minimize` above temperature 0,
a temperature given as text, a pin's size, quantised weights, the state a two-cycle
reports, a settle's digest, leading zeros, and refusals of a `+` sign, an exponent in a
temperature, a byte-order mark, a no-break space, no steps, too many starts, the most
negative whole number, a weight too small and a pin too large). A host that claims this
protocol on the reference's kernels MUST give exactly these.
### 7.2. The battery
A sampling kernel with draws of its own is held to `statistical`: workloads of two to six
cells, and one of eight blocks of three side by side, none coupled to another, each with
a schedule. A member may decline a workload of the battery only where §5 lets it decline
a vector, and it then passes that workload without running it. A workload of many blocks
may name the blocks it reads (`read`); only those are counted, so that many tests at once
do not fail a correct sampler by chance. Workload `k` runs `statistical.chains` (20,000) chains, chain `r` with the
chain seed `out(statistical.seed + k, r + 1)` and its start from that seed (§4.2),
through the workload's temperatures. The final states of each `block` of cells are
counted over its `3ⁿ` states, in the order `Σ (s_i + 1)·3ⁱ`, and held to `exact`. Where
`law` is `settled`, that is the Boltzmann distribution at the schedule's last temperature
above 0, reached on a plateau, carried through one deterministic sweep where the schedule
ends at 0. Where it is `walked`, it is the law of the walk itself from the start's
uniform law, every sweep of the schedule cell by cell in order, on a block whose cells
are all alike; there the counts are read over how many cells of the block hold each
state, which any order of the cells leaves the same. The statistic is Pearson's, every
bin expected fewer than `statistical.pool_below` (5) times pooled into one; with `df` the
bins less one, a block passes when it is at most `df + 5·√(2·df)`, and a workload when
every block does.
The workloads a capacity adds (§7.1) are held by a bound that holds whatever the law,
however small its bins, so that they fail a correct sampler, whatever its draws, less
than once in a million between them. They run in calls of 63, 62 and on down to 17 chains
in turn (no more than the member takes), so that their calls end in every partial warp of
more than 16 chains and every partial workgroup of more than 32. Every block is read. A
block's statistic is the likelihood ratio `G = 2 Σ O ln(O/E)` over every
bin, none pooled: `2N` times the divergence of its counts from its law, `N` the chains.
By the method of types, the chance that `N` draws over `k` bins fall at a divergence `t` or
more from their law is at most `C(N + k − 1, k − 1)·e^(−N·t)`, the number of ways `N` draws
can fall in `k` bins times the chance of the likeliest of them. So a block passes when `G`
is at most `2·(ln C(N + k − 1, k − 1) + ln(B/10⁻⁸))`, `B` the blocks the workload reads: a
workload fails a correct sampler with chance at most 10⁻⁸ (for 27 bins and one block,
429.3; for 10 bins, 189.5). A test sums the chance exactly over every way 1,000 draws can
fall in three bins, for laws with bins a pooled chi-square mishandles. A sampler that
leaves a cell unmoved, draws one at random, or leaves a call's last partial warp at its
starts lies far past the bound on the block that holds it: a cell left at its start in a
block of three gives `G` near 12,000 at `N` = 20,000.
The bound is loose, and what it misses is part of the grade. It sits at a divergence of
about 0.011 a block (429.3 over `2N`), so a law near the exact one passes: three alike
cells at field 1 drawn at a temperature 10% too high are 0.0055 from their law, `G` near
250, and pass; 15% too high, `G` near 490, and fail. The battery's cells are the fixed
workloads' (2 to 24), `C` and the largest `2^j − 1` under it: a fault keyed to another
count of cells, such as the lanes past 32 of a partial last workgroup only where it holds
an even count, is never run. A test holds each of these statements. A kernel graded
`statistical` is never audited (§7.3), and every answer from one says what the grade rests
on and what it misses.
The workloads hold pairs of coupled cells next to each other, two apart and three apart,
a triangle no two colours can split, fields to 40 and a cost of 8 at a high temperature, a
small field at a low one, a schedule that ends at 0, one that cools from 6 to 0.7, a ring
of six cells, eight triangles side by side, a triangle pulled one way that is warm
and then cold, whose end alone gives another law, and fields past 16 bits and past 32 at
a temperature of their own size. A kernel that moves two coupled cells
at once in any order of cells, that ignores the schedule or keeps only its end, that
samples the last sweep rather than running it at 0, whose table is wrong for large
fields, that holds its fields in 16 or 32 bits, or that leaves cells from the fifth on
where they started fails at least one of them; the reference's own kernel, one that colours its cells properly, and one that
takes its cells last to first pass every one. A test holds both statements, with
kernels that are wrong in each of those ways.
### 7.3. The audit
A finite set cannot catch every fault, so a `bit-exact` grade rests on a continuous check
as well as on certification, and the check rests only on what the host computes and
remembers. For every answer from a member's kernel graded `bit-exact`, the host runs part
of the job again on the reference and compares the bits:
- sampling: in every job (a run, a replay, a sweep or a comparison), in every call to the
member, the call's last chain and, for each seed's run the call holds chains of, one of
those chains, each drawn afresh: what the host checks in one call says nothing of what
it checks in the next, so a member that times the host between its calls learns
nothing it can use. The host runs a call's checked chains again after the call returns
and before it makes the next: on the job's own thread, at the job's priority, and on as
many of the audit's threads as are free, a quarter of the host's cores and at most 4
over the whole process at once (none on a host of fewer than 4 cores), each at a low
priority (a nice value 10 higher, to 19, on Linux; the background band on macOS). So an
audited job takes at most its own thread and the audit's threads; several audited jobs
at once each run a share on their own threads at their own priority, beside the
audit's threads, and a host that must keep audited jobs from crowding out others lowers
those jobs' own priority. An audit thread whose priority cannot be lowered says so on
standard error, once, and runs its share all the same;
- settling: the reference's settle, as far as a budget of 2²⁴ of work goes, the work
being the cells and couplings times the sweeps the host asked for, never the sweeps the
member reports. Where the reference comes to rest within the budget, or the whole bound
fits it, that is the whole answer, and the member's is compared with it. Past it, the
whole settle is run in one job in 8; in the others a member whose settle ends before
the reference's had is wrong. The checks of §5 hold as before.
The chains, and which settles past the budget are run whole, are drawn with a key the
host makes when it starts, from its operating system's randomness, and a count that
every draw moves on: no member can tell which of its chains are checked, and the same job
sent again is drawn afresh. Every audited answer records what was checked
(`audit.checked`: each run's seed and its chains checked, or how much of a settle). The
draws are the host's, as the rest of its work is: nothing in an answer lets a reader check
afterwards that the chains were drawn and not chosen, and a reader who needs that runs
the job on the reference.
At the first difference, or the first answer the checks refuse, the host demotes the
member to `uncertified` for both kernels, at once. It answers that job from the reference,
naming the member under `refusals` with why, and states the demotion in every later
answer from the member (`member.demoted`) and in its label. A host placing jobs never
places it again. The host keeps the demotion under the member's identity, its id and its
fingerprint (a bitstream's or a firmware's digest, a driver's version: `Member::fingerprint`),
in a file where it names one, so that it outlives the process: certifying the member again,
or its declaring another capacity, does not clear it. Only another identity is certified
afresh. Hosts and jobs may share the file. The host keeps a demotion at once in a file of
its own beside it (`.<name>.demotion.<32 hex digits>.json`, with the file's mode), with no
lock to wait for, and then merges it into the file under the file's lock (the file of its
name with `.lock` added), waited for at most 5 s (`member::STORE_LOCK_WAIT`): written
whole to a file of its own with the file's mode, synced and renamed into place, the
merged files of their own then removed. Where that wait runs out, the demotion stays in
its own file until a later demotion merges it, and is kept all the same: none is lost
and none loses another's. Whenever it certifies a member, the host reads the file and
every demotion in a file of its own afresh, under the lock held shared, and then rewrites
the file as it is, the way a demotion rewrites it: a file of its own as large as the
largest rewrite a demotion can make (the records with the largest entry one can add, a
reason being kept to its first 1,024 bytes), synced, cut back and renamed over the file.
So a folder no longer written to, a full disk, a limit on a file's size, and a file that
cannot be replaced (another user's in a folder with the sticky bit, one marked immutable
or append-only) are each found before a member is graded on the store. Its temporary
files are named for its file alone (`.<name>.<write|probe|demotion>.<process>.<count>.tmp`,
matched exactly, so that no other store's file is taken for one of its own), each held
locked by its writer while it lives; one unchanged for 10 s that no writer holds is a
killed writer's, and the next certification or demotion removes it. Where the path is a
link, the store is the link's target, followed link by link: its lock, its files and its
rename; a link in a folder anyone may write that has the sticky bit is not followed,
whoever made it, and no file of the store's is opened through a link. The store fails
closed. The host says so on its standard error, grades no kernel `bit-exact`, and holds
the member at `uncertified`, saying why in `member.demoted`, where the path names no file
(an empty `WAI_LANDSCAPE_DEMOTIONS` names none, and is as if unset), where it is a link to
nothing or a link in such a folder, where the file has more than one name (a hard link,
which a rewrite would split), where the file or a demotion in a file of its own cannot be
read or does not parse, where the file cannot be rewritten as a demotion rewrites it,
where a write fails, or where a host that keeps one has no file to name. A demotion it
could neither keep in its own file nor merge it keeps for as long as it runs, and says
so. Where the lock is held past 5 s, the certification that waited grades no kernel
`bit-exact` and says why, and the next waits again, so that a board job holds the board
no longer than that waiting on the store.
A kernel graded `statistical` gives draws of its own, which no audit can hold to the
reference's bits. A host placing jobs places it only where the job asks for it
(`"parity": "statistical"`); otherwise it passes over it, saying why, and a job is
answered by a kernel whose bits are audited, or by the reference. Asked for by name, it
is run, and its answer says `statistical`.
Its cost: in every call, its last chain and one chain of each run it holds chains of, so
for a run of `R` chains in calls of `B` at most `2⌈R/B⌉/R` of its sampling work again,
and for a job of many seeds' runs in one call, one chain of each and one more; for a
settle, at most 2²⁴ of work, and past it the whole settle again one job in 8. The bound
is that work. It is work on the host's CPU, which a device outruns, so in wall time the
audit costs more than its share of the work, most where a job is many short runs, and by
how much depends on the host, its load and the device: a host that needs a wall-time
figure measures it on its own hardware (the `timings` test of `landscape_devices` prints
five runs of each of four jobs, audited against the same member run by name).
Ten runs a device on two shared hosts, with the audit's threads as above, give
an idea: a replay of 256 seeds of 8 chains of 64 cells for 500 sweeps took 108% to 171%
longer audited through Metal on an M3 Ultra's GPU, and 85% to 122% through CUDA on an RTX
4050 laptop GPU; a replay of 256 seeds of one chain each, where every chain is checked,
112% to 183% and 90% to 120% longer, so that through Metal it took up to 1.18 times what
the reference alone took; a run of 4,096 chains of 64 cells at most 18% longer, and one of
1,024 chains of 1,024 cells at most 4%. What it catches: a fault that makes a fraction `q`
of a run's chains wrong, on each such run with a chance of at least `q`, whatever chains
it chooses, since it cannot tell which are checked; one that makes the last chain of a
call wrong (a partial last warp or workgroup, a call longer than the member keeps), on
the first job that shows it; one in a settle whose reference comes to rest within the
budget, on the first job that shows it; one that ends a settle at or before the last
sweep the budget reaches while the reference's goes on, on the first such job; and any
other in a settle past the budget, one that ends it later than that sweep and sooner
than the reference among them, only within `N` such jobs, with a chance of
`1 − (7/8)^N` (0.74 at 10 jobs, 0.99 at 35), each job drawn afresh, repeats of one job
included. A draw index narrower than 64 bits, which
certification holds only to `2²⁴` (§7.1), is caught on the first job whose run passes its
width, since every chain of that run is then wrong. The audit is a check that runs as long
as the member does. It is not a proof.
### 7.4. The joint law against exact enumeration (informative)
The battery holds blocks of at most six cells to their law. The sampling kernel's joint law over every state of
larger workloads is held to the exact law in `quantum-conformance/landscape/stage0/`, registered before it was run:
eight landscapes of 10 to 12 cells (3¹⁰ to 3¹² states), ferromagnetic and frustrated, sparse and dense, two of them
of the second version, each at three temperatures. Each sample is the state of its own chain after a number of
sweeps chosen, before anything is sampled, from the exact law of the chain after each sweep; the energies are whole
numbers and the law's rounding is bounded. Total variation over every state, the divergence and Pearson's statistic
over a partition of the states, and the laws of the energy, of the magnetisation with the cells not at 0, and of each
pair of cells, are held to thresholds registered with the models. An ideal sampler drawing from the exact law is held
to the same rule, and so are three kernels that are wrong in ways a port can be: every cell drawn at once from the old
state, a field plus noise thresholded into three levels, and a cell that reads its couplings as a three-colour cell
does. The results and their document (`wai-quantum/docs/landscape-stage0.md`) say which members ran there, and how
each did. None of it is part of a member's grade (§5.1).
## 8. What does not run on this model
The worked examples include each of these, and they fail there, on purpose: problems of three
interchangeable options (colouring a map), where the state 0 is not a third colour; problems
whose sizes matter (two equal piles), where a coupling keeps only a sign; assignment beyond a
2×2 grid written as sums; and a constraint at temperature 0, which flips between two states
and never rests. A host MUST NOT hide these, and a program marked `#! expect fails` MUST fail.
The second version ([quantum-landscape-2](quantum-landscape-2.md)) gives each variable a cost of
its own, of either sign, and with it writes one-hot, at-most-one and cardinality constraints:
colouring with three interchangeable colours and assignment above 2×2 run there, and its worked
examples say how far. Sizes, and a constraint at temperature 0, do not run there either.
## 9. Versioning
The protocol's name carries its version. Within `/1`: fields may be added to an answer, never
removed or given another meaning; the kernels' bits, the replay digest and the conformance
set's `settle`, `chains` and `jobs` do not change. A change to any of those is `/2`, with a
new kernel name. The words of a sentence, the rates of §4.4 and the published table are not part of
the protocol, and a host's `label` is its own.
§5.4 was added within `/1`: its rules state what every host of this text already wrote, so
every answer sealed before it holds them. The members a client adds to an answer from a
provider (`provider`, `job`, `cost`, quantum-providers §11.3) were added the same way.
**The conformance set did not keep the rule above, and is frozen now.** The file
`quantum-conformance/landscape/vectors.json` changed three times after it was first published,
on 2026-11-06 (commit `f7078696d`, sha256 `d3bac819…`). No expected state, sweep count, ending,
accumulate count, draw count, energy, verdict or replay digest of a vector already in it changed;
but entries changed their form, gained expected fields, and were added, so a member certified on
an earlier set was held to less:
| when | commit | what changed in the set | why | sha256 after |
|---|---|---|---|---|
| 2026-11-06 | `eb0db8895` | every entry's workload grouped under `landscape`, each job's program and seed under `request`; a chain's `term` and a job's `mode`, `restarts` and `sweeps` added to what is expected; the six chains renamed with their sweeps; the eight cell frequencies and the two coupled-cell frequencies replaced by 650 cut points and a rewritten battery; `exp` and `schedule` added; 3 settle vectors, 9 chains vectors and 17 jobs added | the engine's review of the first version: bound every quantity a job can ask for, and pin every rule a reader must follow | `43e543a6…` |
| 2026-11-06 | `0675813de` | every settle and chains entry gained its `field_bound`; 14 settle vectors, 24 chains vectors, the `draws` part and battery workloads added | the review of the GPU members: reach what large jobs reach, past a workgroup, a batch of sweeps and the widths of a lane | `b5286374…` |
| 2026-11-09 | `c0ba8a0ce` | 2 chains vectors added: a long schedule across windows and a schedule across a window by work | declared capacity: the core set and its floor needed the long schedule | `1da13d25…` |
The FPGA board was certified on hardware against the set of `eb0db8895` (`43e543a6…`), before
the later two; its member is certified on the model against the set as it stands, and its grade
names that set. From 2026-11-10 the set is frozen as it stood on main that day (sha256
`1da13d2570eb5b1367d3017b465e1b6a199429210def0c4300dbc403413e3a8e`): the code pins its BLAKE3
digest (`conformance2::VECTORS_1_BLAKE3`), a test fails on any difference, and a change of any
kind to it, an entry changed, removed or added, is a new version of the protocol, as the second
version's set is held (quantum-landscape-2 §7).
## Appendix A. The exponential
The exponential of §4.2, as the reference computes it, with every operation a double
rounded to the nearest and no operation fused. With `ln2_hi = 6.93147180369123816490e-1`,
`ln2_lo = 1.90821492927058770002e-10`, `inv_ln2 = 1.44269504088896338700`, and
`P1 … P5 = 1.66666666666666019037e-1, −2.77777777770155933842e-3,
6.61375632143793436117e-5, −1.65339022054652515390e-6, 4.13813679705723846039e-8`:
1. A NaN is returned as it is; `x > 709.782712893383973096` gives +∞, and
`x < −745.133219101941108420` gives 0.
2. If `|x| > ½·ln 2` (`ln 2` the double nearest it): `k = ±1` when `|x| < 1.5·ln 2`, with
the sign of `x`, and otherwise `k = trunc(inv_ln2·x + (x < 0 ? −0.5 : 0.5))`; then
`hi = x − k·ln2_hi`, `lo = k·ln2_lo`. If `|x| < 2⁻²⁸`, the result is `1 + x`.
Otherwise `hi = x`, `lo = 0`, `k = 0`.
3. `r = hi − lo`, `t = r·r`, `c = r − t·(P1 + t·(P2 + t·(P3 + t·(P4 + t·P5))))`.
4. If `k = 0`, the result is `1 − ((r·c)/(c − 2) − r)`. Otherwise
`y = 1 − ((lo − (r·c)/(2 − c)) − hi)`, and the result is `y·2ᵏ`: computed as
`y·2¹⁰²³·2^(k−1023)` when `k > 1023`, as `y·2^(k+1000)·2⁻¹⁰⁰⁰` when `k < −1021`, and as
`y·2ᵏ` otherwise, each power of two exact.
The conformance set's `exp` part holds its values.