Some checks failed
WAI operation catalogue / does this change touch it (push) Successful in 22s
wai-quantum clippy / does this change touch it (push) Successful in 26s
wai-quantum command line / does this change touch it (push) Successful in 35s
wai-quantum contract / does this change touch it (push) Successful in 21s
wai-quantum docs, course and locales / does this change touch it (push) Successful in 22s
wai-quantum for JavaScript / does this change touch it (push) Successful in 20s
wai-quantum resource estimation / does this change touch it (push) Successful in 24s
wai-quantum other formats / does this change touch it (push) Successful in 26s
wai-quantum OpenQASM reader / does this change touch it (push) Successful in 17s
wai-quantum for Python / does this change touch it (push) Successful in 16s
wai-quantum extension points / does this change touch it (push) Successful in 19s
wai-quantum error correction and mitigation / does this change touch it (push) Successful in 23s
wai-quantum pulse and dynamics / does this change touch it (push) Successful in 22s
wai-audit collector and player integration / does this change touch it (push) Successful in 3m29s
wai-quantum editors / does this change touch it (push) Successful in 2m26s
wai-quantum variational and algorithm library / does this change touch it (push) Successful in 25s
wai-quantum verdicts and repairs / does this change touch it (push) Successful in 23s
wai-quantum studio and desktop / does this change touch it (push) Successful in 29s
wai-quantum service / does this change touch it (push) Successful in 30s
wai-sink-android native sink library / does this change touch it (push) Successful in 1m24s
wai-sink-swift native sink package / does this change touch it (push) Successful in 1m22s
wai-quantum views in agent hosts / does this change touch it (push) Successful in 1m25s
WAI Studio / does this change touch it (push) Successful in 1m18s
wai-quantum service / service energy · linux packages (push) Failing after 11s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 10s
WAI examples / WAI examples · does this change touch them (push) Successful in 15s
wai-quantum wasmQ / does this change touch it (push) Successful in 10s
wai-quantum contract / the policy is linked, and the deprecations page reads (push) Successful in 11s
wai-quantum docs, course and locales / the Studio's words in every locale · linux (push) Successful in 13s
WAI operation catalogue / the catalogue and every door · linux (push) Failing after 3m52s
wai-quantum other formats / the set under wasm32-wasip2 (wasmtime) (push) Successful in 2m17s
wai-quantum clippy / clippy, warnings denied, every feature set · linux (push) Successful in 5m4s
wai-quantum OpenQASM reader / corpus under wasm32-wasip2 (wasmtime) (push) Successful in 1m8s
wai-quantum extension points / the registry under wasm32-wasip2 (wasmtime) (push) Successful in 3m6s
wai-quantum docs, course and locales / the course and the command line's languages · linux (push) Successful in 7m43s
wai-quantum OpenQASM reader / reader and corpus · linux (push) Successful in 6m9s
wai-quantum other formats / readers, writers and the set · linux (push) Successful in 8m22s
wai-quantum for Python / python · linux (push) Successful in 6m17s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs · linux, release (push) Successful in 2m29s
wai-quantum contract / API compatibility · linux (push) Successful in 10m27s
wai-quantum extension points / the registry and the example · linux (push) Successful in 6m39s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs under wasm32-wasip2 (wasmtime) (push) Successful in 2m24s
wai-quantum error correction and mitigation / codes, decoders, texts and mitigation · linux, release (push) Successful in 6m12s
wai-quantum for JavaScript / javascript · linux (push) Successful in 11m28s
wai-quantum resource estimation / estimation and calibration · linux, release (push) Successful in 13m21s
wai-audit collector and player integration / collector · linux (push) Successful in 2m48s
wai-quantum verdicts and repairs / the intent set and the verdict under wasm32-wasip2 (wasmtime) (push) Successful in 3m2s
wai-quantum editors / editors · linux (push) Successful in 4m20s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 59s
wai-quantum contract / schemas and the committed tool lists · linux (push) Successful in 16m11s
wai-quantum verdicts and repairs / verdicts, repairs and the intent set · linux (push) Successful in 4m46s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux, release (push) Successful in 4m5s
wai-quantum studio and desktop / studio · browser (push) Successful in 6m49s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 8m20s
wai-quantum service / service · linux (push) Successful in 11m47s
wai-quantum views in agent hosts / views · the page and its engine (push) Successful in 9m50s
wai-quantum views in agent hosts / views · a scripted host (push) Successful in 11m14s
wai-quantum command line / command line · linux (push) Successful in 26m22s
WAI Studio / Studio in WebKit · linux (push) Failing after 23m36s
wai-quantum docs, course and locales / every command and snippet in the docs · linux (push) Failing after 1h5m32s
wai-quantum extension points / the registry and the example · linux-arm64 (push) Successful in 7m19s
wai-quantum pulse and dynamics / the same bits · linux-arm64 (push) Successful in 7m28s
wai-quantum pulse and dynamics / the same bits · macos (push) Successful in 1m37s
wai-quantum for Python / python · macos (push) Successful in 4m24s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Failing after 18m39s
wai-quantum command line / command line · macos (push) Successful in 5m9s
wai-quantum editors / editors · macos (push) Successful in 1m52s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 3m45s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux-arm64, release (push) Successful in 6m53s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 4m16s
wai-quantum service / service · macos (push) Successful in 9m30s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 14m42s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 9m55s
WAI Studio / Studio in Chromium and Firefox · macos (push) Failing after 11m30s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Failing after 45m47s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · linux (push) Has been cancelled
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · macos (push) Has been cancelled
wai-quantum wasmQ / the reference modules rebuild to their modules of record · linux (push) Has been cancelled
wai-quantum wasmQ / interpreter and vectors under wasm32-wasip2 (wasmtime) (push) Has been cancelled
wai-quantum studio and desktop / desktop app · windows (push) Has been cancelled
WAI examples / WAI examples · portable · linux (push) Has been cancelled
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (push) Has been cancelled
WAI examples / WAI examples · android-app · linux-arm64 (push) Has been cancelled
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Has been cancelled
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Has been cancelled
A processor that takes rx(θ) and rzz(θ) runs an angle between two qubits in one two-qubit gate where rz sx x cz takes two cz. - quantum_toolchain::native::Basis::RzSxXCzRxRzz (label rzsxxczrxrzz): a controlled phase, a run of them on one pair, and cx·p(θ)·cx with only Z rotations between are each one rzz; h·p(θ)·h is one rx, ry one rx between frames; rx(π/2) and rx(π) are sx and x. rzz is held to 0 < θ ≤ π/2, the range the service publishes, an angle outside folded in by Z⊗Z and an X on either side; the check before sending refuses an rzz of no turn or past a quarter turn and an rx with a phase. A three-qubit Fourier transform takes three rzz where rz sx x cz takes six cz. - Proved by the engine's equivalence check (controlled phases each side of zero and past a quarter turn, the folds, rotations between qubits, X and Y rotations, the transform, random programs, none with more two-qubit gates than in rz sx x cz); six native vectors pinned and proved, four refusals. - layout::native_in and place_in place a program in the basis its device's client compiles to; on a target of rz sx x cz rx rzz, rx and rzz are costed as themselves. native_of still reads such a target as rz sx x cz. - sampler-v2 compiles to it with the setting basis=rzsxxczrxrzz, only where basis_gates list rx and rzz, on pairs both maps list; tested against the fake built from the service's own answers, which holds every rzz to the published range. The protocol (§4, §8.4) carries the set as a built-in client's: no description is compiled to it, so no provider is sent one; both verifiers read it in compiled.basis. - The pin, by values: the backend's snapshot was dated anew three times in three and a half hours on 2026-11-12 with no value a placement reads changed (only thresholds and initialisation errors), so a date comparison would refuse nearly every job that waits. The placement now names the hash of the values it read (Target::values_hash), the client states the values in force when the job began running (Stated::ran_under), and a job whose values differ is refused, in the sending process and in a collecting one. Workflow pins: the two engine tests in the registry workflow, the sampler-v2 binary's count (10) and its new test in the qpu workflow. Co-Authored-By: Claude Opus 5.5 <[email protected]>
363 lines
20 KiB
Markdown
363 lines
20 KiB
Markdown
# Bring your own quantum
|
||
|
||
WAI gives you the engine, the free job service and the verifier at no cost.
|
||
It does not sell time on anyone's hardware, and it never pays for yours. You
|
||
bring your own quantum hardware: a device on your bench, an on-premises
|
||
system, an account with a provider, or a simulator you trust. Every surface
|
||
then treats a run on it as it treats a WAI run:
|
||
|
||
- it is **planned**: the circuit is compiled exactly to the device's own gates
|
||
and connectivity, and the compiled program is checked against the circuit by
|
||
simulation before anything is sent;
|
||
- its **cost is shown before it is submitted**, and a run that is not free
|
||
(or whose cost is unknown) runs only when you confirm it;
|
||
- its counts are **sealed in a receipt** with your key, which the existing
|
||
verifier checks.
|
||
|
||
Your credentials stay with you, in the operating system's keychain. They never
|
||
go to a browser page, a log, a receipt, or the hosted service.
|
||
|
||
## What is free
|
||
|
||
```sh runnable
|
||
wai-quantum providers free
|
||
```
|
||
|
||
lists what anyone can use at no cost:
|
||
|
||
- the engine's own methods on your machine, each with the most qubits it holds
|
||
in a job's memory;
|
||
- the free job service, `https://wai.transaction.science/quantum-jobs`, with no
|
||
account (its limits are per client; `GET …/v1` states them);
|
||
- each of your providers whose own description states free use, with the
|
||
limits it states. No provider is named in WAI's code: a provider says what
|
||
it offers, about itself.
|
||
|
||
## Adding a provider
|
||
|
||
A provider is one of six kinds:
|
||
|
||
| kind | what it is | the credential |
|
||
|---|---|---|
|
||
| `http` | any provider of the [open provider protocol](../extensions/quantum-providers.md) at an HTTPS URL | `Authorization: Bearer` |
|
||
| `process` | any program on your machine that speaks the protocol on its standard input and output | its environment (`WAI_PROVIDER_CREDENTIAL`) |
|
||
| `sampler-v2` | a Sampler V2 job service (OpenQASM 3 on physical qubits, rz sx x cz) | an API key, exchanged for a bearer token |
|
||
| `prx-circuits` | a circuit service of phased-X and CZ instructions, star devices (qubits round a computational resonator, reached by `move`) among them | the token you generate in the service's dashboard |
|
||
| `native-turns` | a native-gate service with angles in turns (gpi gpi2 zz, or gpi gpi2 ms where the backend, or its noise model's device, runs only ms) | an API key |
|
||
| `cloud-tasks` | a cloud service of quantum tasks, on your own account, its results in your own storage bucket | your account's keys, `id:secret` or `id:secret:token`, or its usual environment variables |
|
||
|
||
```sh runnable
|
||
# A program of your own, or the reference provider, on this machine:
|
||
wai-quantum providers add lab --kind process -- wai-quantum providers reference --stdio
|
||
|
||
# A provider at a URL, its credential read from standard input into the keychain:
|
||
wai-quantum providers add cloud --kind http --endpoint https://quantum.example/provider --credential-stdin < token.txt
|
||
|
||
# A built-in protocol, its settings beside it, its credential in the keychain:
|
||
wai-quantum providers add mine --kind sampler-v2 --set crn=… --set backend=… --credential-stdin < key.txt
|
||
|
||
# A cloud service of tasks: a device by its name there, your own results bucket and your own keys:
|
||
wai-quantum providers add tasks --kind cloud-tasks --set region=us-east-1 --set device=… --set bucket=your-results-bucket --credential-stdin < keys.txt
|
||
|
||
# Or a credential read from an environment variable whenever it is used, kept nowhere:
|
||
wai-quantum providers add turns --kind native-turns --set backend=simulator --credential-env MY_TURNS_KEY
|
||
```
|
||
|
||
A credential is never given on a command line (where other users of the
|
||
machine could read it). `--credential-stdin` keeps it:
|
||
|
||
- on macOS, in the keychain, through the system `security` tool;
|
||
- on Linux, in the desktop secret service, through `secret-tool`, when it is
|
||
installed and answers;
|
||
- elsewhere (Linux with no secret service, Windows), in a file only you can
|
||
read (`~/.config/wai/quantum-provider-credentials/NAME`, mode 0600), and
|
||
every listing says so. `WAI_QUANTUM_CREDENTIALS=file` chooses the file;
|
||
`WAI_QUANTUM_CREDENTIALS=keychain` accepts nothing but the keychain.
|
||
|
||
The list itself (`~/.config/wai/quantum-providers.json`, or the file
|
||
`$WAI_QUANTUM_PROVIDERS` names) holds no credential: only each provider's
|
||
kind, endpoint or command, non-secret settings, and where its credential is.
|
||
A setting whose name looks like a credential (`token`, `key`, `secret`, …) is
|
||
refused. The built-in kinds still read their environment variables
|
||
(`WAI_QPU_SAMPLER_API_KEY` and the rest, in the [README](README.md)) when no
|
||
credential is kept for them.
|
||
|
||
```sh runnable
|
||
wai-quantum providers list # each provider, and where its credential is
|
||
wai-quantum providers describe lab # its qubits, gates, connectivity, calibration and prices
|
||
wai-quantum providers test lab # the protocol's conformance vectors; jobs only when free, or with --yes
|
||
wai-quantum providers remove turns # and the credential kept for it
|
||
```
|
||
|
||
## Running on it
|
||
|
||
```sh runnable
|
||
wai-quantum run bell.qasm --provider lab --dry-run # the plan, the check and the estimate; nothing sent
|
||
wai-quantum run bell.qasm --provider lab # free: it runs
|
||
```
|
||
|
||
On a provider that charges (here `cloud`, reached with your own account):
|
||
|
||
```sh norun=account
|
||
wai-quantum run bell.qasm --provider cloud # not free: refused, with the estimate (exit 3)
|
||
wai-quantum run bell.qasm --provider cloud --yes # you confirmed it: it runs
|
||
wai-quantum run bell.qasm --provider cloud --json > job.json && wai-quantum verify job.json
|
||
```
|
||
|
||
A run on a provider asks for counts (`--shots`, 1024 by default) of a program
|
||
whose measurements all come at the end and whose every angle is a dyadic
|
||
multiple of 2π (`pi/4`, `3*pi/8`, …), so it compiles exactly. A job that asks
|
||
for expectation values, amplitudes, a noise model or one of the engine's
|
||
methods is refused; those are the engine's.
|
||
|
||
An agent has the same through `wai-quantum mcp`:
|
||
|
||
- `providers_list` lists your providers (and, with `free: true`, what is free);
|
||
- `provider_estimate` is the dry run;
|
||
- `run_on_provider` runs, and says in its description that it can spend your
|
||
money. It refuses a run that is not free unless `confirm_cost: true`, which
|
||
an agent sets only after you have seen the estimate and agreed.
|
||
|
||
The desktop app lists your providers under **Your hardware**, asks for the
|
||
estimate first, and shows a dialog before a run that is not free. The
|
||
browser Studio cannot: a browser tab must not hold a credential, so there the
|
||
switch says that such runs go through the desktop app or the command line.
|
||
The hosted job service never routes a job to a provider and never takes a
|
||
credential; a request that names a provider is refused there.
|
||
|
||
## When the queue is long
|
||
|
||
A device's queue can take days, and nothing has to stay running for it. A job
|
||
is written down before it is sent, in `provider-jobs` beside your registry
|
||
(readable only by you, with no credential in it), and the provider's id beside
|
||
that as soon as the provider gives one.
|
||
|
||
```sh norun=account
|
||
wai-quantum run bell.qasm --provider lab --no-wait # sends it, and answers with its handle
|
||
wai-quantum providers jobs # every job recorded here, and where it last stood
|
||
wai-quantum providers collect pj-0123456789abcdef # asks, and seals its result when it has one
|
||
wai-quantum providers cancel pj-0123456789abcdef
|
||
```
|
||
|
||
A plain `run` waits two hours and then stops waiting, with the job left at the
|
||
provider and its handle on the screen. Only your asking cancels a job. If the
|
||
command, the terminal or the machine stops, the job goes on, and `collect`
|
||
picks it up: exit 0 done, 1 ended otherwise, 2 still at the provider, 75 could
|
||
not ask, which says nothing of the job. An agent has the same in
|
||
`get_provider_job`, `cancel_provider_job` and `list_provider_jobs`, and the job
|
||
from `run_on_provider` is the same job.
|
||
|
||
The counts are read against the program that was sent, and the receipt states
|
||
that program and what the provider said when it was sent, whatever its
|
||
calibration has become since. A request that did not complete may have reached
|
||
the provider, so it is never sent again, since that could be a second bill: the
|
||
record says so, and you look in the provider's own list. A provider you run as
|
||
a local process has to keep its jobs itself, or they end with it.
|
||
|
||
## The protocol, and the reference as your template
|
||
|
||
The [open provider protocol](../extensions/quantum-providers.md) is six
|
||
operations as JSON messages, over HTTP or a local process: `describe`
|
||
(native gates, connectivity, qubits, durations, a calibration snapshot id with
|
||
optional per-qubit and per-pair errors, and the billing: `free`, a unit and
|
||
its price, or not free with no price set, so that a job's cost is unknown and
|
||
it runs only when you confirm it), `estimate`, `submit`, `status`, `result`
|
||
(counts keyed by classical bits) and `cancel`. A program travels in your
|
||
device's own gates, every angle an exact fraction of a turn, with the same
|
||
program as OpenQASM 3 beside it.
|
||
|
||
The reference provider is the protocol around WAI's exact simulator:
|
||
|
||
```sh runnable
|
||
wai-quantum providers reference --stdio # on standard input and output
|
||
wai-quantum providers reference --help-args # its device: qubits, basis, connectivity, a price, a readout error
|
||
```
|
||
|
||
```sh norun=server
|
||
wai-quantum providers reference --http 127.0.0.1:8090 # over HTTP, until stopped
|
||
```
|
||
|
||
To bring a device, copy [`src/reference.rs`](src/reference.rs): keep the
|
||
message handling, the checks of a program against the device, and the two
|
||
servers, and replace `Reference::simulate` with your device's run (and
|
||
`describe` with your device's description). Then hold it to the vectors:
|
||
|
||
```sh norun=account
|
||
wai-quantum providers add mine --kind process -- ./my-provider --stdio # your own provider's program
|
||
wai-quantum providers test mine
|
||
```
|
||
|
||
A device whose gates are a phased `X` rotation, a `Z` rotation and `XX(θ)`,
|
||
reached through a service with an interface of its own (its angles in units of
|
||
π, say), is brought the same way. Its provider describes `"native_gates":
|
||
["prx", "rz", "xx"]` and is sent programs in `prxrzxx`, which it writes in the
|
||
service's terms: `prx(t, p)` as the rotation by 2t and the phase 2p in units
|
||
of π (0 to 1, and 0 to 2), `rz(t)` as 2t (less 2 past 1, where the service
|
||
takes −1 to 1), and `xx(t)`, which is exp(−iπt·X⊗X), as 2t (0 to ½: every
|
||
`cz` arrives as `xx(¼)`, so ½). Each angle is a dyadic fraction and stays
|
||
exact as a number of that form. The provider turns off whatever the service
|
||
would compile, remap or mitigate, and says what it sent in the answer's
|
||
`execution`; and where the service deletes a result a day after it is read, it
|
||
keeps each result as it reads it. A sign or a unit wrong in its `xx` leaves the
|
||
probe's counts as they are: run a circuit whose outcome turns on the entangling
|
||
gate's phase, as the certification's do, before trusting other results. A star
|
||
device describes its `resonators` and the `moves` into them, and is sent
|
||
`move` in `prxcz` or `rzsxxcz`.
|
||
|
||
The first job on a new provider is the probe, an `X` on qubit 0 whose counts
|
||
must all land on `…01`. It settles the bit order before any other result is
|
||
trusted.
|
||
|
||
## Programs that call WebAssembly between gates
|
||
|
||
A wasmQ envelope ([quantum-wasmq](../extensions/quantum-wasmq.md)) calls its WebAssembly
|
||
modules between gates: a decoder between a syndrome and its correction, a planner between
|
||
loading atoms and moving them. A provider's program is a fixed sequence of native gates
|
||
measured at the end, so it cannot carry that, and `run ENVELOPE.wai --provider NAME` is
|
||
refused; the envelope runs on this machine, its quantum part simulated. Nothing about
|
||
bringing your own quantum changes for it. What a hardware run of such a program would
|
||
need, and what replays from its record, is §7 of that extension.
|
||
|
||
## What the receipt proves, and what it does not
|
||
|
||
A processor's result is labelled `measured`. A result from a provider's
|
||
simulator or emulator is labelled `simulated`, since no device measured it,
|
||
and `approximate` too when the provider says its simulator is. Its receipt
|
||
binds the request, the provider's name, kind and protocol, the device and its
|
||
provenance, the hash of the provider's own description, the calibration
|
||
snapshot, the compiled program's text and its hash, the counts, the cost (the
|
||
estimate, the charge, and whether you confirmed it), and the counts set beside
|
||
the circuit's exact distribution with the distance between them.
|
||
|
||
It also says two things a later receipt could not add:
|
||
|
||
- **Where the counts come from** (`counts_source`): tallied from the device's
|
||
records, one a shot (`shots`); the provider's own counts (`vendor_counts`);
|
||
or rebuilt from probabilities (`probabilities`). Rebuilt counts are derived,
|
||
not shot records. `native-turns` reads its job's shot records where the
|
||
service lists them (as a noisy simulation does), else the service's own
|
||
counts, and rebuilds them only from probabilities, as on an ideal
|
||
simulator; it holds every form the job lists to the others, and the shots
|
||
the service flags as leaked are counted as read, and their number sealed
|
||
beside them (`leakage`). A result the service narrows to the qubits up to
|
||
the last its gates touch is read with the qubits above it 0. A job the
|
||
service finished whose result does not read (keys of no form it writes,
|
||
forms that disagree, or a width it does not write) ends `failed`, with the
|
||
reason, and is not asked again. `cloud-tasks` reads a task's rows and rebuilds only when its
|
||
result has none.
|
||
- **What was set at the provider** (`execution`), built from the very request
|
||
the client sends: each of mitigation, twirling, dynamical decoupling,
|
||
remapping and optimisation as `off`, `on`, or `default` when the request sets
|
||
nothing for it, and whether the gates were to run as written. `sampler-v2`
|
||
turns decoupling and twirling off; `native-turns` turns debiasing off, and
|
||
sends its simulator, under a device's noise model, the job's seed, so a
|
||
noisy simulation is the same at each run of that seed, and its note ends
|
||
with what the service says it compiled (precision, gate basis, version) and
|
||
whether the circuit it lists as compiled is the one sent;
|
||
`cloud-tasks` puts a processor's gates in the service's verbatim box;
|
||
`prx-circuits` pins the job to the calibration set it was compiled against
|
||
and sends dynamical decoupling disabled, with the service's other modes as it
|
||
wants them. A provider of the open protocol states its own (§5.5 of the
|
||
protocol), and a wrapper around another service must.
|
||
|
||
`wai-quantum verify` checks the seal and every rule a receipt keeps, and names
|
||
each one it breaks (the protocol's §8.4); `--json` gives the verdict as data.
|
||
|
||
It proves that your key signed this result for this request: what it says
|
||
your host received from the provider and device it names, sent and checked
|
||
is your host's word, and the counts are the provider's. It does not prove
|
||
that the device ran that program, or ran anything. The counts are not
|
||
reproducible by recomputation; the same job run again gives other counts. The
|
||
distance from the exact distribution tells you how far they are from what the
|
||
circuit gives: a distance well above what the shots alone leave is the
|
||
device's or the simulator's error, or a program not run as sent.
|
||
|
||
A receipt seals the provider's id for the job. For `cloud-tasks` that is the
|
||
task's identifier, which names your account's number: sharing the receipt
|
||
shares it.
|
||
|
||
## A first run on a phased-X circuit service's mock quantum computer
|
||
|
||
A `prx-circuits` service may list, beside each quantum computer, a mock of it:
|
||
the same name with `:mock` after it, a server with no quantum hardware that
|
||
answers random bits. It checks the whole wire (your token, the device's
|
||
description, the job, the cancel, the counts) before any processor runs
|
||
anything. Its results are sealed as `simulated`, never as `measured`.
|
||
|
||
1. In the service's dashboard, generate your token. Generating it again makes
|
||
the old one stop working.
|
||
2. Keep it where `wai-quantum` keeps every credential, read from standard input
|
||
(paste it, then press Ctrl-D), never from the command line:
|
||
|
||
```sh norun=account
|
||
wai-quantum providers add mock --kind prx-circuits --set qc=NAME:mock --credential-stdin
|
||
```
|
||
|
||
On macOS that is the keychain: an item whose service is
|
||
`wai-quantum-provider` and whose account is the provider's name, here
|
||
`mock`. On Linux it is the desktop secret service, and elsewhere a file only
|
||
you can read; `wai-quantum providers list` says which. A token you keep
|
||
already, under another item of the keychain, goes over without being shown:
|
||
|
||
```sh norun=account
|
||
security find-generic-password -s YOUR-ITEM -w | wai-quantum providers add mock --kind prx-circuits --set qc=NAME:mock --credential-stdin
|
||
```
|
||
|
||
`WAI_QPU_PRX_TOKEN` is read instead when a provider names no credential.
|
||
3. Read the device, its calibration and its errors, with nothing sent:
|
||
|
||
```sh norun=account
|
||
wai-quantum providers describe mock # qubits, gates, pairs, and the calibration set it is under
|
||
wai-quantum providers test mock # the device and its calibration's errors; the programs only with --yes
|
||
wai-quantum targets import --provider mock --name mock # the calibration's quality metrics, kept as a target
|
||
wai-quantum run probe.qasm --provider mock --dry-run # the compile, the placement, the calibration it is pinned to
|
||
```
|
||
|
||
4. Run the probe, then the conformance programs. The service sets no price
|
||
through its interface, so each is confirmed with `--yes`; look at your
|
||
account's usage before and after to see what the mock cost:
|
||
|
||
```sh norun=account
|
||
wai-quantum run probe.qasm --provider mock --yes --json > probe.json && wai-quantum verify probe.json
|
||
wai-quantum providers test mock --yes
|
||
```
|
||
|
||
Each job is sent pinned to the calibration set the device was read under, so
|
||
the receipt's `calibration` is the set the service says it compiled the job
|
||
against, and a run is refused rather than sealed when the service says it
|
||
compiled against another. If the service recalibrated and no longer runs the
|
||
pinned set, it fails the job (calibration set not found), its record stating no
|
||
billed time, and the next run reads the current one. A
|
||
service that publishes no quality metrics for its calibration leaves the
|
||
compiler's own layout, and the plan's `placement` says so.
|
||
|
||
A `sampler-v2` backend's calibration is its published properties, read after
|
||
the device and named by their `last_update_date`: the job is placed by them,
|
||
and once it has run the client reads the properties in force when it began
|
||
running, so a job that ran under another calibration than the one it was
|
||
placed by is refused rather than sealed. On a free plan the estimate says how
|
||
many seconds of the plan's limit are left, and the receipt seals what the job
|
||
was charged, in `qpu-seconds`.
|
||
|
||
## Connecting a real device: what is yours to do
|
||
|
||
WAI ships no account and no key. To run on a real device:
|
||
|
||
1. Open an account with the provider, or set up your own device, and accept
|
||
its terms. Any price, quota or free tier is between you and the provider.
|
||
2. Mint a credential (an API key or a token) in the provider's own console.
|
||
3. Add it: `wai-quantum providers add NAME --kind … --credential-stdin`, with
|
||
the settings its kind takes (`crn` and `backend` for `sampler-v2`, and
|
||
`basis=rzsxxczrxrzz` to compile to its `rx` and `rzz` too where the backend
|
||
lists them; `qc` for
|
||
`prx-circuits`, `backend` for `native-turns`, `region`, `device` and `bucket`
|
||
for `cloud-tasks`), or `--kind http` for a provider of the open protocol.
|
||
For `cloud-tasks`, first turn the service on in your account. The bucket must
|
||
be in the device's region, its name must begin `amazon-braket-`, and its policy must let the service write to it. A name with a dot works: it is read by path. A region or a bucket that is not a name is refused when the provider is added, and this kind takes no `--endpoint`. <!-- allow-name: the prefix the service requires of a results bucket -->
|
||
On one of its simulators, `--set basis=gpizz` (or `prxcz`, or `prxrzxx` for a processor of `prx`, `xx` and `rz`) compiles to that processor basis, so you can check the gates before paying for the processor.
|
||
4. Run `wai-quantum providers describe NAME`, then `wai-quantum run
|
||
probe.qasm --provider NAME --dry-run` to see the compile and the estimate,
|
||
then the probe itself, confirmed with `--yes` if it is not free.
|
||
|
||
Nothing in WAI's tests spends money: they run against the reference provider,
|
||
whose price, when it has one, is a number in its configuration.
|