From a0bd65d6af22433d9edc01ce76efb47fb77a2949 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Fri, 30 Oct 2026 11:37:36 -0400 Subject: [PATCH 1/7] wai-quantum: the state vector placed on the fabric's members, and split over several A job's new `fabric` says where the statevector method's state runs: auto (the default), cpu, accelerator, a member's id or key, or a list of members (a power of two), the state split by its top qubits into one partition on each. The CUDA, HIP and OpenCL members' f64 state vectors are discovered once per process and certified against the CPU on the pinned corpus; only a member certified bit-exact is placed, so a placed job's answers are the CPU's byte for byte. A placement the host cannot honour is refused (J013), never made elsewhere. With no member asked for and none placed, the plan and the result are what they always were: the existing pins hold. The partitioned run (sv64::run_split) runs the launches the CPU plans on each partition's amplitudes; a gate on a partition qubit first has that qubit exchanged with a local one through the host's copy. Ground truth first: CPU partitions equal the CPU's state vector bit for bit over the pinned corpus at every partition count and on wide states with exchanges. On the fleet, one state split four ways over a laptop GPU (by two backends), the CPU by OpenCL and the CPU reference gives the CPU's answers byte for byte, as does the integrated GPU by HIP beside OpenCL. The result carries `fabric` (member, parity tier, certificate digest, corpus, energy unmetered with the reason), sealed by the job's receipt, and its provenance names the members: optional members of the job request, job result and provenance schemas, and fabric_members in the tools schema. Surfaces: `wai-quantum run --fabric` and `wai-quantum fabric`, the CLI's cuda, hip and opencl features, `fabric` in both MCP servers' job tools and `list_fabric` on the command line's, the service reading it. Members gain run_launches and max_qubits. Hardware legs in the CUDA and HIP workflows, absent legs and the CPU-partition tests by name in containers. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/wai-quantum-cuda.yml | 58 +- .github/workflows/wai-quantum-hip.yml | 29 +- wai/CHANGELOG.md | 34 + wai/wai-quantum-cli/Cargo.lock | 121 +- wai/wai-quantum-cli/Cargo.toml | 5 + wai/wai-quantum-cli/README.md | 9 + wai/wai-quantum-cli/README.zh-CN.md | 9 + wai/wai-quantum-cli/docs/llms-full.txt | 1346 +------ wai/wai-quantum-cli/docs/llms.txt | 1 + wai/wai-quantum-cli/docs/local-mcp.json | 2605 ++++++++++++- wai/wai-quantum-cli/docs/service-mcp.json | 3218 ++++++++++++++++- wai/wai-quantum-cli/locales/zh-CN.json | 1 + .../skills/wai-quantum/reference/tools.md | 1 + wai/wai-quantum-cli/src/guide.rs | 2 +- wai/wai-quantum-cli/src/main.rs | 55 +- wai/wai-quantum-cli/src/mcp.rs | 26 +- wai/wai-quantum-service/Cargo.toml | 2 +- wai/wai-quantum-service/src/mcp.rs | 1 + wai/wai-quantum/Cargo.toml | 4 + wai/wai-quantum/README.md | 30 + wai/wai-quantum/README.zh-CN.md | 9 + wai/wai-quantum/docs/job-refusals.md | 1 + wai/wai-quantum/schemas/job-request.v1.json | 18 + wai/wai-quantum/schemas/job-result.v1.json | 166 + wai/wai-quantum/schemas/provenance.v1.json | 17 +- wai/wai-quantum/schemas/tools.v1.json | 118 + wai/wai-quantum/src/engine/catalog.rs | 19 +- wai/wai-quantum/src/engine/fabric.rs | 783 ++++ wai/wai-quantum/src/engine/guide.rs | 6 +- wai/wai-quantum/src/engine/mod.rs | 1 + wai/wai-quantum/src/engine/refusal.rs | 1 + wai/wai-quantum/src/engine/run.rs | 17 +- wai/wai-quantum/src/quantum_fabric/sv64.rs | 319 ++ wai/wai-quantum/src/quantum_fabric_cuda.rs | 42 +- wai/wai-quantum/src/quantum_fabric_hip.rs | 44 +- wai/wai-quantum/src/quantum_fabric_opencl.rs | 41 +- wai/wai-quantum/tests/fabric_placement.rs | 183 + 37 files changed, 8025 insertions(+), 1317 deletions(-) create mode 100644 wai/wai-quantum/src/engine/fabric.rs create mode 100644 wai/wai-quantum/tests/fabric_placement.rs diff --git a/.github/workflows/wai-quantum-cuda.yml b/.github/workflows/wai-quantum-cuda.yml index f45a03cbb..0218f7da7 100644 --- a/.github/workflows/wai-quantum-cuda.yml +++ b/.github/workflows/wai-quantum-cuda.yml @@ -12,10 +12,14 @@ name: wai-quantum CUDA member # limbs, must do all of the same under its own implementation id, with its # own mutants caught; and the dense f64 state vector must come back with the # CPU's bits on its pinned corpus and at 16 and 20 qubits, every state-vector -# mutant caught. +# mutant caught; and jobs placed on the fabric's members found there (the GPU +# by CUDA and by OpenCL, the CPU by OpenCL) must give the CPU's answers byte +# for byte, alone and with one state split four ways over them and the CPU +# reference, a state past a member refused. # - cuda-absent (a container with no GPU and no CUDA libraries): the same build # finds no member and says why, rather than failing; the device tests run over -# no member with the declaration `none`. +# no member with the declaration `none`; and placement with no device, the +# state split over CPU partitions bit for bit the CPU's, every test by name. concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -133,6 +137,34 @@ jobs: key="$WAI_QUANTUM_CUDA_EXPECT" grep -q "^cuda sv certified: key=$key .* parity=bit-exact cases=48 digest=b7d129d0593adf70dc164477664970c5c0b8c09f79f1a0573036bd60888dbcd1$" "$report" || { echo "::error::the state vector is not the CPU's bit for bit"; exit 1; } grep -qx "cuda sv mutants: key=$key killed 4 of 4" "$report" || { echo "::error::a state-vector mutant survived"; exit 1; } + - name: Jobs placed on the fabric's members, and a state split over several devices + shell: bash + working-directory: src/wai/wai-quantum + run: | + set -euo pipefail + export PATH="$HOME/.cargo/bin:$PATH" + # The CPU platform's runtime loads its threading and memory libraries + # from the toolkit's own directories (as in wai-quantum-opencl.yml). + oneapi=/opt/intel/oneapi + export LD_LIBRARY_PATH="$oneapi/compiler/latest/lib:$oneapi/tbb/latest/lib/intel64/gcc4.8:$oneapi/tbb/latest/lib:$oneapi/umf/latest/lib:$oneapi/tcm/latest/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + # The members placement finds here, sorted: the GPU by CUDA and by OpenCL, + # and the CPU by OpenCL (the integrated GPU has no binary64, and is not + # placed). One state is split four ways: the GPU by both, the CPU by + # OpenCL, and the CPU reference. + keys="${WAI_QUANTUM_HW_FABRIC_KEYS:-gpu-cuda-sm89,opencl-cpu-8086,opencl-gpu-10de}" + split="${WAI_QUANTUM_HW_FABRIC_SPLIT:-gpu-cuda-sm89,opencl-gpu-10de,opencl-cpu-8086,cpu}" + report="$RUNNER_TEMP/fabric-report.txt"; : > "$report" + WAI_QUANTUM_FABRIC_EXPECT="$keys" WAI_QUANTUM_FABRIC_SPLIT="$split" WAI_QUANTUM_FABRIC_REPORT="$report" CARGO_TARGET_DIR="$HOME/hw-target/wai-quantum-cuda" nice -n 10 \ + cargo test --locked --release --features quantum_engine,quantum_fabric,quantum_fabric_cuda,quantum_fabric_opencl --test fabric_placement -- --test-threads=1 2>&1 | tee "$RUNNER_TEMP/fabric.log" + grep -qE '^test result: ok\. 5 passed; 0 failed' "$RUNNER_TEMP/fabric.log" || { echo "::error::not every placement test ran and passed"; exit 1; } + cat "$report" + grep -qx "fabric members: as declared ($keys)" "$report" || { echo "::error::the members placement found are not the declared ones"; exit 1; } + for key in ${keys//,/ }; do + grep -q "^fabric placed: key=$key .* give the CPU's answers byte for byte$" "$report" || { echo "::error::$key: a placed job's answers are not the CPU's"; exit 1; } + grep -q "^fabric refused: key=$key " "$report" || { echo "::error::$key: a state past what it holds was not refused"; exit 1; } + done + grep -qx "fabric split: ${split//,/+} over 14 and 19 qubits gives the CPU's answers byte for byte" "$report" || { echo "::error::the state split over the devices is not the CPU's"; exit 1; } + grep -q "^fabric auto: .* the CPU's answers byte for byte" "$report" || { echo "::error::auto placed no wide state"; exit 1; } cuda-absent: name: member · CUDA absent (linux) @@ -167,3 +199,25 @@ jobs: grep -qx 'cuda tensor devices: as declared (none)' "$report" || { echo "::error::the tensor-core absent case was not established"; exit 1; } cargo test --locked --features quantum_fabric_cuda,quantum_sv --test cuda_sv -- --test-threads=1 2>&1 | tee "$RUNNER_TEMP/sv.log" grep -qE '^test result: ok\. 3 passed; 0 failed' "$RUNNER_TEMP/sv.log" || { echo "::error::the state-vector tests did not run over no device"; exit 1; } + WAI_QUANTUM_FABRIC_EXPECT=none WAI_QUANTUM_FABRIC_REPORT="$report" cargo test --locked --features quantum_engine,quantum_fabric,quantum_fabric_cuda --test fabric_placement -- --test-threads=1 2>&1 | tee "$RUNNER_TEMP/fabric.log" + grep -qE '^test result: ok\. 5 passed; 0 failed' "$RUNNER_TEMP/fabric.log" || { echo "::error::the placement tests did not run over no member"; exit 1; } + grep -qx 'fabric members: as declared (none)' "$report" || { echo "::error::the placement's absent case was not established"; exit 1; } + # The placement and the split with no device: CPU partitions bit for bit the + # CPU's state vector, exchanges included, and every refusal a host gives; + # each test required by name. + - name: Placement and the split, on CPU partitions + shell: bash + working-directory: wai/wai-quantum + run: | + set -euo pipefail + cargo test --locked --features full --lib -- engine::fabric:: quantum_fabric::sv64:: 2>&1 | tee "$RUNNER_TEMP/split.log" + for t in quantum_fabric::sv64::tests::a_partitioned_run_is_the_cpu_run_bit_for_bit \ + quantum_fabric::sv64::tests::exchanges_and_remaps_move_amplitudes_and_compute_nothing \ + quantum_fabric::sv64::tests::a_split_refuses_what_it_cannot_hold \ + engine::fabric::tests::a_job_s_fabric_reads_or_is_refused_with_its_code \ + engine::fabric::tests::a_placement_changes_where_the_state_runs_and_not_a_byte_of_the_answers \ + engine::fabric::tests::a_placement_this_host_cannot_honour_is_refused_never_made_elsewhere \ + engine::fabric::tests::a_placed_result_and_its_provenance_follow_their_schemas; do + grep -qx "test $t ... ok" "$RUNNER_TEMP/split.log" || { echo "::error::$t did not run and pass"; exit 1; } + done + grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/split.log" || { echo "::error::a test failed"; exit 1; } diff --git a/.github/workflows/wai-quantum-hip.yml b/.github/workflows/wai-quantum-hip.yml index 74f6eecc7..0ce0c74e1 100644 --- a/.github/workflows/wai-quantum-hip.yml +++ b/.github/workflows/wai-quantum-hip.yml @@ -12,7 +12,10 @@ name: wai-quantum HIP member # GPU's bf16 matrix instruction from offset-binary 8-bit limbs, must do all # of the same under its own implementation id, with its own mutants caught; # and the dense f64 state vector must come back with the CPU's bits on its -# pinned corpus and at 16 and 20 qubits, every state-vector mutant caught. +# pinned corpus and at 16 and 20 qubits, every state-vector mutant caught; +# and jobs placed on the fabric's members found there (the GPU by HIP and by +# OpenCL) must give the CPU's answers byte for byte, alone and with one state +# split over them, a state past a member refused. # - hip-absent (a container with no GPU and no HIP libraries): the same build # finds no member and says why, rather than failing; the device tests run over # no member with the declaration `none`. @@ -135,6 +138,27 @@ jobs: cat "$report" grep -q "^hip sv certified: key=$key .* parity=bit-exact cases=48 digest=b7d129d0593adf70dc164477664970c5c0b8c09f79f1a0573036bd60888dbcd1$" "$report" || { echo "::error::the state vector is not the CPU's bit for bit"; exit 1; } grep -qx "hip sv mutants: key=$key killed 4 of 4" "$report" || { echo "::error::a state-vector mutant survived"; exit 1; } + - name: Jobs placed on the fabric's members, and a state split over them + shell: bash + working-directory: src/wai/wai-quantum + run: | + set -euo pipefail + export PATH="$HOME/.cargo/bin:$PATH" + # The members placement finds here, sorted (the GPU by HIP and by OpenCL), + # declared here or by the runner; one state is split over them. + keys="${WAI_QUANTUM_AMD_FABRIC_KEYS:-gpu-hip-gfx1151,opencl-gpu-1002}" + report="$RUNNER_TEMP/fabric-report.txt"; : > "$report" + WAI_QUANTUM_FABRIC_EXPECT="$keys" WAI_QUANTUM_FABRIC_SPLIT="$keys" WAI_QUANTUM_FABRIC_REPORT="$report" CARGO_TARGET_DIR="$HOME/hw-target/wai-quantum-hip" nice -n 10 \ + cargo test --locked --release --features quantum_engine,quantum_fabric,quantum_fabric_hip,quantum_fabric_opencl --test fabric_placement -- --test-threads=1 2>&1 | tee "$RUNNER_TEMP/fabric.log" + grep -qE '^test result: ok\. 5 passed; 0 failed' "$RUNNER_TEMP/fabric.log" || { echo "::error::not every placement test ran and passed"; exit 1; } + cat "$report" + grep -qx "fabric members: as declared ($keys)" "$report" || { echo "::error::the members placement found are not the declared ones"; exit 1; } + for key in ${keys//,/ }; do + grep -q "^fabric placed: key=$key .* give the CPU's answers byte for byte$" "$report" || { echo "::error::$key: a placed job's answers are not the CPU's"; exit 1; } + grep -q "^fabric refused: key=$key " "$report" || { echo "::error::$key: a state past what it holds was not refused"; exit 1; } + done + grep -qx "fabric split: ${keys//,/+} over 14 and 19 qubits gives the CPU's answers byte for byte" "$report" || { echo "::error::the state split over the members is not the CPU's"; exit 1; } + grep -q "^fabric auto: .* the CPU's answers byte for byte" "$report" || { echo "::error::auto placed no wide state"; exit 1; } hip-absent: name: member · HIP absent (linux-arm64) @@ -169,3 +193,6 @@ jobs: grep -qx 'hip wmma devices: as declared (none)' "$report" || { echo "::error::the matrix-instruction absent case was not established"; exit 1; } cargo test --locked --features quantum_fabric_hip,quantum_sv --test hip_sv -- --test-threads=1 2>&1 | tee "$RUNNER_TEMP/sv.log" grep -qE '^test result: ok\. 3 passed; 0 failed' "$RUNNER_TEMP/sv.log" || { echo "::error::the state-vector tests did not run over no device"; exit 1; } + WAI_QUANTUM_FABRIC_EXPECT=none WAI_QUANTUM_FABRIC_REPORT="$report" cargo test --locked --features quantum_engine,quantum_fabric,quantum_fabric_hip --test fabric_placement -- --test-threads=1 2>&1 | tee "$RUNNER_TEMP/fabric.log" + grep -qE '^test result: ok\. 5 passed; 0 failed' "$RUNNER_TEMP/fabric.log" || { echo "::error::the placement tests did not run over no member"; exit 1; } + grep -qx 'fabric members: as declared (none)' "$report" || { echo "::error::the placement's absent case was not established"; exit 1; } diff --git a/wai/CHANGELOG.md b/wai/CHANGELOG.md index e9f4ce5f1..cd8fc0113 100644 --- a/wai/CHANGELOG.md +++ b/wai/CHANGELOG.md @@ -267,6 +267,40 @@ wire format may change and such changes are recorded here. implementation, `channel_lineup_verify.py`, from the text alone, agrees on every vector, and a CI step runs both. +### wai-quantum: simulator scale-out, the state vector on the fabric's members + +- **Placement** (`engine::fabric`): a job's new `fabric` field says where the `statevector` method's state runs: + `auto` (the default), `cpu`, `accelerator`, a member's id or key, or a list of members, a power of two of them, + the state split by its top qubits into one partition on each. The CUDA, HIP and OpenCL members' dense f64 state + vectors (`quantum_fabric::sv64`) are discovered once per process, compiled and certified against the CPU on the + pinned corpus; only a member certified bit-exact is placed, so a placed job's answers are the CPU's byte for + byte. `auto` places a state of 20 qubits or more on the first such member that holds it, GPUs first, and keeps a + smaller one on the CPU; a member that fails during an auto run hands the job back to the CPU, and the receipt + says so. A placement the host cannot honour is refused with the new code `J013`, never made elsewhere. With no + member asked for and none placed, a job's plan and result are the ones they always were; the pinned digests are + unchanged. +- **The fabric's receipt in the job's**: a placed result, or one whose job asked for a placement, carries `fabric` + (the kernel, the placement asked, the member or each partition's, its certificate's parity tier, digest and + corpus, and the energy, unmetered with the reason), sealed by the job's receipt; its provenance's `computer` + names the members. New optional members of `wai.quantum.job-request/1`, `wai.quantum.job-result/1` and + `wai.quantum.provenance/1`, and `fabric_members` in `wai.quantum.tools/1`. +- **Several devices on one node** (`quantum_fabric::sv64::run_split`): each partition runs the launches the CPU + plans on its own amplitudes, each runner on a thread of its own; a gate on a partition qubit first has that qubit + exchanged with a local one through the host's copy of the state. Held bit for bit to the CPU's state vector over + the pinned corpus at every partition count a case admits and on wide states with exchanges, on CPU partitions in + every container. On the fleet: a laptop GPU by CUDA and by OpenCL, the CPU by OpenCL and the CPU reference, + one state split four ways over them; an integrated GPU by HIP and by OpenCL; and each GPU beside the CPU and split + over itself, each giving the CPU's answers byte for byte. Each member states the most qubits it holds (25 on every GPU + here), and a state or partition past it is refused before anything runs. +- **Members' runs from a given state**: `CudaSv::run_launches`, `HipSv::run_launches` and + `OpenClSv::run_launches`, with `max_qubits`, each refusing a state or a launch outside what it holds. +- **Surfaces**: `wai-quantum run --fabric` (repeatable) and `wai-quantum fabric [--json]`, the command line's + `cuda`, `hip` and `opencl` features; `fabric` in both MCP servers' job tools and `list_fabric` on the command + line's; the job service reads `fabric` and places on its CPU. The generated agent docs carry it. +- **CI**: `tests/fabric_placement.rs` on jetson-hub (CUDA and OpenCL) and framework-128gb (HIP and OpenCL) in the + hardware workflows, each with its declared members and a split over them, and absent where there is no device; + the split and the planner's refusals in the containers. + ### wai-quantum: the variational and algorithm library - **Parameters in a job** (`engine::catalog::bind_params`): a job's `"params"` gives each of its program's parameters diff --git a/wai/wai-quantum-cli/Cargo.lock b/wai/wai-quantum-cli/Cargo.lock index d0ac9590f..5f4dad27c 100644 --- a/wai/wai-quantum-cli/Cargo.lock +++ b/wai/wai-quantum-cli/Cargo.lock @@ -126,6 +126,18 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" +[[package]] +name = "cl3" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad5f4170f520224684c5c6e86e8d5474c2a10696e553b1db8389970cd82ece7" +dependencies = [ + "dlopen2", + "libc", + "opencl-sys", + "thiserror", +] + [[package]] name = "clap" version = "4.6.7" @@ -260,6 +272,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "cudarc" +version = "0.19.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7359bf1de037ddada72729c3acec9b040f3468400c6e9e740b01ba0cd2e89562" +dependencies = [ + "libloading", +] + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -324,6 +345,29 @@ dependencies = [ "syn 3.0.9", ] +[[package]] +name = "dlopen2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2c5bd4158e66d1e215c49b837e11d62f3267b30c92f1d171c4d3105e3dc4d4" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "document-features" version = "0.2.12" @@ -370,7 +414,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -603,6 +647,16 @@ version = "0.2.191" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" +[[package]] +name = "libloading" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" +dependencies = [ + "cfg-if", + "windows-link", +] + [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -697,6 +751,25 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "opencl-sys" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c295aff010162eb6b1a59c758f0547b886c1edcbf324a41f48ee8f64dc48c4" +dependencies = [ + "libc", +] + +[[package]] +name = "opencl3" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecb3473c4f01afd0eea3ee5b31649fec47dbc23353a63e1b916aa67cd810fb73" +dependencies = [ + "cl3", + "libc", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -794,7 +867,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -992,6 +1065,26 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "thiserror" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + [[package]] name = "time" version = "0.3.55" @@ -1123,10 +1216,12 @@ name = "wai-quantum" version = "0.7.0" dependencies = [ "blake3", + "cudarc", "ed25519-dalek", "objc2", "objc2-foundation", "objc2-metal", + "opencl3", "serde", "serde_json", ] @@ -1168,6 +1263,28 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-link" version = "0.2.1" diff --git a/wai/wai-quantum-cli/Cargo.toml b/wai/wai-quantum-cli/Cargo.toml index cfb987744..4ffbecc0f 100644 --- a/wai/wai-quantum-cli/Cargo.toml +++ b/wai/wai-quantum-cli/Cargo.toml @@ -28,6 +28,11 @@ service = ["dep:ureq"] providers = ["dep:wai-quantum-qpu"] # The single-precision state vector on the GPU (`--method statevector_single`), on macOS. metal = ["wai-quantum/quantum_sv_metal", "wai-quantum/quantum_cutrank_metal"] +# The fabric's accelerator members a statevector job may be placed on (`--fabric`, `wai-quantum fabric`): each loads its +# driver and runtime compiler when first used, so a build with them runs where there are none and finds no member there. +cuda = ["wai-quantum/quantum_fabric_cuda"] +hip = ["wai-quantum/quantum_fabric_hip"] +opencl = ["wai-quantum/quantum_fabric_opencl"] [dependencies] clap = { version = "4.6", features = ["derive", "env", "wrap_help"] } diff --git a/wai/wai-quantum-cli/README.md b/wai/wai-quantum-cli/README.md index eb0bc6dc7..7066e5882 100644 --- a/wai/wai-quantum-cli/README.md +++ b/wai/wai-quantum-cli/README.md @@ -100,6 +100,14 @@ wai-quantum instance ghz-family.qasm --input n=3 `wai-quantum methods` lists each method's reach in a job's memory here (`--memory-gb`, default 16). +`--fabric` says where the `statevector` method's state runs: `auto` (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits), `cpu`, `accelerator`, or a member's id or key; given more than once, the state is split by its top qubits into one partition on each member named (a power of two of them; `cpu` is a member, and one may be named twice). Every member placed gives the CPU's answers byte for byte, and the result names where its state ran, with the member's certificate, in its receipt. `wai-quantum fabric` lists the members this host can place on, each with the most qubits it holds, and the devices found and not placed, with why. A placement this host cannot honour is refused (`J013`), never made elsewhere. + +```sh runnable +wai-quantum fabric +wai-quantum run circuit.qasm --method statevector --fabric cpu --fabric cpu --shots 100 +wai-quantum run prog.qasm --fabric a-member-elsewhere # exits 1 +``` + Each result names: - its method, and why that method was chosen; @@ -693,6 +701,7 @@ Every `--json` output and every MCP tool's answer follows a committed JSON Schem - **Default:** `submit`, over HTTPS. - **`--features metal`:** the single-precision state vector on the GPU (`--method statevector_single`), on macOS. +- **`--features cuda`, `hip`, `opencl`:** the fabric's accelerator members a state vector can be placed on (`--fabric`, `wai-quantum fabric`). Each loads its driver and runtime compiler when first used, so a build with them runs where there are none and finds no member there. - **`--no-default-features --target wasm32-wasip2`:** a WASI component without `submit`. It gives the same output under any WASI runtime. `wai-quantum completions zsh` (or bash, fish, elvish, PowerShell) prints shell completion. diff --git a/wai/wai-quantum-cli/README.zh-CN.md b/wai/wai-quantum-cli/README.zh-CN.md index 6878f1576..59804445f 100644 --- a/wai/wai-quantum-cli/README.zh-CN.md +++ b/wai/wai-quantum-cli/README.zh-CN.md @@ -103,6 +103,14 @@ wai-quantum instance ghz-family.qasm --input n=3 `wai-quantum methods` 列出每种方法在本机一个作业的内存(`--memory-gb`,默认 16)内能达到的规模。 +`--fabric` 指定 `statevector` 方法的态在哪里运行:`auto`(默认:从 20 个量子比特起,放到本机第一个经认证逐位一致且能容纳它的加速器成员上)、`cpu`、`accelerator`,或成员的 id 或键;多次给出时,态按最高位量子比特划分为若干分区,每个所列成员一个分区(数量为 2 的幂;`cpu` 也是成员,同一成员可列两次)。放置到的每个成员都给出与 CPU 逐字节相同的答案,结果在其收据中指明态在哪里运行以及该成员的证书。`wai-quantum fabric` 列出本机可放置的成员(各附其可容纳的最多量子比特数),以及找到但未放置的设备及原因。主机无法兑现的放置会被拒绝(`J013`),绝不改放别处。 + +```sh runnable +wai-quantum fabric +wai-quantum run circuit.qasm --method statevector --fabric cpu --fabric cpu --shots 100 +wai-quantum run prog.qasm --fabric a-member-elsewhere # exits 1:别处的成员,被拒绝 +``` + 每个结果都注明: - 所用的方法,以及选择该方法的原因; @@ -683,6 +691,7 @@ wai-quantum version --json # 同样的内容,以 wai.quantum.versions/1 - **默认:**包含 `submit`,通过 HTTPS。 - **`--features metal`:**在 macOS 上于 GPU 运行的单精度态矢量(`--method statevector_single`)。 +- **`--features cuda`、`hip`、`opencl`:**态矢量可放置其上的计算结构加速器成员(`--fabric`、`wai-quantum fabric`)。每个成员在首次使用时才加载其驱动和运行时编译器,因此带这些特性的构建在没有它们的机器上也能运行,只是在那里找不到成员。 - **`--no-default-features --target wasm32-wasip2`:**不含 `submit` 的 WASI 组件。它在任何 WASI 运行时下给出相同的输出。 `wai-quantum completions zsh`(或 bash、fish、elvish、PowerShell)打印 shell 补全脚本。 diff --git a/wai/wai-quantum-cli/docs/llms-full.txt b/wai/wai-quantum-cli/docs/llms-full.txt index 58cc6ed42..79824e8e5 100644 --- a/wai/wai-quantum-cli/docs/llms-full.txt +++ b/wai/wai-quantum-cli/docs/llms-full.txt @@ -46,46 +46,42 @@ Runs on this machine, signed with the user's key; nothing leaves the machine. Run an OpenQASM program on this machine, planned as the quantum job service plans it: measurement counts, Pauli expectation values and/or amplitudes, the method chosen and why, its accuracy class, and a receipt signed with this user's key. Give `intent` (an exact distribution, or a reference program it must equal or whose state it must prepare) and the engine checks it with the run. Every answer carries `verdict`: the level the engine checked to (proof, evidence, executed, parsed, refused), whether the intent holds and a plain statement, sealed in the receipt. Quote the verdict and the numbers; do not estimate them or claim more. Parameters: -- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. -- `qasm` (string): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. +- `qasm` (string, required): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. - `inputs` (object): Values for a generator's integer inputs, as {"n": 5}: the program is read as its family's circuit at those values. - `shots` (integer): Shots to sample; 1024 when nothing else is asked. - `seed` (integer): The sampling seed (default 1). -- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. +- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names. - `observables` (array): Pauli observables, as "Z0 Z1" or "0.5 X2". - `amplitudes` (array): Basis states whose amplitudes to return, as bit strings with the highest qubit first. - `noise` (object): Channel probabilities - `options` (object): Method options: max_bond, fusion, trajectories, threshold, memory_gb. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's "compiled" states its distance from the program. - `target` (any): A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it. +- `fabric` (any): Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's "fabric" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013). - `intent` (any): What the program must do, checked by the engine with the run: the result's "verdict" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's "repaired" holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. -- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. -- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050). ### `plan_quantum_circuit`: Plan a quantum program The method a program would run on and why, the memory and work it would take, without running it. Parameters: -- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. -- `qasm` (string): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. +- `qasm` (string, required): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. - `inputs` (object): Values for a generator's integer inputs, as {"n": 5}: the program is read as its family's circuit at those values. - `shots` (integer): Shots to sample; 1024 when nothing else is asked. - `seed` (integer): The sampling seed (default 1). -- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. +- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names. - `observables` (array): Pauli observables, as "Z0 Z1" or "0.5 X2". - `amplitudes` (array): Basis states whose amplitudes to return, as bit strings with the highest qubit first. - `noise` (object): Channel probabilities - `options` (object): Method options: max_bond, fusion, trajectories, threshold, memory_gb. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's "compiled" states its distance from the program. - `target` (any): A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it. +- `fabric` (any): Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's "fabric" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013). - `intent` (any): What the program must do, checked by the engine with the run: the result's "verdict" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's "repaired" holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. -- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. -- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050). ### `lint_qasm`: Check an OpenQASM program @@ -126,18 +122,6 @@ Parameters: - `b` (string, required): The second program. - `inputs` (object): Values for a generator's integer inputs, as {"n": 5}: the program is read as its family's circuit at those values. -### `convert_program`: Convert a program between formats - -Carry a program between OpenQASM 3, QIR (LLVM text, read under its base and adaptive profiles, written as QIR 2.0) and jeff (its Cap'n Proto message, as base64). The answer is the program written, the program as OpenQASM 3 (what every other tool takes), each note with its code (a rotation at an arbitrary angle, a custom gate read by its name, what a format leaves out), what was read and written, and the check: the output read back and held to the program by the equivalence ladder. A construct a reader cannot hold exactly is refused with its code (Q700 to Q721) and its place: quote the code, and never guess around it. - -Parameters: -- `program` (string): The program's text: OpenQASM or QIR. -- `program_base64` (string): The program's bytes as base64: jeff. -- `from` (string, one of qasm, qir, jeff): Its format; found from its bytes when not given. -- `to` (string, required, one of qasm, qir, jeff): The format to write. -- `profile` (string, one of base, adaptive): QIR's profile to write: by default base when the program's measurements all come at the end, else adaptive. -- `check` (boolean): false: write it without the check. - ### `improve_qasm`: Improve an OpenQASM program The program with its smells fixed in its own text (all of them, and each alone), each with its measures and the equivalence check's verdict against the original. A candidate the check finds different is never returned. @@ -387,6 +371,10 @@ Parameters: Each simulation method: its accuracy class, the circuits it takes, and the most qubits it holds in a job's memory here. +### `list_fabric`: List the fabric's members + +The members of the fabric a statevector job can be placed on here (a job's `fabric`): the CPU and each accelerator found and certified bit-exact against the CPU in this process, each with its key, its certificate and the most qubits it holds; the devices found and not placed, and why; and the backends this build reaches. + ### `qasm_diagnostics`: The reader's diagnostic codes Every code the OpenQASM reader gives (each refusal and warning carries one, as `[Q103]` at the end of its message and as `code` in lint's JSON): its outcome (refused, lowered, carried, preserved or warned) and its meaning; and beside them, under job_codes, the codes of what is asked of a program (`[J011]`: the request, the method, an intent, a repair, the host). A code never changes meaning once released. Give `code` for one of either. @@ -412,23 +400,21 @@ Parameters: Run an OpenQASM program here as it would run on a device target: compiled exactly to the target's native gates, placed on the qubits and routes most likely to succeed (the expected success given beside the fewest-swaps layout's), checked against the circuit, and simulated under the noise its calibration gives (each gate's error, T1, T2 and durations, idling, and each qubit's readout), on the density matrix or by trajectories. Counts and expectation values, their distance from the ideal distribution, the noise derived, and a receipt signed with this user's key that binds the target's hash. A model of the device, not a run on it: quote it as such. Every angle must be a dyadic multiple of 2π. Parameters: -- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. -- `qasm` (string): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. +- `qasm` (string, required): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. - `inputs` (object): Values for a generator's integer inputs, as {"n": 5}: the program is read as its family's circuit at those values. - `shots` (integer): Shots to sample; 1024 when nothing else is asked. - `seed` (integer): The sampling seed (default 1). -- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. +- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names. - `observables` (array): Pauli observables, as "Z0 Z1" or "0.5 X2". - `amplitudes` (array): Basis states whose amplitudes to return, as bit strings with the highest qubit first. - `noise` (object): Channel probabilities - `options` (object): Method options: max_bond, fusion, trajectories, threshold, memory_gb. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's "compiled" states its distance from the program. - `target` (any, required): A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it. +- `fabric` (any): Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's "fabric" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013). - `intent` (any): What the program must do, checked by the engine with the run: the result's "verdict" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's "repaired" holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. -- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. -- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050). ### `qec_code`: Show an error-correcting code and certify its distance @@ -471,92 +457,6 @@ Parameters: - `rounds` (integer): surface: rounds (default the distance). - `seed` (integer) -### `pulse_schedule`: Read a pulse program into its schedule - -Read a pulse program (OpenPulse calibrations: ports, frames, waveforms, play, delay, shift_phase, set_phase, shift_frequency, set_frequency, captures and barriers) into its schedule on frames: every instruction at its sample, each waveform's samples (gaussian, drag, gaussian_square, constant, sech, sine, or explicit), each gate call with the samples its calibration spans, and the digests a pulse run's receipt binds (the program, its calibrations, the schedule). Durations are whole samples of dt (pulse.dt_ns, default 0.5 ns) or refused. A construct the reader does not take is refused with a Q code and its line. Sealed with this user's key. To run it, give the program to run_quantum_circuit with method "pulse". - -Parameters: -- `qasm` (string, required): A pulse program: OpenQASM 3 with `defcalgrammar "openpulse";`, `cal` blocks declaring ports (d0 drives qubit 0, m0 is its measurement port, a0 its acquisition port), frames (newframe(port, frequency Hz, phase)) and waveforms, a `defcal` for every gate it calls on physical qubits ($0), and the calls. -- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. - -### `pulse_check`: Check a pulse run by running it again - -Check a pulse job as a host returned it ({"request", "result"}, the result with its receipt): the receipt's signature, the program's digest against the request's text, and the request run again here with the result held to the one given field by field (the density matrix's digest among them), each difference named. A pulse run is the same bits on every platform, so a result that does not reproduce was not made from that request by this engine. Sealed with this user's key. Quote `verified` and the statement. - -Parameters: -- `request` (object, required): The pulse job's request. -- `result` (object, required): Its result, with its receipt. - -### `gradient_qasm`: The exact gradient of a Hamiltonian's expectation by a program's parameters - -The expectation E = ⟨ψ|H|ψ⟩ of a Hamiltonian at a program's parameters, and its gradient by each parameter, exactly: by adjoint differentiation or the parameter-shift rule on the double-precision state vector (at most 20 qubits, no noise, measurements only at the end). The reader follows each parameter into the gates, so an argument may be any expression of the built-in functions. The answer states its method, that it is f64 and approximate, and a bound on the rounding of the value and of each component (precision.rounding_bound). Sealed with this user's key. Quote the gradient with its bound. - -Parameters: -- `qasm` (string, required): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). -- `params` (object, required): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). -- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. -- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. - -### `optimize_qasm`: Minimise a Hamiltonian's expectation over a program's parameters - -Minimise E = ⟨ψ|H|ψ⟩ over a program's parameters from the given params, deterministically: gradient descent with a fixed step, Adam, or SPSA from a seeded stream (at most 2000 steps). Every step's parameters and value (and gradient, or SPSA's perturbation and estimate) are listed, each step a link of a digest chain from the request, best and final given; the same request gives the same bytes on every platform. Sealed with this user's key: the receipt binds the program, every step, the method and the seed, and verify_quantum_result (or wai-quantum verify) re-runs it. A minimum found is a minimum along this path, not a proof of the global one. - -Parameters: -- `qasm` (string, required): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). -- `params` (object, required): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). -- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. -- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). -- `steps` (integer): Steps to take (default 100). -- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). -- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. -- `seed` (integer): SPSA's seed (default 1). - -### `vqe_ground_state`: Find a Hamiltonian's ground energy by the variational eigensolver - -The variational eigensolver: an ansatz (the program given as qasm with params, or ansatz {"layers": L}: layers of ry and rz on every qubit and a ring of cx, its parameters t0, t1, … from 0.1) optimised on the Hamiltonian as optimize_qasm does. At most 8 qubits the answer sets the energy found beside the exact ground energy by diagonalisation (reference.ground_energy and gap); the energy found is never below it. Sealed with this user's key. Report the gap: an ansatz that cannot reach the ground state stops above it. - -Parameters: -- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. -- `qasm` (string): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). -- `params` (object): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). -- `ansatz` (object): The built-in ansatz in place of qasm (layers default 2, qubits the Hamiltonian's). -- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). -- `steps` (integer): Steps to take (default 100). -- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). -- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. -- `seed` (integer): SPSA's seed (default 1). - -### `qaoa_maxcut`: Solve Max-Cut on a graph by QAOA - -Max-Cut by the quantum approximate optimisation algorithm: the program (|+⟩ⁿ, then for each layer rzz(gamma·w) on every edge and rx(2·beta) on every qubit) and its cost Hamiltonian built from the graph (at most 20 vertices, 16 layers), optimised as optimize_qasm does from the params or a linear ramp, and read against the maximum cut found by brute force: the expected cut and its ratio to the maximum, the likeliest assignment and whether it is optimal, and the probability of an optimal one. Sealed with this user's key. - -Parameters: -- `graph` (object, required) -- `layers` (integer): QAOA's p (default 1). -- `params` (object): gamma_0, beta_0, … to start from. -- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). -- `steps` (integer): Steps to take (default 100). -- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). -- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. -- `seed` (integer): SPSA's seed (default 1). - -### `build_algorithm`: Write the program for a standard algorithm, checked against its reference - -An OpenQASM 3 program for a standard algorithm, with how to read its result, what it gives, and the equivalence ladder's verdict on it against a reference matrix or truth table built from the definitions (check: exact on every basis state up to 8 qubits, the adder's up to 16; past that unchecked). qpe: the phase φ of p(2πφ) on counting qubits; amplitude_estimation: the amplitude a that A = ry(2·arcsin √a) gives the good state, by phase estimation of the Grover operator; adder: the ripple-carry adder of bits-bit integers in place (with a and b, prepared and measured); qsvt: quantum signal processing from phases, of a signal x or of a real symmetric 2 × 2 matrix through its block encoding (all phases zero give the Chebyshev polynomial). Sealed with this user's key. Run the program with run_quantum_circuit. - -Parameters: -- `algorithm` (any, required, one of qpe, amplitude_estimation, adder, qsvt) -- `counting` (integer): qpe, amplitude_estimation: counting qubits (default 4). -- `phase` (number): qpe: the phase φ, in turns. -- `amplitude` (number): amplitude_estimation: the good state's probability a. -- `bits` (integer): adder: the integers' width. -- `a` (integer): adder: the first addend, prepared. -- `b` (integer): adder: the second, which the sum replaces. -- `carry_in` (boolean): adder: a carry in. -- `phases` (array): qsvt: φ₀ … φ_d, radians. -- `x` (number): qsvt: the signal. -- `matrix` (array): qsvt: [[a, b], [b, c]], real and symmetric, its eigenvalues within [-1, 1]. - ### `providers_list`: List the person's quantum providers The person's own quantum providers, as their registry lists them: each one's name, kind, protocol, endpoint or command, and where its credential is kept (never the credential itself). With free: true, also what anyone can use at no cost: the engine's methods on this machine with their limits, the free job service, and each provider whose own description states free use (this asks each provider to describe itself). @@ -596,22 +496,20 @@ Streamable HTTP, no account and no key. Run an OpenQASM program and return measurement counts, Pauli expectation values and/or amplitudes. The service chooses the method (bit-exact or double-precision state vector up to 32 qubits, single precision on a GPU to 33, stabilizer tableau for Clifford circuits up to 32768 qubits, matrix product states up to 4096, sparse Pauli dynamics for expectation values up to 1024 with an error bound, an exact density matrix or trajectories for noise), reports why and how accurate, and signs the result. Give `intent` (an exact distribution, or a reference program it must equal or whose state it must prepare) and the engine checks it with the run. Every answer carries `verdict`: the level the engine checked to (proof, evidence, executed, parsed, refused), whether the intent holds and a plain statement, sealed in the receipt. Waits up to 50 s; a longer job answers with status running and an id for get_quantum_job. Parameters: -- `qasm` (string): The program, OpenQASM 3 (or 2), read as the whole language: registers, aliases and slices; the standard gates, `U` and `gphase`; user `gate` definitions and `def` subroutines, inlined; every modifier (`ctrl @`, `negctrl @`, `inv @`, `pow(k) @`) on any gate, lowered exactly; classical types (int, uint, float, angle, complex, bool, bit, arrays), their arithmetic and built-in functions, computed on reading; `for`, `while`, `switch`, `break`, `continue`; measurement and `reset` anywhere; classical control on measured bits (`if (c[0]) x q[1];`, `if (c >= 2) { … } else { … }`, `&&`, `||`); a `while` on measured bits takes `@wai.max_iterations N` before it. `output` declarations come back in the result; `delay`, `box` and `stretch` are carried and labelled as not applied; `defcal` and `cal` are kept, not run. A program that measures in the middle or acts on what it measured runs on statevector or stabilizer: counts split their shots at each measurement; expectation values are exact, of the state before the final measurements. What the reader refuses comes back with a code, as `[Q103]`; qasm_diagnostics says what each code means. +- `qasm` (string, required): The program, OpenQASM 3 (or 2), read as the whole language: registers, aliases and slices; the standard gates, `U` and `gphase`; user `gate` definitions and `def` subroutines, inlined; every modifier (`ctrl @`, `negctrl @`, `inv @`, `pow(k) @`) on any gate, lowered exactly; classical types (int, uint, float, angle, complex, bool, bit, arrays), their arithmetic and built-in functions, computed on reading; `for`, `while`, `switch`, `break`, `continue`; measurement and `reset` anywhere; classical control on measured bits (`if (c[0]) x q[1];`, `if (c >= 2) { … } else { … }`, `&&`, `||`); a `while` on measured bits takes `@wai.max_iterations N` before it. `output` declarations come back in the result; `delay`, `box` and `stretch` are carried and labelled as not applied; `defcal` and `cal` are kept, not run. A program that measures in the middle or acts on what it measured runs on statevector or stabilizer: counts split their shots at each measurement; expectation values are exact, of the state before the final measurements. What the reader refuses comes back with a code, as `[Q103]`; qasm_diagnostics says what each code means. - `shots` (integer): Measurement shots. Default 1024 when no observables or amplitudes are asked for. - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, density_matrix, trajectories, pulse): Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. +- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, density_matrix, trajectories): Leave as auto unless you need a particular method. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. - `target` (any): A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing. +- `fabric` (any): Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. -- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. -- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. -- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes. ### `run_quantum_set`: Run a set of quantum programs, or one over a grid @@ -623,16 +521,15 @@ Parameters: - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, density_matrix, trajectories, pulse): Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. +- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, density_matrix, trajectories): Leave as auto unless you need a particular method. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. - `target` (any): A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing. +- `fabric` (any): Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. -- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. -- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes. - `programs` (array): The set's programs: each a program's text, or a job ({"qasm", …}) whose own fields win over the set's. - `sweep` (object): Each input of qasm and its values: every combination runs, the names in sorted order, the first varying slowest; an integer input's values are whole numbers. @@ -646,19 +543,17 @@ Parameters: - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, density_matrix, trajectories, pulse): Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. +- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, density_matrix, trajectories): Leave as auto unless you need a particular method. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. - `target` (any): A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing. +- `fabric` (any): Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. -- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. -- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes. - `programs` (array): The set's programs: each a program's text, or a job ({"qasm", …}) whose own fields win over the set's. - `sweep` (object): Each input of qasm and its values: every combination runs, the names in sorted order, the first varying slowest; an integer input's values are whole numbers. -- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. ### `get_quantum_job`: Read a quantum job @@ -690,18 +585,6 @@ Parameters: - `a` (string, required) - `b` (string, required) -### `convert_program`: Convert a program between formats - -Carry a program between OpenQASM 3, QIR (LLVM text, read under its base and adaptive profiles, written as QIR 2.0) and jeff (its Cap'n Proto message, as base64). The answer is the program written, the program as OpenQASM 3 (what every other tool takes), each note with its code (a rotation at an arbitrary angle, a custom gate read by its name, what a format leaves out), what was read and written, and the check: the output read back and held to the program by the equivalence ladder. A construct a reader cannot hold exactly is refused with its code (Q700 to Q721) and its place: quote the code, and never guess around it. A conversion larger than the service takes is refused with the command that runs it locally. - -Parameters: -- `program` (string): The program's text: OpenQASM or QIR. -- `program_base64` (string): The program's bytes as base64: jeff. -- `from` (string, one of qasm, qir, jeff): Its format; found from its bytes when not given. -- `to` (string, required, one of qasm, qir, jeff): The format to write. -- `profile` (string, one of base, adaptive): QIR's profile to write: by default base when the program's measurements all come at the end, else adaptive. -- `check` (boolean): false: write it without the check. - ### `improve_qasm`: Improve a quantum program The program with its smells fixed in its own text (all of them, and each alone), each candidate with its measures and the equivalence check's verdict against the program. A candidate the check finds different is never returned. @@ -782,21 +665,19 @@ Parameters: Run an OpenQASM program as it would run on a device target: compiled exactly to its gates, placed on its most reliable qubits and routes (the expected success given), checked against the circuit, and simulated under the noise its calibration gives, on the density matrix or by trajectories. Counts and expectation values with their distance from the ideal distribution, the noise derived, and a receipt that binds the target's hash. A model of the device, not a run on it. Every angle must be a dyadic multiple of 2π. Waits up to 50 s, as run_quantum_circuit does. Parameters: -- `qasm` (string): The program, OpenQASM 3 (or 2), read as the whole language: registers, aliases and slices; the standard gates, `U` and `gphase`; user `gate` definitions and `def` subroutines, inlined; every modifier (`ctrl @`, `negctrl @`, `inv @`, `pow(k) @`) on any gate, lowered exactly; classical types (int, uint, float, angle, complex, bool, bit, arrays), their arithmetic and built-in functions, computed on reading; `for`, `while`, `switch`, `break`, `continue`; measurement and `reset` anywhere; classical control on measured bits (`if (c[0]) x q[1];`, `if (c >= 2) { … } else { … }`, `&&`, `||`); a `while` on measured bits takes `@wai.max_iterations N` before it. `output` declarations come back in the result; `delay`, `box` and `stretch` are carried and labelled as not applied; `defcal` and `cal` are kept, not run. A program that measures in the middle or acts on what it measured runs on statevector or stabilizer: counts split their shots at each measurement; expectation values are exact, of the state before the final measurements. What the reader refuses comes back with a code, as `[Q103]`; qasm_diagnostics says what each code means. +- `qasm` (string, required): The program, OpenQASM 3 (or 2), read as the whole language: registers, aliases and slices; the standard gates, `U` and `gphase`; user `gate` definitions and `def` subroutines, inlined; every modifier (`ctrl @`, `negctrl @`, `inv @`, `pow(k) @`) on any gate, lowered exactly; classical types (int, uint, float, angle, complex, bool, bit, arrays), their arithmetic and built-in functions, computed on reading; `for`, `while`, `switch`, `break`, `continue`; measurement and `reset` anywhere; classical control on measured bits (`if (c[0]) x q[1];`, `if (c >= 2) { … } else { … }`, `&&`, `||`); a `while` on measured bits takes `@wai.max_iterations N` before it. `output` declarations come back in the result; `delay`, `box` and `stretch` are carried and labelled as not applied; `defcal` and `cal` are kept, not run. A program that measures in the middle or acts on what it measured runs on statevector or stabilizer: counts split their shots at each measurement; expectation values are exact, of the state before the final measurements. What the reader refuses comes back with a code, as `[Q103]`; qasm_diagnostics says what each code means. - `shots` (integer): Measurement shots. Default 1024 when no observables or amplitudes are asked for. - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes. +- `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. - `target` (any, required): A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing. +- `fabric` (any): Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. -- `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. -- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. -- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. ### `quantum_circuit_examples`: Ready-to-run quantum examples @@ -843,92 +724,6 @@ Parameters: - `rounds` (integer): surface: rounds (default the distance). - `seed` (integer) -### `pulse_schedule`: Read a pulse program into its schedule - -Read a pulse program (OpenPulse calibrations: ports, frames, waveforms, play, delay, shift_phase, set_phase, shift_frequency, set_frequency, captures and barriers) into its schedule on frames: every instruction at its sample, each waveform's samples (gaussian, drag, gaussian_square, constant, sech, sine, or explicit), each gate call with the samples its calibration spans, and the digests a pulse run's receipt binds (the program, its calibrations, the schedule). Durations are whole samples of dt (pulse.dt_ns, default 0.5 ns) or refused. A construct the reader does not take is refused with a Q code and its line. Sealed with the service's key. To run it, give the program to run_quantum_circuit with method "pulse". - -Parameters: -- `qasm` (string, required): A pulse program: OpenQASM 3 with `defcalgrammar "openpulse";`, `cal` blocks declaring ports (d0 drives qubit 0, m0 is its measurement port, a0 its acquisition port), frames (newframe(port, frequency Hz, phase)) and waveforms, a `defcal` for every gate it calls on physical qubits ($0), and the calls. -- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. - -### `pulse_check`: Check a pulse run by running it again - -Check a pulse job as a host returned it ({"request", "result"}, the result with its receipt): the receipt's signature, the program's digest against the request's text, and the request run again here with the result held to the one given field by field (the density matrix's digest among them), each difference named. A pulse run is the same bits on every platform, so a result that does not reproduce was not made from that request by this engine. Sealed with the service's key. Quote `verified` and the statement. - -Parameters: -- `request` (object, required): The pulse job's request. -- `result` (object, required): Its result, with its receipt. - -### `gradient_qasm`: The exact gradient of a Hamiltonian's expectation by a program's parameters - -The expectation E = ⟨ψ|H|ψ⟩ of a Hamiltonian at a program's parameters, and its gradient by each parameter, exactly: by adjoint differentiation or the parameter-shift rule on the double-precision state vector (at most 20 qubits, no noise, measurements only at the end). The reader follows each parameter into the gates, so an argument may be any expression of the built-in functions. The answer states its method, that it is f64 and approximate, and a bound on the rounding of the value and of each component (precision.rounding_bound). Sealed with the service's key. Quote the gradient with its bound. - -Parameters: -- `qasm` (string, required): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). -- `params` (object, required): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). -- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. -- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. - -### `optimize_qasm`: Minimise a Hamiltonian's expectation over a program's parameters - -Minimise E = ⟨ψ|H|ψ⟩ over a program's parameters from the given params, deterministically: gradient descent with a fixed step, Adam, or SPSA from a seeded stream (at most 2000 steps). Every step's parameters and value (and gradient, or SPSA's perturbation and estimate) are listed, each step a link of a digest chain from the request, best and final given; the same request gives the same bytes on every platform. Sealed with the service's key: the receipt binds the program, every step, the method and the seed, and verify_quantum_result (or wai-quantum verify) re-runs it. A minimum found is a minimum along this path, not a proof of the global one. - -Parameters: -- `qasm` (string, required): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). -- `params` (object, required): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). -- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. -- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). -- `steps` (integer): Steps to take (default 100). -- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). -- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. -- `seed` (integer): SPSA's seed (default 1). - -### `vqe_ground_state`: Find a Hamiltonian's ground energy by the variational eigensolver - -The variational eigensolver: an ansatz (the program given as qasm with params, or ansatz {"layers": L}: layers of ry and rz on every qubit and a ring of cx, its parameters t0, t1, … from 0.1) optimised on the Hamiltonian as optimize_qasm does. At most 8 qubits the answer sets the energy found beside the exact ground energy by diagonalisation (reference.ground_energy and gap); the energy found is never below it. Sealed with the service's key. Report the gap: an ansatz that cannot reach the ground state stops above it. - -Parameters: -- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. -- `qasm` (string): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). -- `params` (object): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). -- `ansatz` (object): The built-in ansatz in place of qasm (layers default 2, qubits the Hamiltonian's). -- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). -- `steps` (integer): Steps to take (default 100). -- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). -- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. -- `seed` (integer): SPSA's seed (default 1). - -### `qaoa_maxcut`: Solve Max-Cut on a graph by QAOA - -Max-Cut by the quantum approximate optimisation algorithm: the program (|+⟩ⁿ, then for each layer rzz(gamma·w) on every edge and rx(2·beta) on every qubit) and its cost Hamiltonian built from the graph (at most 20 vertices, 16 layers), optimised as optimize_qasm does from the params or a linear ramp, and read against the maximum cut found by brute force: the expected cut and its ratio to the maximum, the likeliest assignment and whether it is optimal, and the probability of an optimal one. Sealed with the service's key. - -Parameters: -- `graph` (object, required) -- `layers` (integer): QAOA's p (default 1). -- `params` (object): gamma_0, beta_0, … to start from. -- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). -- `steps` (integer): Steps to take (default 100). -- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). -- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. -- `seed` (integer): SPSA's seed (default 1). - -### `build_algorithm`: Write the program for a standard algorithm, checked against its reference - -An OpenQASM 3 program for a standard algorithm, with how to read its result, what it gives, and the equivalence ladder's verdict on it against a reference matrix or truth table built from the definitions (check: exact on every basis state up to 8 qubits, the adder's up to 16; past that unchecked). qpe: the phase φ of p(2πφ) on counting qubits; amplitude_estimation: the amplitude a that A = ry(2·arcsin √a) gives the good state, by phase estimation of the Grover operator; adder: the ripple-carry adder of bits-bit integers in place (with a and b, prepared and measured); qsvt: quantum signal processing from phases, of a signal x or of a real symmetric 2 × 2 matrix through its block encoding (all phases zero give the Chebyshev polynomial). Sealed with the service's key. Run the program with run_quantum_circuit. - -Parameters: -- `algorithm` (any, required, one of qpe, amplitude_estimation, adder, qsvt) -- `counting` (integer): qpe, amplitude_estimation: counting qubits (default 4). -- `phase` (number): qpe: the phase φ, in turns. -- `amplitude` (number): amplitude_estimation: the good state's probability a. -- `bits` (integer): adder: the integers' width. -- `a` (integer): adder: the first addend, prepared. -- `b` (integer): adder: the second, which the sum replaces. -- `carry_in` (boolean): adder: a carry in. -- `phases` (array): qsvt: φ₀ … φ_d, radians. -- `x` (number): qsvt: the signal. -- `matrix` (array): qsvt: [[a, b], [b, c]], real and symmetric, its eigenvalues within [-1, 1]. - ## Resources, on both servers ### `wai-quantum://docs/language`: the OpenQASM the engine reads @@ -980,8 +775,7 @@ Each construct below is supported (read as the language defines it), lowered (re | `array[T, d1, d2, …]`, nested values, `sizeof` | supported | Q107, Q110 | | `const` | supported: known on reading; not assignable | Q127 | | `input int n;`, `input uint n;` | supported: given when the program is read (a generator) | Q114 | -| `input float theta;`, `input angle phi;` | a parameter: a job's `params` binds it as a `const` at exactly the double given before the program is read (left without a value, the job is refused with Q114 and J050); the reader alone gives it no value | Q115 | -| a parameter followed into a gradient | supported through arithmetic, the built-in functions, loops and gate definitions into gates' arguments; refused under a modifier, in a classical variable, a condition, an index, a size, a loop's range, a subroutine, or a type that rounds it | Q129 | +| `input` of another type | refused: only integers take values | Q115 | | `output` | carried into the result: a bit register's places in each outcome, or a value | Q600, Q601 | | `let a = q[0:2] ++ r;` | supported; a `let` that reuses an enclosing scope's name is refused | Q101 | | `extern f(…) -> T;` | supported as a declaration; a call is refused | Q125 | @@ -1081,15 +875,9 @@ Each construct below is supported (read as the language defines it), lowered (re | Construct | Status | Codes | |---|---|---| -| `defcalgrammar "openpulse";` | preserved; in a pulse run, read (another grammar is refused) | Q452, Q454 | -| `cal { … }` | preserved, never run by the circuit methods; in a pulse run, read as OpenPulse and run in order | Q451, Q453 | -| `defcal …` | preserved, never run by the circuit methods; the gate's matrix comes from its definition or the library. In a pulse run, read as OpenPulse and run at each call on its physical qubits | Q450, Q126, Q453, Q459 | -| Ports, frames, waveforms (`constant`, `gaussian`, `sech`, `gaussian_square`, `drag`, `sine`, explicit samples) | in a pulse run, lowered to the schedule | Q453, Q455 to Q458 | -| `play`, `delay`, `shift_phase`, `set_phase`, `shift_frequency`, `set_frequency`, `capture_v0` to `capture_v4`, `barrier` | in a pulse run, lowered to the schedule on frames | Q453, Q457, Q458, Q461 | -| Plays on a measurement port | in a pulse run, scheduled and timed; the readout is not simulated | Q462 | - -A pulse run is the job method `pulse`; [the pulse page](pulse.md) gives the -model, the bound and the options. +| `defcalgrammar "openpulse";` | preserved | Q452 | +| `cal { … }` | preserved, never run | Q451 | +| `defcal …` | preserved, never run; the gate's matrix comes from its definition or the library | Q450, Q126 | #### The bit-exact method @@ -1120,6 +908,7 @@ A program that measures a qubit and then acts on it, resets one after its first - On this machine: `wai-quantum run`, or the local MCP server (`wai-quantum mcp`). Results are signed with the user's key and nothing leaves the machine. - On the free job service, for a program too large for this machine: `wai-quantum submit`, `POST https://wai.transaction.science/quantum-jobs/v1/run`, or its MCP server at https://wai.transaction.science/quantum-jobs/mcp. No account and no key. - auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen. +- The statevector method's state runs where the job's `fabric` says: auto (the default) places a state of 20 qubits or more on the first accelerator member of the fabric found here and certified bit-exact against the CPU (`wai-quantum fabric`, or list_fabric, lists them), and keeps a smaller one on the CPU; cpu, accelerator (any certified accelerator member) or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere. ### `wai-quantum://docs/diagnostics`: the reader's diagnostics @@ -1184,7 +973,6 @@ Every code: | `Q126` | refused | A call of an `opaque` gate, or of a gate with only a calibration: its matrix is not known. | | `Q127` | refused | An assignment to a constant, an input or a loop variable. | | `Q128` | refused | A measurement where a value is needed that is not a bit (measurement gives bits, into a bit register). | -| `Q129` | refused | A parameter (`input float`, `input angle`) a gradient cannot follow to the gates: under a modifier, in a classical variable, a condition, an index, a size, a loop's range, a subroutine or `gphase`, or one whose type rounds it (`angle[n]`, `float[32]`); a gradient follows a parameter through arithmetic, the built-in functions and gate definitions into a gate's arguments. | | `Q200` | lowered | A `gate` the program defines, inlined at each call with its parameters bound. | | `Q201` | lowered | `ctrl @` and `negctrl @` on any gate, lowered exactly to standard gates (a negative control is a control between two `x`). | | `Q202` | lowered | `inv @` on any gate, user gates included: each gate's exact inverse, in reverse order. | @@ -1232,40 +1020,11 @@ Every code: | `Q450` | preserved | `defcal`: kept verbatim for export, never executed; the gate's matrix comes from its `gate` definition or the standard library. | | `Q451` | preserved | `cal { … }`: kept verbatim for export, never executed. | | `Q452` | preserved | `defcalgrammar`: kept verbatim for export. | -| `Q453` | lowered | In a pulse run, a `cal` or `defcal` body read as OpenPulse and lowered to the schedule on frames (plays, delays, phase and frequency changes, captures and barriers) that the pulse simulator integrates. | -| `Q454` | refused | In a pulse run, a `defcalgrammar` other than `"openpulse"`: the pulse reader reads OpenPulse alone. | -| `Q455` | refused | A statement in a calibration that the pulse reader does not take: classical control, a frame's attributes or `get_phase`, an `extern` function, a frame made inside a `defcal`, a nested calibration, or a `defcal` over qubit arguments (the message names it and what to write instead). | -| `Q456` | refused | A waveform that does not read: a template the reader does not know, arguments of the wrong number or kind, a length or a width that is not positive, a sample that is not a number, or more samples than it holds. | -| `Q457` | refused | A frame or a port that does not read: a play, a delay or a phase or frequency change on a name that is not a frame, `newframe` on a name that is not a port, a frequency that is not a number, or a port that reaches no qubit. | -| `Q458` | refused | A duration in a calibration that is not a whole, non-negative number of samples at the sample period (`dt`), or a schedule longer than the reader holds. | -| `Q459` | refused | In a pulse run, a gate or a measurement on physical qubits that no `defcal` calibrates for those qubits and those parameters. | -| `Q460` | refused | In a pulse run, a statement outside the calibrations that the pulse reader does not take: declared qubits (a pulse program names physical qubits, `$0`), a modifier, `reset`, classical control, a subroutine, or a measurement into something other than a bit. | -| `Q461` | refused | A capture that does not read: not on a frame of an acquisition port, without a duration or a waveform, or its result put somewhere other than a bit. | -| `Q462` | warned | A play on a measurement port: scheduled and timed, its effect on the readout not simulated (a capture reads the qubit's state). | | `Q500` | refused | An angle that is not a dyadic multiple of 2π (2πm/2^k, k ≤ 32): the bit-exact method refuses it, never rounds it; the methods in double precision take it. | | `Q501` | refused | More than 255 qubits for the bit-exact circuit. | | `Q502` | refused | A program that measures a qubit and then acts on it, resets one after its first gate, or acts on measured bits: the bit-exact circuit takes programs whose measurements all come at the end. | | `Q600` | carried | An `output` declaration, carried into the result: its bits (their places in each outcome) or its value. | | `Q601` | refused | An `output` that is not a bit and whose value depends on a measurement at the end. | -| `Q700` | refused | A file that does not read in the format named: QIR that is not LLVM text with one entry point, or jeff that is not a Cap'n Proto message of the jeff schema (a pointer outside the message, a struct or list of the wrong shape, more than the reader takes); the message says what and where. | -| `Q701` | refused | A format version the reader does not take: QIR whose `qir_major_version` is not 1 or 2, or jeff other than 0.2 and 0.3. | -| `Q702` | warned | A QIR module that leaves out what its profile requires (the `qir_profiles` attribute, the version flags, `required_num_qubits`, `required_num_results`, the `entry_point` attribute of its only function): read from what it holds, and said so. | -| `Q703` | refused | A QIR profile the reader does not take: `qir_profiles` names neither `base_profile` nor `adaptive_profile`. | -| `Q704` | refused | What the module's own QIR profile forbids: under the base profile a branch, a classical instruction, reading a result, or a gate or reset on a qubit after its measurement; under the adaptive profile an optional capability its module flags do not declare (computation on integers or floats of a type, IR-defined functions, loops, `switch`, several returns, dynamic qubits or results, arrays). | -| `Q705` | refused | A QIR capability the module may use that this reader does not take: loops, `switch`, `phi`, IR-defined functions, dynamic allocation of qubits or results, arrays, controlled forms that take their controls in an array, or a classical value computed from a measurement anywhere but a branch's condition. | -| `Q706` | refused | An instruction or function the reader does not know: a quantum intrinsic outside the gates it reads (`docs/formats.md` lists them), a runtime function it does not take, an LLVM instruction no profile lists, or a function a module declares and does not define. | -| `Q707` | refused | A QIR operand that does not read: a qubit or result that is not a constant index, an index past `required_num_qubits` or `required_num_results`, or an angle that is not a finite number known on reading. | -| `Q708` | refused | A value whose meaning the program's text cannot keep: in QIR a result read, measured again and only then branched on; in jeff a qubit the two sides of a branch on a measurement leave in different places. | -| `Q709` | warned | Rotations at angles that are not dyadic multiples of 2π, read at their exact doubles: the double-precision methods take them; the bit-exact method refuses them (Q500). | -| `Q710` | refused | A jeff custom gate the reader does not know: its name is not a gate of the standard library (in any case), or its qubits or parameters are not that gate's. | -| `Q711` | warned | A jeff custom gate named as a gate of the standard library (`H`, `CX`, `Rx`, in any case) with that gate's qubits and parameters: read as that gate, by its name alone. | -| `Q712` | lowered | A jeff Pauli-product rotation, `exp(iθP)` as its schema defines it, lowered exactly to basis changes, a parity ladder and one `rz`. | -| `Q713` | refused | A jeff value used where it cannot be: a qubit or register used twice, a value used before it is defined or never defined, a cycle, or a value of the wrong type or count for its operation. | -| `Q714` | refused | A jeff value the reader needs on reading and cannot know: a gate angle, a loop's bounds or a `while` condition from a measurement, a register's size or index, a `switch` on a value that is neither known nor a measured bit, or integer arithmetic on a measured bit beyond not, and, or, xor, eq and select. | -| `Q715` | lowered | jeff's structured control flow: a `for` or `while` decided on reading unrolled, a `switch` on a known value decided, a `switch` on a measured bit written as `if … else`, and a call of a function the module defines inlined. | -| `Q716` | warned | A jeff entry point that takes qubits: they are the program's first qubits, starting in \|0⟩, and the qubits it returns are not measured. | -| `Q720` | refused | A program the format written cannot hold as it is: under QIR's base profile a measurement in the middle, a reset after a gate or a condition (write the adaptive profile), a loop in QIR, or in jeff a branch on a measured bit. | -| `Q721` | warned | What the format read or written has no place for, left out and said so: delays, boxes, barriers and gate durations, calibrations, `output` declarations, and classical values recorded as output. | ### `wai-quantum://docs/methods`: the methods and their accuracy classes @@ -1282,7 +1041,6 @@ Every code: | `cutrank_single` | single | as for cutrank; the table on a GPU, its arithmetic in single precision | counts, amplitudes | | `density_matrix` | exact | any, with noise | counts, expectations | | `trajectories` | estimate | any, with noise | counts, expectations | -| `pulse` | bounded | pulse programs: OpenPulse calibrations (cal, defcal) on physical qubits, every gate called with its calibration | counts, populations, captures | The accuracy classes: @@ -1294,6 +1052,8 @@ The accuracy classes: auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen. +The statevector method's state runs where the job's `fabric` says: auto (the default) places a state of 20 qubits or more on the first accelerator member of the fabric found here and certified bit-exact against the CPU (`wai-quantum fabric`, or list_fabric, lists them), and keeps a smaller one on the CPU; cpu, accelerator (any certified accelerator member) or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere. + ### `wai-quantum://examples`: worked examples, each with what it must do #### A Bell pair (`bell.qasm`) @@ -1533,10 +1293,6 @@ Commands: run Run a program here, planned as the job service plans it, and sign the result plan Show the method a program would run on and why, without running it instance Write a generator out at its `--input` values, as plain OpenQASM - convert Carry a program between formats (OpenQASM 3, QIR as LLVM text, jeff), every - conversion checked: what is written is read back and held to the program by the - equivalence ladder; notes and the check go to standard error (exit 1 refused, 2 the - check found it different) lint Check a program and print each problem with its line draw Draw a program's circuit: as text, or as an SVG image, LaTeX (plain TikZ) or words debug Step through a program on the engine's exact methods and look into the state at a @@ -1560,18 +1316,6 @@ Commands: Toffolis, rotations at their synthesised T counts, depth, qubits with ancillas), physical qubits, runtime and factories, and the frontier between qubits and time, each estimate signed (`wai-quantum estimate --help`) - gradient The expectation of a Hamiltonian at a program's parameters and its exact gradient by - each (adjoint differentiation or the parameter-shift rule, in f64 with a stated - rounding bound), signed - optimize Minimise a Hamiltonian's expectation over a program's parameters: gradient descent, - Adam or SPSA from a seed, every step in a digest chain the receipt seals - vqe The variational eigensolver: an ansatz optimised on a Hamiltonian, the energy found - set beside the exact ground energy by diagonalisation - qaoa Max-Cut on a graph by QAOA: the program and its cost built from the graph, optimised, - and the cut set beside the maximum cut by brute force - build A standard algorithm's program (qpe, amplitude_estimation, adder, qsvt) on standard - output, checked by the equivalence ladder against a reference built from its - definition repair Repair a program from its diagnostics, on the lines they flag alone: the mechanical fixes, a proposed fix checked against those lines, and what needs a person (exit 0 it reads, 1 something needs a person, 2 a proposal rejected) @@ -1586,6 +1330,10 @@ Commands: version This binary's version and the engine's, the schema of each document it writes, the protocols it speaks, and where the policy is that says what each version promises methods Each method, what it takes, and how far it reaches in a job's memory here + fabric The members of the fabric a statevector job can be placed on here (`run --fabric`): + the CPU and each accelerator this build reaches that is found and certified bit-exact + against the CPU, each with the most qubits it holds; the devices found and not + placed, and why diagnostics The diagnostic codes: the OpenQASM reader's (each with its outcome: refused, lowered, carried, preserved or warned) and the job layer's (refused or retry), each with its meaning @@ -1621,9 +1369,6 @@ Commands: qec Error correction: a code and its certified distance, a syndrome or a circuit's detectors decoded, a threshold measured, each answer signed (`wai-quantum qec --help`) - pulse Pulse programs: a program's schedule on frames drawn as a timeline, and a pulse job - checked by running it again; a pulse program runs with `run --method pulse` - (`wai-quantum pulse --help`) eval Score a model on a task set with the engine: whether its program reads, the verdict's level and whether the intent holds, and the joules per solved task where its server's energy is metered; or write each task's answer three ways for a token count @@ -1658,10 +1403,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -1695,10 +1436,6 @@ Options: --seed The seed shots are sampled with (1 if not given) - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --method A method by name, or auto (the default) for the strongest the program admits; `wai-quantum methods` lists them @@ -1765,13 +1502,12 @@ Options: pea, pec, cdr, vd or readout, or its options as JSON ({"method": "pea", "factors": [1, 1.5, 2]}) - --pulse - A pulse run's options (with --method pulse), as JSON or a file of it: dt_ns, levels, - tolerance, substeps, qubits, couplings and ports (`wai-quantum pulse --help`) - - --param - A parameter's value, as theta=0.3 (repeatable): each `input float` and `input angle` of - the program, bound exactly (the job's "params"); in a sweep, the parameters it fixes + --fabric + Where the state vector runs (the statevector method): auto (the default: a certified + accelerator member from 20 qubits), cpu, accelerator, or a member's id or key + (`wai-quantum fabric` lists them); repeated, the state is split by its top qubits into one + partition on each member named, a power of two of them. A member certified bit-exact gives + the CPU's answers; a placement this host cannot honour is refused (J013) --json Print the job as the service returns it: request, plan, result and receipt @@ -1833,10 +1569,6 @@ Options: --seed The seed shots are sampled with (1 if not given) - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --method A method by name, or auto (the default) for the strongest the program admits; `wai-quantum methods` lists them @@ -1903,13 +1635,12 @@ Options: pea, pec, cdr, vd or readout, or its options as JSON ({"method": "pea", "factors": [1, 1.5, 2]}) - --pulse - A pulse run's options (with --method pulse), as JSON or a file of it: dt_ns, levels, - tolerance, substeps, qubits, couplings and ports (`wai-quantum pulse --help`) - - --param - A parameter's value, as theta=0.3 (repeatable): each `input float` and `input angle` of - the program, bound exactly (the job's "params"); in a sweep, the parameters it fixes + --fabric + Where the state vector runs (the statevector method): auto (the default: a certified + accelerator member from 20 qubits), cpu, accelerator, or a member's id or key + (`wai-quantum fabric` lists them); repeated, the state is split by its top qubits into one + partition on each member named, a power of two of them. A member certified bit-exact gives + the CPU's answers; a placement this host cannot honour is refused (J013) --json Print the plan as JSON @@ -1941,61 +1672,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - - -h, --help - Print help - - -V, --version - Print version -``` - -### `wai-quantum convert` - -```text -Carry a program between formats (OpenQASM 3, QIR as LLVM text, jeff), every conversion checked: what -is written is read back and held to the program by the equivalence ladder; notes and the check go to -standard error (exit 1 refused, 2 the check found it different) - -Usage: wai-quantum convert [OPTIONS] --to [FILE] - -Arguments: - [FILE] - The program; `-` or nothing reads standard input; its format is --from, else its - extension, else what its bytes look like - -Options: - --input - A value for a generator's integer `input`, as n=5 (repeat for each input): the program is - read as its family's circuit at those values - - --to - The format to write: qasm, qir or jeff - - --lang - The language of the words the command line writes itself, en or zh-CN (by default the one - LANG names); results, codes and the engine's own messages stay in English - - --profile - QIR's profile, base or adaptive: by default the base profile when the program's - measurements all come at the end, else the adaptive one - - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - - -o, --output - Write the program to this file (jeff is binary: give a file, or --json for its base64) - - --json - Print the conversion as JSON: the program (base64 for jeff), the program as OpenQASM, the - notes, what was read and written, and the check - - --no-check - Write it without the check - -h, --help Print help @@ -2026,10 +1702,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -2065,10 +1737,6 @@ Options: --svg The drawing as a standalone SVG image, the Studio's picture - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --latex The drawing as LaTeX: one picture in plain TikZ, which needs only \usepackage{tikz} @@ -2110,10 +1778,6 @@ Options: --line Stop before the first step on this line - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --outcomes The outcome of each measurement (and reset) the path meets, in order, as 0,1,1; the likelier when not given @@ -2168,10 +1832,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -2203,10 +1863,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -2241,10 +1897,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -2277,10 +1929,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -2316,10 +1964,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -2367,10 +2011,6 @@ Options: [default: clifford_t] - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --twirl Twirl each two-qubit Clifford gate with Paulis drawn from this seed (one instance; checked to be the same gate) @@ -2438,10 +2078,6 @@ Options: [default: 0.001] - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --qubit A reference qubit (us-e3, us-e4, ns-e3, ns-e4, meas-e4, meas-e6), `all` of them, or a JSON file describing one @@ -2484,345 +2120,6 @@ Options: Print version ``` -### `wai-quantum gradient` - -```text -The expectation of a Hamiltonian at a program's parameters and its exact gradient by each (adjoint -differentiation or the parameter-shift rule, in f64 with a stated rounding bound), signed - -Usage: wai-quantum gradient [OPTIONS] [FILE] - -Arguments: - [FILE] - The program; `-` or nothing reads standard input - -Options: - --input - A value for a generator's integer `input`, as n=5 (repeat for each input): the program is - read as its family's circuit at those values - - --param - A parameter's value, as theta=0.3 (repeatable): every `input float` and `input angle` the - program declares needs one - - --lang - The language of the words the command line writes itself, en or zh-CN (by default the one - LANG names); results, codes and the engine's own messages stay in English - - --term - A term of the Hamiltonian, as "Z0 Z1", "0.5 X2" or "-1.5" (a constant) (repeatable; the - terms are summed) - - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - - --hamiltonian - The Hamiltonian as a JSON list of terms, in place of --term - - --gradient - adjoint (the default: one pass forward, one back) or parameter_shift (each gate a - parameter moves run at shifted angles) - - --json - Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) - - --key - Sign with the key in this file (64 hex digits) - - --demo-key - Sign with the published demo key: the receipt then shows a result is unaltered, not who - signed it - - -h, --help - Print help - - -V, --version - Print version -``` - -### `wai-quantum optimize` - -```text -Minimise a Hamiltonian's expectation over a program's parameters: gradient descent, Adam or SPSA -from a seed, every step in a digest chain the receipt seals - -Usage: wai-quantum optimize [OPTIONS] [FILE] - -Arguments: - [FILE] - The program; `-` or nothing reads standard input - -Options: - --input - A value for a generator's integer `input`, as n=5 (repeat for each input): the program is - read as its family's circuit at those values - - --param - A parameter's value, as theta=0.3 (repeatable): every `input float` and `input angle` the - program declares needs one - - --lang - The language of the words the command line writes itself, en or zh-CN (by default the one - LANG names); results, codes and the engine's own messages stay in English - - --term - A term of the Hamiltonian, as "Z0 Z1", "0.5 X2" or "-1.5" (a constant) (repeatable; the - terms are summed) - - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - - --hamiltonian - The Hamiltonian as a JSON list of terms, in place of --term - - --gradient - adjoint (the default: one pass forward, one back) or parameter_shift (each gate a - parameter moves run at shifted angles) - - --optimizer - gradient_descent, adam (the default) or spsa, or its settings as JSON ({"name": "adam", - "beta1": 0.9}) - - --steps - Steps to take (default 100) - - --step-size - The step (gradient descent 0.1, Adam 0.05), or SPSA's gain a (0.2) - - --seed - SPSA's seed (default 1) - - --json - Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) - - --key - Sign with the key in this file (64 hex digits) - - --demo-key - Sign with the published demo key: the receipt then shows a result is unaltered, not who - signed it - - -h, --help - Print help - - -V, --version - Print version -``` - -### `wai-quantum vqe` - -```text -The variational eigensolver: an ansatz optimised on a Hamiltonian, the energy found set beside the -exact ground energy by diagonalisation - -Usage: wai-quantum vqe [OPTIONS] [FILE] - -Arguments: - [FILE] - The program; `-` or nothing reads standard input - -Options: - --input - A value for a generator's integer `input`, as n=5 (repeat for each input): the program is - read as its family's circuit at those values - - --param - A parameter's value, as theta=0.3 (repeatable): every `input float` and `input angle` the - program declares needs one - - --lang - The language of the words the command line writes itself, en or zh-CN (by default the one - LANG names); results, codes and the engine's own messages stay in English - - --term - A term of the Hamiltonian, as "Z0 Z1", "0.5 X2" or "-1.5" (a constant) (repeatable; the - terms are summed) - - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - - --hamiltonian - The Hamiltonian as a JSON list of terms, in place of --term - - --gradient - adjoint (the default: one pass forward, one back) or parameter_shift (each gate a - parameter moves run at shifted angles) - - --layers - The built-in ansatz in place of a program: this many layers of ry and rz on every qubit - and a ring of cx, its parameters t0, t1, … from 0.1 - - --qubits - With --layers: the ansatz's qubits (default the Hamiltonian's) - - --optimizer - gradient_descent, adam (the default) or spsa, or its settings as JSON ({"name": "adam", - "beta1": 0.9}) - - --steps - Steps to take (default 100) - - --step-size - The step (gradient descent 0.1, Adam 0.05), or SPSA's gain a (0.2) - - --seed - SPSA's seed (default 1) - - --json - Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) - - --key - Sign with the key in this file (64 hex digits) - - --demo-key - Sign with the published demo key: the receipt then shows a result is unaltered, not who - signed it - - -h, --help - Print help - - -V, --version - Print version -``` - -### `wai-quantum qaoa` - -```text -Max-Cut on a graph by QAOA: the program and its cost built from the graph, optimised, and the cut -set beside the maximum cut by brute force - -Usage: wai-quantum qaoa [OPTIONS] --graph - -Options: - --graph - The graph as JSON: {"nodes": n, "edges": [[0, 1], [1, 2, 0.5]]} - - --input - A value for a generator's integer `input`, as n=5 (repeat for each input): the program is - read as its family's circuit at those values - - --lang - The language of the words the command line writes itself, en or zh-CN (by default the one - LANG names); results, codes and the engine's own messages stay in English - - --layers - QAOA's layers, p (default 1) - - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - - --param - A starting value, as gamma_0=0.4 (repeatable; default a linear ramp) - - --gradient - adjoint (the default) or parameter_shift - - --optimizer - gradient_descent, adam (the default) or spsa, or its settings as JSON ({"name": "adam", - "beta1": 0.9}) - - --steps - Steps to take (default 100) - - --step-size - The step (gradient descent 0.1, Adam 0.05), or SPSA's gain a (0.2) - - --seed - SPSA's seed (default 1) - - --json - Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) - - --key - Sign with the key in this file (64 hex digits) - - --demo-key - Sign with the published demo key: the receipt then shows a result is unaltered, not who - signed it - - -h, --help - Print help - - -V, --version - Print version -``` - -### `wai-quantum build` - -```text -A standard algorithm's program (qpe, amplitude_estimation, adder, qsvt) on standard output, checked -by the equivalence ladder against a reference built from its definition - -Usage: wai-quantum build [OPTIONS] - -Arguments: - - qpe, amplitude_estimation, adder or qsvt - -Options: - --counting - qpe, amplitude_estimation: counting qubits (default 4) - - --input - A value for a generator's integer `input`, as n=5 (repeat for each input): the program is - read as its family's circuit at those values - - --lang - The language of the words the command line writes itself, en or zh-CN (by default the one - LANG names); results, codes and the engine's own messages stay in English - - --phase - qpe: the phase φ of p(2πφ), in turns - - --amplitude - amplitude_estimation: the good state's probability a - - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - - --bits - adder: the integers' width - - --a - adder: the first addend, prepared - - --b - adder: the second, which the sum replaces - - --carry-in - adder: a carry in - - --phases - qsvt: the phases φ0 … φd, in radians, as 0.1,-0.2,0.3 - - --x - qsvt: the signal, within [-1, 1] - - --matrix - qsvt: a real symmetric matrix [[a, b], [b, c]], as a,b,c - - --json - Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) - - --key - Sign with the key in this file (64 hex digits) - - --demo-key - Sign with the published demo key: the receipt then shows a result is unaltered, not who - signed it - - -h, --help - Print help - - -V, --version - Print version -``` - ### `wai-quantum repair` ```text @@ -2857,10 +2154,6 @@ Options: Round each angle the bit-exact method refuses (Q500) to the nearest multiple of 2π/2^K, its rounding stated on its line - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --size A register's size, for one used before it is declared (Q102), as q=3 (repeatable) @@ -2908,10 +2201,6 @@ Options: --seed The seed shots are sampled with (1 if not given) - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --method A method by name, or auto (the default) for the strongest the program admits; `wai-quantum methods` lists them @@ -2978,13 +2267,12 @@ Options: pea, pec, cdr, vd or readout, or its options as JSON ({"method": "pea", "factors": [1, 1.5, 2]}) - --pulse - A pulse run's options (with --method pulse), as JSON or a file of it: dt_ns, levels, - tolerance, substeps, qubits, couplings and ports (`wai-quantum pulse --help`) - - --param - A parameter's value, as theta=0.3 (repeatable): each `input float` and `input angle` of - the program, bound exactly (the job's "params"); in a sweep, the parameters it fixes + --fabric + Where the state vector runs (the statevector method): auto (the default: a certified + accelerator member from 20 qubits), cpu, accelerator, or a member's id or key + (`wai-quantum fabric` lists them); repeated, the state is split by its top qubits into one + partition on each member named, a power of two of them. A member certified bit-exact gives + the CPU's answers; a placement this host cannot honour is refused (J013) --json Print the job as the service returns it: request, plan, result and receipt @@ -3053,10 +2341,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --service The service's address @@ -3097,10 +2381,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --service The service's address @@ -3141,10 +2421,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --service The service's address @@ -3189,10 +2465,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --service The service's address @@ -3238,10 +2510,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --service The service's address @@ -3286,10 +2554,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --service The service's address @@ -3335,10 +2599,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --service The service's address @@ -3383,10 +2643,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --service The service's address @@ -3427,10 +2683,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --service The service's address @@ -3478,10 +2730,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -3512,10 +2760,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -3543,10 +2787,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -3578,9 +2818,38 @@ Options: [default: 16] - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help + Print help + + -V, --version + Print version +``` + +### `wai-quantum fabric` + +```text +The members of the fabric a statevector job can be placed on here (`run --fabric`): the CPU and each +accelerator this build reaches that is found and certified bit-exact against the CPU, each with the +most qubits it holds; the devices found and not placed, and why + +Usage: wai-quantum fabric [OPTIONS] + +Options: + --input + A value for a generator's integer `input`, as n=5 (repeat for each input): the program is + read as its family's circuit at those values + + --json + Print the list as JSON + + --lang + The language of the words the command line writes itself, en or zh-CN (by default the one + LANG names); results, codes and the engine's own messages stay in English + + --memory-gb + The memory a job may take, GiB + + [default: 16] -h, --help Print help @@ -3609,10 +2878,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -3645,10 +2910,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --memory-gb The memory a job may take, GiB @@ -3696,10 +2957,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --memory-gb The memory a job may take, GiB, when not the server's default @@ -3735,10 +2992,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --name The name the entry goes under @@ -3791,10 +3044,6 @@ Options: --write Write each file back formatted - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -3832,10 +3081,6 @@ Options: Sign with the published demo key: the receipt then shows a result is unaltered, not who signed it - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --stdio Accepted for the editors that pass it: standard input and output is the server's only transport @@ -3875,10 +3120,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -3916,10 +3157,6 @@ Options: Sign with the published demo key: the receipt then shows a result is unaltered, not who signed it - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -3955,10 +3192,6 @@ Options: [default: 1] - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --max-edits Edits made to a parent before it is evaluated, at most @@ -4017,10 +3250,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4057,10 +3286,6 @@ Options: --parent The id of the archive entry it came from - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --proposer Who wrote it @@ -4112,10 +3337,6 @@ Options: --source Print one entry's generator, by id - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --json Print the summary as JSON @@ -4149,10 +3370,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4190,10 +3407,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4232,10 +3445,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4274,10 +3483,6 @@ Options: [default: person] - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --name Which one: a model's or an agent's name, the rewrite, where the program came from @@ -4324,10 +3529,6 @@ Options: --locks The rules a proposal must keep (default: beside the program, as NAME.locks.json, if there) - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --parent The version it was changed from (default: the head) @@ -4385,10 +3586,6 @@ Options: --locks The rules a proposal must keep (default: beside the program, as NAME.locks.json, if there) - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --parent @@ -4434,10 +3631,6 @@ Options: --accept The changes accepted: their numbers from `changes` (as 0,2), all, or none - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --parent @@ -4503,10 +3696,6 @@ Options: [default: person] - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --name Which one: a model's or an agent's name, the rewrite, where the program came from @@ -4553,10 +3742,6 @@ Options: --locks The rules a proposal must keep (default: beside the program, as NAME.locks.json, if there) - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --json @@ -4596,10 +3781,6 @@ Options: --locks The rules a proposal must keep (default: beside the program, as NAME.locks.json, if there) - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --json @@ -4637,10 +3818,6 @@ Options: --locks The rules a proposal must keep (default: beside the program, as NAME.locks.json, if there) - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --job A job from `run --json --history` or the service @@ -4679,10 +3856,6 @@ Options: The program it is meant to improve on: the measures it beats it on that --weigh does not name - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --weigh The measures the cost weighs, comma-separated (as depth,two_qubit) @@ -4718,10 +3891,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4758,10 +3927,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4792,10 +3957,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4829,10 +3990,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4867,10 +4024,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4908,10 +4061,6 @@ Options: Sign with the published demo key: the receipt then shows a result is unaltered, not who signed it - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4935,10 +4084,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -4969,10 +4114,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5014,10 +4155,6 @@ Options: Sign with the published demo key: the receipt then shows a result is unaltered, not who signed it - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --json @@ -5052,10 +4189,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5090,10 +4223,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5130,10 +4259,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5166,10 +4291,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5200,10 +4321,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5237,10 +4354,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5271,10 +4384,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5308,10 +4417,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5345,10 +4450,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5387,10 +4488,6 @@ Options: [default: equivalent] - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --profile The profile's name: one person can keep several (for teaching, for one device) @@ -5430,10 +4527,6 @@ Options: --taste The file the profiles are kept in - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --json @@ -5470,10 +4563,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --novelty The novelty dial: −1 toward the typical, 1 toward the novel @@ -5524,10 +4613,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --task `prepares` or `equivalent` (a specification's own task by default) @@ -5573,10 +4658,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5613,10 +4694,6 @@ Options: --check Check this certificate (a sealed answer or the certificate alone) against the code - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --json Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) @@ -5659,10 +4736,6 @@ Options: --error The flipped qubits, as 3,12 (its syndrome is decoded and its residual judged) - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --memory The rotated surface-code memory experiment, as DISTANCE,ROUNDS,P @@ -5729,10 +4802,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --p Physical rates, as 0.002,0.004 @@ -5765,133 +4834,6 @@ Options: Print version ``` -### `wai-quantum pulse` - -```text -Pulse programs: a program's schedule on frames drawn as a timeline, and a pulse job checked by -running it again; a pulse program runs with `run --method pulse` (`wai-quantum pulse --help`) - -Usage: wai-quantum pulse [OPTIONS] - -Commands: - schedule A pulse program's schedule: each frame's timeline, every instruction at its sample, the - waveforms and the gate calls - check A pulse job (`run --method pulse --json`) checked: its receipt, its program's digest, - and the request run again here, its result held to the one given - help Print this message or the help of the given subcommand(s) - -Options: - --input - A value for a generator's integer `input`, as n=5 (repeat for each input): the program is - read as its family's circuit at those values - - --lang - The language of the words the command line writes itself, en or zh-CN (by default the one - LANG names); results, codes and the engine's own messages stay in English - - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - - -h, --help - Print help - - -V, --version - Print version -``` - -### `wai-quantum pulse schedule` - -```text -A pulse program's schedule: each frame's timeline, every instruction at its sample, the waveforms -and the gate calls - -Usage: wai-quantum pulse schedule [OPTIONS] [FILE] - -Arguments: - [FILE] - The program; `-` or nothing reads standard input - -Options: - --input - A value for a generator's integer `input`, as n=5 (repeat for each input): the program is - read as its family's circuit at those values - - --pulse - The pulse options, as JSON or a file of it (only dt_ns and ports matter here) - - --lang - The language of the words the command line writes itself, en or zh-CN (by default the one - LANG names); results, codes and the engine's own messages stay in English - - --width - The timeline's width, in columns - - [default: 60] - - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - - --json - Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) - - --key - Sign with the key in this file (64 hex digits) - - --demo-key - Sign with the published demo key: the receipt then shows a result is unaltered, not who - signed it - - -h, --help - Print help - - -V, --version - Print version -``` - -### `wai-quantum pulse check` - -```text -A pulse job (`run --method pulse --json`) checked: its receipt, its program's digest, and the -request run again here, its result held to the one given - -Usage: wai-quantum pulse check [OPTIONS] [FILE] - -Arguments: - [FILE] - The job, as `run --json` or the service returns it; `-` reads standard input - -Options: - --input - A value for a generator's integer `input`, as n=5 (repeat for each input): the program is - read as its family's circuit at those values - - --json - Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) - - --key - Sign with the key in this file (64 hex digits) - - --lang - The language of the words the command line writes itself, en or zh-CN (by default the one - LANG names); results, codes and the engine's own messages stay in English - - --demo-key - Sign with the published demo key: the receipt then shows a result is unaltered, not who - signed it - - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - - -h, --help - Print help - - -V, --version - Print version -``` - ### `wai-quantum eval` ```text @@ -5918,10 +4860,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -5954,10 +4892,6 @@ Options: The model server: a chat-completions endpoint on this machine or a private network, as http://127.0.0.1:8080/v1 - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --name The model's name as its server knows it (default: the server's own) @@ -6029,10 +4963,6 @@ Options: -o, --out Write the corpus here (default: standard output) - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6061,10 +4991,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6101,10 +5027,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6141,10 +5063,6 @@ Options: [default: 16] - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --junit Also write the verdict as a JUnit report to this file, one test case for each intent @@ -6189,10 +5107,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6239,10 +5153,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help (see a summary with '-h') @@ -6280,10 +5190,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --json Print the course and your progress as JSON @@ -6317,10 +5223,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6354,10 +5256,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6392,10 +5290,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6432,10 +5326,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6470,10 +5360,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6503,10 +5389,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6541,10 +5423,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6582,10 +5460,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --provider Read one of your providers' describe answers instead of a file (`wai-quantum providers list`) @@ -6622,10 +5496,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6659,10 +5529,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --view Print what the Studio draws: each qubit's place and errors, each pair's error @@ -6693,10 +5559,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6720,10 +5582,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6763,10 +5621,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6805,10 +5659,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - --set A setting that is not a secret, as backend=NAME (repeatable) @@ -6849,10 +5699,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6880,10 +5726,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6915,10 +5757,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6953,10 +5791,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -6989,10 +5823,6 @@ Options: [default: 16] - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -7021,10 +5851,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help @@ -7052,10 +5878,6 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English - --from - The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default - the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise - -h, --help Print help diff --git a/wai/wai-quantum-cli/docs/llms.txt b/wai/wai-quantum-cli/docs/llms.txt index ecbd0187c..933973900 100644 --- a/wai/wai-quantum-cli/docs/llms.txt +++ b/wai/wai-quantum-cli/docs/llms.txt @@ -73,6 +73,7 @@ Runs on this machine, signed with the user's key; nothing leaves the machine. - `history_blame`: Whose hand each line and gate is in - `history_log`: A program's history - `list_methods`: List the methods +- `list_fabric`: List the fabric's members - `qasm_diagnostics`: The reader's diagnostic codes - `list_targets`: List the device targets - `show_target`: Show a device target diff --git a/wai/wai-quantum-cli/docs/local-mcp.json b/wai/wai-quantum-cli/docs/local-mcp.json index 1d1708a7d..dd98785fc 100644 --- a/wai/wai-quantum-cli/docs/local-mcp.json +++ b/wai/wai-quantum-cli/docs/local-mcp.json @@ -160,6 +160,24 @@ "target": { "description": "A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it." }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "intent": { "description": "What the program must do, checked by the engine with the run: the result's \"verdict\" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt.", "anyOf": [ @@ -1096,6 +1114,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -2284,6 +2320,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -2652,7 +3044,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -2673,6 +3065,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -3958,6 +4365,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -5144,6 +5569,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -5512,7 +6293,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -5533,6 +6314,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -7062,6 +7858,24 @@ "target": { "description": "A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it." }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "intent": { "description": "What the program must do, checked by the engine with the run: the result's \"verdict\" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt.", "anyOf": [ @@ -25794,6 +26608,211 @@ ] } }, + { + "name": "list_fabric", + "title": "List the fabric's members", + "description": "The members of the fabric a statevector job can be placed on here (a job's `fabric`): the CPU and each accelerator found and certified bit-exact against the CPU in this process, each with its key, its certificate and the most qubits it holds; the devices found and not placed, and why; and the backends this build reaches.", + "inputSchema": { + "type": "object", + "properties": {} + }, + "outputSchema": { + "$id": "wai-quantum://schemas/list_fabric/1", + "type": "object", + "description": "The members of the fabric a statevector job can be placed on here: the CPU reference and each accelerator certified bit-exact in this process, each with the most qubits it holds; the devices found and not placed, with why; why each backend the build reaches found none; and the backends it reaches.", + "anyOf": [ + { + "type": "object", + "description": "The members of the fabric a statevector job can be placed on here: the CPU reference and each accelerator certified bit-exact in this process, each with the most qubits it holds; the devices found and not placed, with why; why each backend the build reaches found none; and the backends it reaches.", + "required": [ + "kernel", + "members" + ], + "properties": { + "kernel": { + "type": "string" + }, + "auto_min_qubits": { + "type": "integer", + "minimum": 1, + "description": "The fewest qubits auto places on an accelerator member." + }, + "members": { + "type": "array", + "items": { + "type": "object", + "required": [ + "member", + "implementation", + "parity" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "detail": { + "type": "object", + "description": "The most qubits it holds and what bounds it; for an accelerator, its backend and what discovery found.", + "properties": { + "max_qubits": { + "type": "integer", + "minimum": 0 + }, + "memory": { + "type": "string" + }, + "backend": { + "type": "string" + }, + "device": { + "type": "string" + } + } + } + } + } + }, + "refused": { + "type": "array", + "items": { + "type": "object", + "properties": { + "backend": { + "type": "string" + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "why": { + "type": "string" + } + } + } + }, + "unavailable": { + "type": "array", + "items": { + "type": "object", + "properties": { + "backend": { + "type": "string" + }, + "why": { + "type": "string" + } + } + } + }, + "backends": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, { "name": "qasm_diagnostics", "title": "The reader's diagnostic codes", @@ -27377,6 +28396,24 @@ "target": { "description": "A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it." }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "intent": { "description": "What the program must do, checked by the engine with the run: the result's \"verdict\" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt.", "anyOf": [ @@ -28316,6 +29353,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -29504,6 +30559,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -29872,7 +31283,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -29893,6 +31304,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -31178,6 +32604,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -32364,6 +33808,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -32732,7 +34532,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -32753,6 +34553,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -46274,6 +48089,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -47462,6 +49295,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -47830,7 +50019,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -47851,6 +50040,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -49136,6 +51340,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -50322,6 +52544,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -50690,7 +53268,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -50711,6 +53289,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, diff --git a/wai/wai-quantum-cli/docs/service-mcp.json b/wai/wai-quantum-cli/docs/service-mcp.json index 6e55e5998..25b4b26f9 100644 --- a/wai/wai-quantum-cli/docs/service-mcp.json +++ b/wai/wai-quantum-cli/docs/service-mcp.json @@ -131,6 +131,24 @@ "target": { "description": "A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing." }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "intent": { "description": "What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt.", "anyOf": [ @@ -1101,6 +1119,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -2289,6 +2325,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -2657,7 +3049,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -2678,6 +3070,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -3963,6 +4370,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -5149,6 +5574,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -5517,7 +6298,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -5538,6 +6319,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -8382,6 +9178,24 @@ "target": { "description": "A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing." }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "intent": { "description": "What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt.", "anyOf": [ @@ -9356,6 +10170,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -10544,6 +11376,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -10912,7 +12100,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -10933,6 +12121,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -12218,6 +13421,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -13404,6 +14625,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -13772,7 +15349,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -13793,6 +15370,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -16637,6 +18229,24 @@ "target": { "description": "A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing." }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "intent": { "description": "What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt.", "anyOf": [ @@ -18641,6 +20251,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -19829,6 +21457,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -20197,7 +22181,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -20218,6 +22202,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -21503,6 +23502,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -22689,6 +24706,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -23057,7 +25430,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -23078,6 +25451,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -37820,6 +40208,24 @@ "target": { "description": "A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing." }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "intent": { "description": "What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt.", "anyOf": [ @@ -38783,6 +41189,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -39971,6 +42395,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -40339,7 +43119,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -40360,6 +43140,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -41645,6 +44440,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ @@ -42831,6 +45644,362 @@ } } }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "type": "object", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "energy": { + "description": "The CPU energy of the job's process as the kernel counts it, with its uncertainty and what it leaves out, or unmetered with the reason.", + "anyOf": [ + { + "type": "object", + "required": [ + "unmetered" + ], + "properties": { + "unmetered": { + "type": "string" + }, + "service_kwh": { + "type": "number", + "description": "A provider job: the provider's own figure." + }, + "service_kwh_is": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "joules_micro", + "energy_provenance", + "coverage" + ], + "properties": { + "joules_micro": { + "type": "integer", + "minimum": 1 + }, + "energy_provenance": { + "type": "string" + }, + "energy_uncertainty": { + "type": "object", + "properties": { + "relative_ppm": { + "type": "integer" + }, + "window_us": { + "type": "integer" + } + } + }, + "energy_counter_filtering": { + "type": "string" + }, + "coverage": { + "enum": [ + "whole", + "partial" + ] + }, + "covers": { + "type": "string" + }, + "excludes": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu_ms": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "attribution": { + "enum": [ + "process", + "none" + ], + "description": "Whose energy it is: the job's worker process, or none (the processor packages' over the job's window, every process on the host in it)." + }, + "packages": { + "type": "integer", + "minimum": 1, + "description": "The processor packages read." + }, + "concurrent_jobs": { + "type": "integer", + "minimum": 0, + "description": "Other jobs that ran on the host during the window." + }, + "counter": { + "type": "object", + "description": "The package counter as seen: the longest it went between updates, and the smallest step it took.", + "properties": { + "update_us": { + "type": "integer", + "minimum": 0 + }, + "step_uj": { + "type": "integer", + "minimum": 0 + } + } + }, + "declared": { + "type": "string", + "description": "What the stated uncertainty covers, and what it does not." + } + } + } + ] + }, + "why": { + "type": "string" + } + } + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -43199,7 +46368,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -43220,6 +46389,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -44687,6 +47871,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ diff --git a/wai/wai-quantum-cli/locales/zh-CN.json b/wai/wai-quantum-cli/locales/zh-CN.json index dbd0261f9..1f50ff8e6 100644 --- a/wai/wai-quantum-cli/locales/zh-CN.json +++ b/wai/wai-quantum-cli/locales/zh-CN.json @@ -62,6 +62,7 @@ "version": { "source": "This binary's version and the engine's, the schema of each document it writes, the protocols it speaks, and where the policy is that says what each version promises", "text": "本程序和引擎的版本、它所写的每种文档遵循的模式、它所使用的协议,以及说明每个版本作何承诺的策略所在之处" }, "key": { "source": "Show the key this user signs receipts with", "text": "显示本用户为回执签名所用的密钥" }, "methods": { "source": "Each method, what it takes, and how far it reaches in a job's memory here", "text": "每种方法、它接受什么,以及在本机作业内存中它能达到的规模" }, + "fabric": { "source": "The members of the fabric a statevector job can be placed on here (`run --fabric`): the CPU and each accelerator this build reaches that is found and certified bit-exact against the CPU, each with the most qubits it holds; the devices found and not placed, and why", "text": "本机上 statevector 作业可放置其上的计算结构成员(`run --fabric`):CPU,以及本构建可达、已找到并经认证与 CPU 逐位一致的每个加速器,各附其可容纳的最多量子比特数;以及找到但未放置的设备及其原因" }, "diagnostics": { "source": "The diagnostic codes: the OpenQASM reader's (each with its outcome: refused, lowered, carried, preserved or warned) and the job layer's (refused or retry), each with its meaning", "text": "诊断代码:OpenQASM 读取器的代码(各附其结果:refused、lowered、carried、preserved 或 warned)和作业层的代码(refused 或 retry),各附其含义" }, "mcp": { "source": "Serve run, plan, lint, critique, the equivalence check, improve, the classical shortcuts, compile, draw, the debugger and verify to an agent over standard input and output (MCP), with resources and prompts; `mcp config` and `mcp install` register it with a client", "text": "通过标准输入输出(MCP)向智能体提供 run、plan、lint、critique、等价检查、improve、经典捷径、compile、draw、调试器和 verify,以及资源和提示词;`mcp config` 和 `mcp install` 把它注册到客户端" }, "fmt": { "source": "Format programs in one layout: a statement to a line, blocks indented two spaces, a space around each operator, comments and blank lines kept; a program whose brackets do not match is left as it is, with its line", "text": "按统一的版式格式化程序:每行一条语句,块缩进两个空格,运算符两侧各留一个空格,保留注释和空行;括号不匹配的程序保持原样,并给出所在的行" }, diff --git a/wai/wai-quantum-cli/skills/wai-quantum/reference/tools.md b/wai/wai-quantum-cli/skills/wai-quantum/reference/tools.md index 2ad1158b4..e808b30b0 100644 --- a/wai/wai-quantum-cli/skills/wai-quantum/reference/tools.md +++ b/wai/wai-quantum-cli/skills/wai-quantum/reference/tools.md @@ -36,6 +36,7 @@ Generated by `wai-quantum docs skill` from the servers' own lists; `wai-quantum - `history_blame`: Whose hand each line and gate is in - `history_log`: A program's history - `list_methods`: List the methods +- `list_fabric`: List the fabric's members - `qasm_diagnostics`: The reader's diagnostic codes - `list_targets`: List the device targets - `show_target`: Show a device target diff --git a/wai/wai-quantum-cli/src/guide.rs b/wai/wai-quantum-cli/src/guide.rs index 3c814b610..7ac3b8eaa 100644 --- a/wai/wai-quantum-cli/src/guide.rs +++ b/wai/wai-quantum-cli/src/guide.rs @@ -585,7 +585,7 @@ pub fn llms_full() -> String { for (k, v) in wai_quantum::engine::catalog::accuracy_classes().as_object().into_iter().flatten() { s.push_str(&format!("- {k}: {}\n", v.as_str().unwrap_or(""))); } - s.push_str(&format!("\n{}\n", engine::AUTO)); + s.push_str(&format!("\n{}\n\n{}\n", engine::AUTO, engine::FABRIC)); s.push_str(&format!("\n### `{}`: worked examples, each with what it must do\n\n", engine::EXAMPLES)); for e in engine::examples() { s.push_str(&format!("#### {} (`{}`)\n\n{}\n\n```qasm\n{}```\n\n", e.title, e.file(), e.shows, e.program)); diff --git a/wai/wai-quantum-cli/src/main.rs b/wai/wai-quantum-cli/src/main.rs index cfd1ff20d..eb00740a4 100644 --- a/wai/wai-quantum-cli/src/main.rs +++ b/wai/wai-quantum-cli/src/main.rs @@ -330,6 +330,15 @@ enum Command { #[arg(long, default_value_t = DEFAULT_MEMORY_GB)] memory_gb: u64, }, + /// The members of the fabric a statevector job can be placed on here (`run --fabric`): the CPU and each accelerator this build reaches that is found and certified bit-exact against the CPU, each with the most qubits it holds; the devices found and not placed, and why + Fabric { + /// Print the list as JSON + #[arg(long)] + json: bool, + /// The memory a job may take, GiB + #[arg(long, default_value_t = DEFAULT_MEMORY_GB)] + memory_gb: u64, + }, /// The diagnostic codes: the OpenQASM reader's (each with its outcome: refused, lowered, carried, preserved or warned) and the job layer's (refused or retry), each with its meaning Diagnostics { /// Print the table as JSON @@ -532,6 +541,9 @@ struct Job { /// A parameter's value, as theta=0.3 (repeatable): each `input float` and `input angle` of the program, bound exactly (the job's "params"); in a sweep, the parameters it fixes #[arg(long = "param", value_name = "NAME=VALUE", value_parser = variational::param_arg)] params: Vec<(String, f64)>, + /// Where the state vector runs (the statevector method): auto (the default: a certified accelerator member from 20 qubits), cpu, accelerator, or a member's id or key (`wai-quantum fabric` lists them); repeated, the state is split by its top qubits into one partition on each member named, a power of two of them. A member certified bit-exact gives the CPU's answers; a placement this host cannot honour is refused (J013) + #[arg(long = "fabric", value_name = "PLACEMENT")] + fabric: Vec, } /// `name=v1,v2,…`: each value a whole number if it reads as one, else a number. @@ -595,6 +607,27 @@ fn option_arg(s: &str) -> Result<(String, Value), String> { Ok((k.to_string(), value)) } +/// The fabric's members as `wai-quantum fabric` prints them. +fn fabric_text(f: &Value) -> String { + let s = |v: &Value| v.as_str().unwrap_or("").to_string(); + let mut o = format!("kernel {} (auto places a state of {} qubits or more on the first accelerator listed that holds it)\n", s(&f["kernel"]), f["auto_min_qubits"]); + for m in f["members"].as_array().into_iter().flatten() { + let corpus = m["corpus"].as_str().map(|c| format!(", corpus {}… over {} cases", &c[..16.min(c.len())], m["cases"])).unwrap_or_default(); + o.push_str(&format!("member {:<18} {:<4} up to {} qubits, {} {}{corpus}\n", s(&m["key"]), s(&m["class"]), m["detail"]["max_qubits"], s(&m["implementation"]), s(&m["parity"]["tier"]))); + o.push_str(&format!(" {}\n", s(&m["member"]))); + } + for x in f["refused"].as_array().into_iter().flatten() { + o.push_str(&format!("not placed {} {}: {}\n", s(&x["backend"]), if x["key"].as_str().is_some_and(|k| !k.is_empty()) { s(&x["key"]) } else { s(&x["member"]) }, s(&x["why"]))); + } + for x in f["unavailable"].as_array().into_iter().flatten() { + o.push_str(&format!("none found {}: {}\n", s(&x["backend"]), s(&x["why"]))); + } + if f["backends"].as_array().is_none_or(Vec::is_empty) { + o.push_str("backends none in this build: the CPU alone (build with --features cuda, hip or opencl)\n"); + } + o +} + fn die(msg: &str) -> ! { eprintln!("wai-quantum: {msg}"); std::process::exit(1) @@ -790,6 +823,11 @@ fn request(job: &Job, qasm: String) -> Value { if !job.params.is_empty() { r["params"] = Value::Object(job.params.iter().map(|(k, v)| (k.clone(), json!(v))).collect()); } + match &job.fabric[..] { + [] => {} + [one] => r["fabric"] = json!(one), + many => r["fabric"] = json!(many), + } r } @@ -926,6 +964,13 @@ fn print_job(body: &Value, top: usize) { println!("accuracy {}{}", s(&acc["class"]), if extra.is_empty() { String::new() } else { format!(" ({})", extra.join("; ")) }); } println!("circuit {} qubits, {} gates", r["qubits"], r["gates"]); + if let Some(f) = r.get("fabric") { + let s = |v: &Value| v.as_str().unwrap_or("").to_string(); + match f.get("partitions").and_then(Value::as_array) { + Some(parts) => println!("fabric {} partitions on {}, {} exchanges, {}", parts.len(), parts.iter().map(|p| s(&p["key"])).collect::>().join(", "), f["exchanges"], s(&f["parity"]["tier"])), + None => println!("fabric {} ({}), {}, certificate {}", s(&f["key"]), s(&f["implementation"]), s(&f["parity"]["tier"]), s(&f["certificate"])), + } + } if let Some(w) = r.get("warning").and_then(Value::as_str) { println!("warning {w}"); } @@ -1377,6 +1422,14 @@ fn main() { } } } + Command::Fabric { json, memory_gb } => { + let f = wai_quantum::engine::fabric::list(memory_gb << 30); + if json { + println!("{f}"); + } else { + print!("{}", fabric_text(&f)); + } + } Command::Diagnostics { json } => { if json { println!("{}", job::diagnostic_codes()); @@ -1498,7 +1551,7 @@ mod tests { fn job(qasm: &str) -> (Job, String) { ( - Job { file: None, shots: None, seed: None, method: None, observables: vec![], amplitudes: vec![], noise: vec![], options: vec![], memory_gb: 1, history: None, compile: None, target: None, intent: vec![], verdict: false, repair: false, max_iterations: None, programs: vec![], sweep: vec![], mitigate: None, pulse: None, params: vec![] }, + Job { file: None, shots: None, seed: None, method: None, observables: vec![], amplitudes: vec![], noise: vec![], options: vec![], memory_gb: 1, history: None, compile: None, target: None, intent: vec![], verdict: false, repair: false, max_iterations: None, programs: vec![], sweep: vec![], mitigate: None, pulse: None, params: vec![], fabric: vec![] }, qasm.to_string(), ) } diff --git a/wai/wai-quantum-cli/src/mcp.rs b/wai/wai-quantum-cli/src/mcp.rs index fdeb1d99e..1f7f2f441 100644 --- a/wai/wai-quantum-cli/src/mcp.rs +++ b/wai/wai-quantum-cli/src/mcp.rs @@ -72,6 +72,7 @@ fn output_of(tool: &str) -> Option<&'static str> { "classical_shortcuts" => "tools.v1.json#/$defs/shortcuts", "draw_circuit" => "tools.v1.json#/$defs/draw", "list_methods" => "tools.v1.json#/$defs/methods", + "list_fabric" => "tools.v1.json#/$defs/fabric_members", "rewrite_qasm" => "tools.v1.json#/$defs/rewrite", "novelty_qasm" => "tools.v1.json#/$defs/novelty", "discover_evaluate" => "tools.v1.json#/$defs/discover_evaluate", @@ -115,6 +116,7 @@ fn job_schema() -> Value { "options": { "type": "object", "description": "Method options: max_bond, fusion, trajectories, threshold, memory_gb." }, "compile": compile_options_schema("Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's \"compiled\" states its distance from the program."), "target": { "description": "A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it." }, + "fabric": fabric_schema(), "intent": intent_schema(), "repair": { "description": "Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {\"max_iterations\": N, \"dyadic_bits\": K, \"sizes\": {\"q\": 3}}. The result's \"repaired\" holds the program that ran and each repair." }, "mitigate": wai_quantum::engine::mitigate::schema(), @@ -124,6 +126,14 @@ fn job_schema() -> Value { }) } +/// What a job's `fabric` takes: where the statevector method's state runs. +pub(crate) fn fabric_schema() -> Value { + json!({ + "description": "Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", + "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "array", "minItems": 2, "maxItems": 64, "items": { "type": "string", "minLength": 1 } }] + }) +} + /// What a job's `intent` takes: one intent or a list. pub(crate) fn intent_schema() -> Value { let one = json!({ @@ -437,6 +447,12 @@ fn core_tools() -> Value { "description": "Each simulation method: its accuracy class, the circuits it takes, and the most qubits it holds in a job's memory here.", "inputSchema": { "type": "object", "properties": {} }, }, + { + "name": "list_fabric", + "title": "List the fabric's members", + "description": "The members of the fabric a statevector job can be placed on here (a job's `fabric`): the CPU and each accelerator found and certified bit-exact against the CPU in this process, each with its key, its certificate and the most qubits it holds; the devices found and not placed, and why; and the backends this build reaches.", + "inputSchema": { "type": "object", "properties": {} }, + }, { "name": "qasm_diagnostics", "title": "The reader's diagnostic codes", @@ -573,6 +589,7 @@ fn call(name: &str, args: &Value, memory_gb: u64, key: &SigningKey, client: &Cli Ok(json!({ "valid": valid, "key": key })) } "list_methods" => Ok(json!({ "methods": catalog::describe(memory_gb << 30) })), + "list_fabric" => Ok(wai_quantum::engine::fabric::list(memory_gb << 30)), "qasm_diagnostics" => match raw.get("code").and_then(Value::as_str) { None => Ok(job::diagnostic_codes()), Some(c) => job::diagnostic_code(c), @@ -905,7 +922,7 @@ mod tests { let list = handle(&json!({ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }), 1, &key(), &mut Client::default()).unwrap(); let names: Vec<&str> = list["result"]["tools"].as_array().unwrap().iter().map(|t| t["name"].as_str().unwrap()).collect(); #[allow(unused_mut)] - let mut want = vec!["run_quantum_circuit", "plan_quantum_circuit", "lint_qasm", "repair_qasm", "critique_qasm", "check_equivalent", "convert_program", "improve_qasm", "classical_shortcuts", "compile_qasm", "estimate_resources", "draw_circuit", "debug_step", "debug_branches", "verify_quantum_result", "discover_evaluate", "discover_submit", "discover_archive", "novelty_qasm", "discover_novelty", "rewrite_qasm", "converge_cohort", "converge_history", "study_measure", "study_cohort", "taste_rank", "taste_next", "history_commit", "history_changes", "history_blame", "history_log", "list_methods", "qasm_diagnostics", "list_targets", "show_target", "run_on_target", "qec_code", "qec_decode", "qec_threshold", "pulse_schedule", "pulse_check", "gradient_qasm", "optimize_qasm", "vqe_ground_state", "qaoa_maxcut", "build_algorithm"]; + let mut want = vec!["run_quantum_circuit", "plan_quantum_circuit", "lint_qasm", "repair_qasm", "critique_qasm", "check_equivalent", "convert_program", "improve_qasm", "classical_shortcuts", "compile_qasm", "estimate_resources", "draw_circuit", "debug_step", "debug_branches", "verify_quantum_result", "discover_evaluate", "discover_submit", "discover_archive", "novelty_qasm", "discover_novelty", "rewrite_qasm", "converge_cohort", "converge_history", "study_measure", "study_cohort", "taste_rank", "taste_next", "history_commit", "history_changes", "history_blame", "history_log", "list_methods", "list_fabric", "qasm_diagnostics", "list_targets", "show_target", "run_on_target", "qec_code", "qec_decode", "qec_threshold", "pulse_schedule", "pulse_check", "gradient_qasm", "optimize_qasm", "vqe_ground_state", "qaoa_maxcut", "build_algorithm"]; #[cfg(feature = "providers")] want.extend(["providers_list", "provider_estimate", "run_on_provider"]); assert_eq!(names, want); @@ -1432,6 +1449,13 @@ mod tests { call_tool("draw_circuit", json!({ "qasm": draft }), false, &mut called, &mut hold); call_tool("verify_quantum_result", json!({ "job": job }), false, &mut called, &mut hold); call_tool("list_methods", json!({}), false, &mut called, &mut hold); + call_tool("list_fabric", json!({}), false, &mut called, &mut hold); + // A state split over the CPU, as the fabric places it: the answers the + // CPU gives, and where it ran in the result; a member that is not here + // is refused. + let placed = call_tool("run_quantum_circuit", json!({ "qasm": "OPENQASM 3.0;\nqubit[4] q;\nbit[4] c;\nh q[0];\ncx q[0], q[3];\nrx(0.3) q[2];\nc = measure q;\n", "shots": 50, "fabric": ["cpu", "cpu"] }), false, &mut called, &mut hold); + assert_eq!(placed["result"]["fabric"]["partitions"].as_array().map(Vec::len), Some(2), "{placed}"); + call_tool("run_quantum_circuit", json!({ "qasm": "OPENQASM 3.0;\nqubit[4] q;\nh q[0];\n", "shots": 5, "method": "statevector", "fabric": "a-member-elsewhere" }), true, &mut called, &mut hold); call_tool("novelty_qasm", json!({ "qasm": star, "inputs": { "n": 4 }, "reference": bell }), false, &mut called, &mut hold); for (op, extra) in [("options", json!({})), ("simplify", json!({})), ("explain", json!({ "other": "OPENQASM 3.0;\nqubit[2] q;\ncx q[0], q[1];\nt q[1];\n" }))] { let mut a = json!({ "qasm": draft, "op": op }); diff --git a/wai/wai-quantum-service/Cargo.toml b/wai/wai-quantum-service/Cargo.toml index e9b02522a..9f8ac98c5 100644 --- a/wai/wai-quantum-service/Cargo.toml +++ b/wai/wai-quantum-service/Cargo.toml @@ -20,7 +20,7 @@ getrandom = "0.4" blake3 = "=1.8.7" # A job's status as server-sent events (src/http.rs): a stream built from its changes. futures-util = { version = "=0.3.34", default-features = false } -wai-quantum = { path = "../wai-quantum", default-features = false, features = ["quantum_engine", "quantum_receipt", "quantum_qec", "quantum_noise", "quantum_sv_metal", "quantum_cutrank_metal"] } +wai-quantum = { path = "../wai-quantum", default-features = false, features = ["quantum_engine", "quantum_receipt", "quantum_qec", "quantum_noise", "quantum_fabric", "quantum_sv_metal", "quantum_cutrank_metal"] } # proc_pid_rusage and waitid, for each job's energy (src/energy.rs). [target.'cfg(target_os = "macos")'.dependencies] diff --git a/wai/wai-quantum-service/src/mcp.rs b/wai/wai-quantum-service/src/mcp.rs index 810697cf6..6f957bc43 100644 --- a/wai/wai-quantum-service/src/mcp.rs +++ b/wai/wai-quantum-service/src/mcp.rs @@ -228,6 +228,7 @@ fn tool_list() -> Value { "options": { "type": "object", "description": "Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories." }, "compile": { "type": "object", "description": "Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program.", "properties": compile_props() }, "target": { "description": "A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing." }, + "fabric": { "description": "Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "array", "minItems": 2, "maxItems": 64, "items": { "type": "string", "minLength": 1 } }] }, "intent": intent_schema(), "repair": { "description": "Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {\"max_iterations\": N, \"dyadic_bits\": K, \"sizes\": {\"q\": 3}}. The result's `repaired` holds the program that ran and each repair." }, "mitigate": wai_quantum::engine::mitigate::schema(), diff --git a/wai/wai-quantum/Cargo.toml b/wai/wai-quantum/Cargo.toml index 4c767886e..e97252f7d 100644 --- a/wai/wai-quantum/Cargo.toml +++ b/wai/wai-quantum/Cargo.toml @@ -297,6 +297,10 @@ required-features = ["quantum_fabric_opencl"] name = "opencl_sv" required-features = ["quantum_fabric_opencl", "quantum_sv"] +[[test]] +name = "fabric_placement" +required-features = ["quantum_engine", "quantum_fabric"] + [[test]] name = "fpga_member" required-features = ["quantum_fabric_fpga"] diff --git a/wai/wai-quantum/README.md b/wai/wai-quantum/README.md index 8bc555e90..e7703ef62 100644 --- a/wai/wai-quantum/README.md +++ b/wai/wai-quantum/README.md @@ -531,6 +531,36 @@ rotations, CX, CZ, iSWAP, fSim, …) for it and for the tensor networks. A 26-qubit, depth-20 random circuit runs in about nine seconds on one machine, and the bits do not depend on how many threads ran it. +### Where the state runs + +```sh runnable +wai-quantum fabric # the members a state vector can be placed on here +wai-quantum run circuit.qasm --method statevector --fabric cpu --fabric cpu --fabric cpu --fabric cpu --shots 100 --json > split.json +``` + +A job's `fabric` places the `statevector` method's state on the fabric's +members (`engine::fabric`). With the CUDA, HIP or OpenCL member compiled in +(`quantum_fabric_cuda`, `quantum_fabric_hip`, `quantum_fabric_opencl`, with +`quantum_engine`), each device this process finds runs the dense f64 state +vector (`quantum_fabric::sv64`) and is certified against the CPU on the pinned +corpus; only a member certified bit-exact is placed, so a job placed on one +gives the CPU's answers byte for byte. `auto`, the default, places a state of +20 qubits or more on the first such member that holds it, GPUs first, and +keeps a smaller one on the CPU; `cpu`, `accelerator` or a member's id or key +place it there; and a list of members, a power of two of them, splits the +state by its top qubits into one partition on each. Each partition runs the +same launches the CPU plans on its own amplitudes, and a gate on a partition +qubit first has that qubit exchanged with a local one through the host's copy +of the state (`quantum_fabric::sv64::run_split`), so the joined state is the +CPU's, bit for bit. The result's `fabric` names the member, or each +partition's, with its certificate's parity tier, digest and corpus, and the +receipt seals it; with no member asked for and none placed a result is the one +it always was. Each member states the most qubits it holds, and a state or a +partition past that is refused, as is any placement the host cannot honour +(`J013`). Measured on the fleet's GPUs (a laptop GPU and an integrated one, +each beside a CPU), a whole job takes about as long either way below 22 +qubits: the copies to and from a device cost what its passes save. + ## Tensor networks An amplitude of a circuit is a tensor network, and the order it is contracted diff --git a/wai/wai-quantum/README.zh-CN.md b/wai/wai-quantum/README.zh-CN.md index b08181ec8..d043ddced 100644 --- a/wai/wai-quantum/README.zh-CN.md +++ b/wai/wai-quantum/README.zh-CN.md @@ -343,6 +343,15 @@ wai-quantum lab sv --file circuit.jsonl --sample 1000 --seed 7 `quantum_sv` 以双精度在最多 32 个量子比特上运行任意角度的任意门。`gates` 按名称为它和张量网络提供标准门(H、S、T、√X、√Y、√W、旋转门、CX、CZ、iSWAP、fSim……)。一条 26 量子比特、深度 20 的随机线路在一台机器上约九秒跑完,而且结果的每一位都与运行它的线程数无关。 +### 态在哪里运行 + +```sh runnable +wai-quantum fabric # 本机上态矢量可放置其上的成员 +wai-quantum run circuit.qasm --method statevector --fabric cpu --fabric cpu --fabric cpu --fabric cpu --shots 100 --json > split.json +``` + +作业的 `fabric` 把 `statevector` 方法的态放到计算结构的成员上(`engine::fabric`)。编译进 CUDA、HIP 或 OpenCL 成员(`quantum_fabric_cuda`、`quantum_fabric_hip`、`quantum_fabric_opencl`,配合 `quantum_engine`)后,本进程找到的每个设备都运行稠密 f64 态矢量(`quantum_fabric::sv64`),并在固定语料上对照 CPU 认证;只有认证为逐位一致的成员才会被放置,因此放到其上的作业给出与 CPU 逐字节相同的答案。默认的 `auto` 把 20 个量子比特及以上的态放到第一个能容纳它的此类成员上(GPU 优先),较小的态留在 CPU 上;`cpu`、`accelerator` 或成员的 id 或键把它放到那里;成员列表(数量为 2 的幂)按最高位量子比特把态划分为若干分区,每个成员一个分区。每个分区在自己的振幅上运行 CPU 规划的同一组启动;作用于分区量子比特的门,先经主机上的态副本把该量子比特与一个本地量子比特交换(`quantum_fabric::sv64::run_split`),因此拼合后的态与 CPU 的逐位相同。结果的 `fabric` 指明成员(或每个分区的成员)及其证书的一致性等级、摘要和语料,并由收据封存;未请求成员、也未放置时,结果与以往相同。每个成员说明它能容纳的最多量子比特数,超过此数的态或分区会被拒绝,主机无法兑现的任何放置也会被拒绝(`J013`)。在本集群的 GPU(一块笔记本 GPU 和一块集成 GPU,各与一颗 CPU 相邻)上测得:低于 22 个量子比特时,整个作业两种方式耗时相近,设备往返拷贝的开销与它节省的遍历相当。 + ## 张量网络 线路的一个振幅就是一个张量网络,而缩并的顺序决定了它的代价是 `2³⁰` 次运算还是 `2⁶⁰` 次。`quantum_tn` 搜索这一顺序,将其切片以适应内存,然后进行缩并: diff --git a/wai/wai-quantum/docs/job-refusals.md b/wai/wai-quantum/docs/job-refusals.md index 282b6d468..7f34f56ee 100644 --- a/wai/wai-quantum/docs/job-refusals.md +++ b/wai/wai-quantum/docs/job-refusals.md @@ -64,6 +64,7 @@ browser engine. A test holds this page to the code's table. | `J010` | refused | A method that does not exist: the methods list names them. | | `J011` | refused | The method named cannot take this job: a gate it does not hold, more qubits, memory or work than it takes here, noise it does not model, or an answer it does not give; the message says which, and `auto` picks a method that can. | | `J012` | refused | No method takes this job: each method's reason is listed, so the job can be changed to suit one. | +| `J013` | refused | A placement on the fabric (`fabric`) this host cannot honour: no member by that name, no certified accelerator member here, a state or a partition larger than a member holds, a partition count that is not a power of two, or a method or program the fabric's members do not run (the message says which, and what is here). | | `J020` | refused | An intent that does not read: not one of `distribution`, `equivalent` or `prepares`, a distribution whose outcomes are not the program's bits or whose probabilities do not sum to 1, or a reference program that does not read. | | `J021` | refused | A proposed repair that changes a line no diagnostic flags, or adds lines away from one: rejected, and the program left as it was. | | `J022` | refused | A repair's choices that do not read (`max_iterations`, `dyadic_bits`, `sizes`), or a proposal that is not a program's text. | diff --git a/wai/wai-quantum/schemas/job-request.v1.json b/wai/wai-quantum/schemas/job-request.v1.json index 7746558ea..a7132c8bb 100644 --- a/wai/wai-quantum/schemas/job-request.v1.json +++ b/wai/wai-quantum/schemas/job-request.v1.json @@ -172,6 +172,24 @@ } ] }, + "fabric": { + "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "string", + "minLength": 1 + } + } + ] + }, "repair": { "description": "Repair the program first on its flagged lines: true, or the choices.", "anyOf": [ diff --git a/wai/wai-quantum/schemas/job-result.v1.json b/wai/wai-quantum/schemas/job-result.v1.json index 4c9f8917f..cbea0e005 100644 --- a/wai/wai-quantum/schemas/job-result.v1.json +++ b/wai/wai-quantum/schemas/job-result.v1.json @@ -332,6 +332,9 @@ } } }, + "fabric": { + "$ref": "#/$defs/fabric" + }, "repaired": { "type": "object", "description": "A job asked to repair its program first: the program that ran, each repair, and what needs a person.", @@ -1020,6 +1023,169 @@ "description": "The noise model derived from the target's calibration: its channels, durations and idling, and each qubit's readout." } } + }, + "fabric_parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } + } + }, + "fabric_member": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "$ref": "#/$defs/fabric_parity" + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + } + } + }, + "fabric": { + "type": "object", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "required": [ + "kernel", + "asked", + "parity", + "energy" + ], + "properties": { + "kernel": { + "type": "string" + }, + "asked": { + "description": "The placement the job asked for, as it gave it.", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "$ref": "#/$defs/fabric_parity" + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "description": "Each partition's member, by the value of the state's top qubits: partition i holds the amplitudes whose top bits read i.", + "items": { + "$ref": "#/$defs/fabric_member" + } + }, + "partition_qubits": { + "type": "integer", + "minimum": 0 + }, + "local_qubits": { + "type": "integer", + "minimum": 0 + }, + "segments": { + "type": "integer", + "minimum": 0, + "description": "Runs of gates the partitions took in turn, between exchanges." + }, + "exchanges": { + "type": "integer", + "minimum": 0, + "description": "Partition qubits exchanged with local ones through the host's copy of the state." + }, + "fell_back_from": { + "$ref": "#/$defs/fabric_member", + "description": "An auto placement whose member failed during the run: that member; the CPU ran the job." + }, + "energy": { + "$ref": "#/$defs/energy" + }, + "why": { + "type": "string" + } + } } } } diff --git a/wai/wai-quantum/schemas/provenance.v1.json b/wai/wai-quantum/schemas/provenance.v1.json index b1df5e383..546fc55a8 100644 --- a/wai/wai-quantum/schemas/provenance.v1.json +++ b/wai/wai-quantum/schemas/provenance.v1.json @@ -41,7 +41,7 @@ }, "computer": { "type": "object", - "description": "What ran it: a classical simulator, the method and its accuracy class, and a device target's hash when the job named one.", + "description": "What ran it: a classical simulator, the method and its accuracy class, a device target's hash when the job named one, and the fabric's members when the result names where its state ran.", "required": [ "kind", "method" @@ -62,6 +62,21 @@ "target": { "type": "string", "description": "The device target's hash; its layout, routes and noise are in the result's own target." + }, + "fabric": { + "type": "object", + "description": "The kernel and the member that ran the state, or each partition's, as the result's fabric names them.", + "properties": { + "kernel": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, diff --git a/wai/wai-quantum/schemas/tools.v1.json b/wai/wai-quantum/schemas/tools.v1.json index 77542fdcd..9a79d1445 100644 --- a/wai/wai-quantum/schemas/tools.v1.json +++ b/wai/wai-quantum/schemas/tools.v1.json @@ -2227,6 +2227,124 @@ "description": "The output read back and held to the program read (or, for a program read into OpenQASM, written back to its format and read again), or null when no check was asked." } } + }, + "fabric_members": { + "type": "object", + "description": "The members of the fabric a statevector job can be placed on here: the CPU reference and each accelerator certified bit-exact in this process, each with the most qubits it holds; the devices found and not placed, with why; why each backend the build reaches found none; and the backends it reaches.", + "required": [ + "kernel", + "members" + ], + "properties": { + "kernel": { + "type": "string" + }, + "auto_min_qubits": { + "type": "integer", + "minimum": 1, + "description": "The fewest qubits auto places on an accelerator member." + }, + "members": { + "type": "array", + "items": { + "type": "object", + "required": [ + "member", + "implementation", + "parity" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "parity": { + "$ref": "job-result.v1.json#/$defs/fabric_parity" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "detail": { + "type": "object", + "description": "The most qubits it holds and what bounds it; for an accelerator, its backend and what discovery found.", + "properties": { + "max_qubits": { + "type": "integer", + "minimum": 0 + }, + "memory": { + "type": "string" + }, + "backend": { + "type": "string" + }, + "device": { + "type": "string" + } + } + } + } + } + }, + "refused": { + "type": "array", + "items": { + "type": "object", + "properties": { + "backend": { + "type": "string" + }, + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "why": { + "type": "string" + } + } + } + }, + "unavailable": { + "type": "array", + "items": { + "type": "object", + "properties": { + "backend": { + "type": "string" + }, + "why": { + "type": "string" + } + } + } + }, + "backends": { + "type": "array", + "items": { + "type": "string" + } + } + } } } } diff --git a/wai/wai-quantum/src/engine/catalog.rs b/wai/wai-quantum/src/engine/catalog.rs index 785cd4a4b..3edbe658e 100644 --- a/wai/wai-quantum/src/engine/catalog.rs +++ b/wai/wai-quantum/src/engine/catalog.rs @@ -936,6 +936,9 @@ pub fn plan(v: &Value, job_bytes: u64) -> Result { // the device would run it (engine::targets::job). #[cfg(feature = "quantum_receipt")] if crate::engine::targets::job::names_target(v) { + if !matches!(super::fabric::asked(v)?, super::fabric::Ask::Auto | super::fabric::Ask::Cpu) { + return Err(tag(refusal::FABRIC, "fabric: a job on a device target runs on the CPU, as the device's simulation; give fabric cpu, or leave it out")); + } let p = crate::engine::targets::job::plan(v, job_bytes)?; return with_intent(v, &read(v)?, p, job_bytes); } @@ -944,10 +947,24 @@ pub fn plan(v: &Value, job_bytes: u64) -> Result { return Err("this build has no device targets (the engine's quantum_receipt feature)".into()); } let r = read(v)?; - let p = choose(&r, job_bytes)?; + let mut p = choose_placed(v, &r, job_bytes)?; + super::fabric::admit(v, &r, &mut p)?; with_intent(v, &r, p, job_bytes) } +/// [`choose`], except that a job asking for a member of the fabric +/// (`accelerator`, a member, or partitions) under `auto` takes the one method +/// the fabric's members run, `statevector`. +fn choose_placed(v: &Value, r: &Request, job_bytes: u64) -> Result { + use super::fabric::Ask; + let ask = super::fabric::asked(v)?; + if r.method != "auto" || matches!(ask, Ask::Auto | Ask::Cpu) { + return choose(r, job_bytes); + } + let (dyadic, clifford) = (r.program.dyadic(), r.program.clifford()); + try_method("statevector", r, &dyadic, &clifford, job_bytes).map_err(|e| tag(refusal::FABRIC, format!("fabric: only the statevector method is placed on the fabric's members, and it cannot take this job: {e}"))) +} + /// `p` for the job `v`, read as `r`, admitting the memory its intents' check /// takes beside the run, where it fits (super::verdict). fn with_intent(v: &Value, r: &Request, mut p: Plan, job_bytes: u64) -> Result { diff --git a/wai/wai-quantum/src/engine/fabric.rs b/wai/wai-quantum/src/engine/fabric.rs new file mode 100644 index 000000000..9b4cd17ea --- /dev/null +++ b/wai/wai-quantum/src/engine/fabric.rs @@ -0,0 +1,783 @@ +//! Where a job's state vector runs: the members of the fabric +//! (`wai.quantum.fabric`) a `statevector` job may be placed on, the placement +//! a job asks for, and the fabric's receipt inside the job's result. +//! +//! - **Members.** The CPU reference, and each accelerator the build reaches +//! (the features `quantum_fabric_cuda`, `quantum_fabric_hip` and +//! `quantum_fabric_opencl`) that this process finds, compiles the dense f64 +//! state vector for ([`crate::quantum_fabric::sv64`]) and certifies against +//! the CPU on the pinned corpus. Only a member certified bit-exact is +//! placed: it gives the CPU's bits, so a job placed on it has the answers it +//! would have had on the CPU, byte for byte. Discovery runs once per +//! process, the first time a job may be placed on a member. +//! - **Asking.** A job's `fabric` is `auto` (the default), `cpu`, +//! `accelerator` (any certified accelerator member), a member's id or key, +//! or a list of them: the state split by its top qubits into that many +//! partitions, a power of two, one on each member named (a member may be +//! named more than once, and `cpu` is a member). A placement this host +//! cannot honour is refused ([`super::refusal::FABRIC`]), never made +//! somewhere else. +//! - **Auto.** A state of at least [`AUTO_MIN_QUBITS`] qubits goes to the +//! first certified accelerator member that holds it, GPUs first; a smaller +//! one, or one no member holds, stays on the CPU. A member that fails during +//! an auto run hands the job back to the CPU, and the receipt says so. With +//! no member present a job runs as it always did, and its result has no +//! `fabric`. +//! - **Partitions** ([`crate::quantum_fabric::sv64::run_split`]). Each +//! partition runs the same launches the CPU plans, on its own amplitudes; a +//! gate on a partition qubit first has that qubit exchanged with a local one +//! through the host's copy of the state. The joined state is the CPU's, bit +//! for bit. +//! - **The receipt.** A result placed on a member, or one whose job asked for +//! a placement, carries `fabric`: the kernel, the member (or each +//! partition's), its certificate's parity tier, digest and corpus, and the +//! energy, unmetered with the reason. The job's receipt seals it with the +//! rest of the result. +//! - **Memory.** Each member states the most qubits it holds ([`list`]); a +//! state or a partition past that is refused. + +use super::catalog::{Plan, Request}; +use super::refusal::{self, tag}; +use serde_json::{Value, json}; + +/// The kernel a placement runs: a gate list on a dense f64 state. +pub const KERNEL: &str = "wai.quantum.sv/run"; + +/// The fewest qubits `auto` places on an accelerator member. Below, the +/// copies to and from the device cost more than the passes over the state +/// they save. +pub const AUTO_MIN_QUBITS: u32 = 20; + +/// The most partitions a state may be split into. +pub const MAX_PARTITIONS: usize = 64; + +/// The words `fabric` takes besides a member's id or key. +pub const WORDS: [&str; 3] = ["auto", "cpu", "accelerator"]; + +/// What a job's `fabric` asks for. +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) enum Ask { + Auto, + Cpu, + Accelerator, + Member(String), + Split(Vec), +} + +impl Ask { + /// The ask as the job gave it, for the receipt. + fn json(&self) -> Value { + match self { + Ask::Auto => json!("auto"), + Ask::Cpu => json!("cpu"), + Ask::Accelerator => json!("accelerator"), + Ask::Member(m) => json!(m), + Ask::Split(v) => json!(v), + } + } +} + +/// What the job's `fabric` asks, read and checked. +pub(crate) fn asked(v: &Value) -> Result { + let bad = |m: &str| tag(refusal::BAD_FIELD, m); + const TAKES: &str = "\"fabric\" is auto, cpu, accelerator, a member's id or key (wai-quantum fabric lists them), or a list of members, one for each partition of the state"; + match v.get("fabric") { + None | Some(Value::Null) => Ok(Ask::Auto), + Some(Value::String(s)) => Ok(match s.as_str() { + "auto" => Ask::Auto, + "cpu" => Ask::Cpu, + "accelerator" => Ask::Accelerator, + "" => return Err(bad(TAKES)), + id => Ask::Member(id.to_string()), + }), + Some(Value::Array(a)) => { + let names: Vec = a.iter().map(|x| x.as_str().filter(|s| !s.is_empty() && !matches!(*s, "auto" | "accelerator")).map(str::to_string)).collect::>().ok_or_else(|| bad("\"fabric\" as a list names the member each partition runs on: cpu, or a member's id or key"))?; + if names.len() < 2 || names.len() > MAX_PARTITIONS || !names.len().is_power_of_two() { + return Err(tag(refusal::FABRIC, format!("fabric: {} partitions; a state splits into a power of two of them, 2 to {MAX_PARTITIONS}", names.len()))); + } + Ok(Ask::Split(names)) + } + Some(_) => Err(bad(TAKES)), + } +} + +/// The fewest index bits a launch of `r`'s circuit may touch at once: its +/// widest gate, or the fusion width, whichever is wider. +fn widest(r: &Request) -> u32 { + let width = r.options.get("fusion").and_then(Value::as_u64).unwrap_or(3).clamp(1, 5) as u32; + let op = r.program.ops.iter().map(|o| o.qubits.len() as u32).max().unwrap_or(1); + if width >= 2 { op.max(width) } else { op } +} + +/// Checks the placement `v` asks for against `plan`, and states it in the +/// plan's `why` when it is not the CPU by default. Refused, with +/// [`refusal::FABRIC`], when this host cannot honour it. +pub(crate) fn admit(v: &Value, r: &Request, plan: &mut Plan) -> Result<(), String> { + let ask = asked(v)?; + let placed_method = plan.method == "statevector" && r.program.dynamic.is_none(); + if !placed_method { + return match ask { + Ask::Auto => Ok(()), + Ask::Cpu if matches!(plan.method.as_str(), "statevector_single" | "cutrank_single") => Err(tag(refusal::FABRIC, format!("fabric cpu: {} runs on the GPU in single precision; give another method, or leave fabric out", plan.method))), + Ask::Cpu => Ok(()), + _ if plan.method == "statevector" => Err(tag(refusal::FABRIC, "fabric: a program that measures in the middle, resets or acts on measured bits runs on the CPU; give fabric cpu, or leave it out")), + _ => Err(tag(refusal::FABRIC, format!("fabric: only the statevector method is placed on the fabric's members; this job runs {}. Give method statevector, or leave fabric out", plan.method))), + }; + } + let placed = imp::resolve(&ask, r.program.n_qubits, widest(r))?; + if let Some(said) = imp::said(&ask, &placed) { + plan.why = format!("{}; {said}", plan.why); + } + Ok(()) +} + +/// The state of `gates` on `n` qubits at fusion `width`, run where the job +/// `v` asks (as [`admit`] admitted it), and the fabric's receipt when the +/// result is to carry one. The state is the CPU's, bit for bit, wherever it +/// ran. +pub(crate) fn statevector(v: &Value, n: u32, gates: &[crate::gates::Gate], width: usize, widest: u32) -> Result<(crate::quantum_sv::StateVector, Option), String> { + let ask = asked(v)?; + let placed = imp::resolve(&ask, n, widest)?; + imp::run(&ask, &placed, n, gates, width) +} + +/// The widest launch the job `r` can make, for [`statevector`]. +pub(crate) fn widest_of(r: &Request) -> u32 { + widest(r) +} + +/// The members a job can be placed on here, each with the most qubits it +/// holds (the CPU's in `job_bytes`), its implementation and its certificate; +/// the devices found and not placed, with why; and why each backend the build +/// reaches found none. Discovers the members if no job has yet. +pub fn list(job_bytes: u64) -> Value { + imp::list(job_bytes) +} + +fn cpu_detail(job_bytes: u64) -> Value { + json!({ "max_qubits": super::catalog::statevector_max_qubits(job_bytes), "memory": "the job's memory on this host" }) +} + +/// The energy a member's run carries: none is metered here. +fn unmetered() -> Value { + json!({ "unmetered": "no meter brackets a member's run in the engine: the job's own energy is its host process's, not the device's" }) +} + +fn hex(b: &[u8]) -> String { + b.iter().map(|x| format!("{x:02x}")).collect() +} + +#[cfg(not(feature = "quantum_fabric"))] +mod imp { + use super::*; + + pub(super) enum Placed { + Cpu, + } + + pub(super) fn resolve(ask: &Ask, _n: u32, _widest: u32) -> Result { + match ask { + Ask::Auto => Ok(Placed::Cpu), + _ => Err(tag(refusal::FABRIC, "fabric: this build has no fabric (the engine's quantum_fabric feature); leave fabric out")), + } + } + + pub(super) fn said(_ask: &Ask, _p: &Placed) -> Option { + None + } + + pub(super) fn run(_ask: &Ask, _p: &Placed, n: u32, gates: &[crate::gates::Gate], width: usize) -> Result<(crate::quantum_sv::StateVector, Option), String> { + let mut sv = crate::quantum_sv::StateVector::zero(n).map_err(|e| format!("{e:?}"))?; + sv.run(gates, width).map_err(|e| format!("{e:?}"))?; + Ok((sv, None)) + } + + pub(super) fn list(job_bytes: u64) -> Value { + json!({ + "kernel": KERNEL, + "auto_min_qubits": AUTO_MIN_QUBITS, + "members": [{ "member": "cpu", "key": "cpu", "class": "cpu", "implementation": "reference", "parity": { "tier": "bit-exact" }, "detail": cpu_detail(job_bytes) }], + "refused": [], + "unavailable": [{ "backend": "fabric", "why": "this build has no fabric (the engine's quantum_fabric feature)" }], + "backends": [], + }) + } +} + +#[cfg(feature = "quantum_fabric")] +mod imp { + use super::*; + use crate::quantum_fabric::sv64::{self, Launch, PartRunner}; + use crate::quantum_fabric::{Certificate, FabricClass, Parity}; + use std::sync::OnceLock; + + /// An accelerator that runs the plan's launches on a state it is given. + pub(super) trait Device: Send + Sync { + fn max_qubits(&self) -> u32; + fn run(&self, re: &[f64], im: &[f64], launches: &[Launch]) -> Result<(Vec, Vec), String>; + } + + /// A certified member. + pub(super) struct Accelerator { + id: String, + key: String, + class: FabricClass, + backend: &'static str, + certificate: Certificate, + detail: String, + device: Box, + } + + struct Registry { + members: Vec, + refused: Vec, + unavailable: Vec, + } + + fn registry() -> &'static Registry { + static R: OnceLock = OnceLock::new(); + R.get_or_init(discover) + } + + /// The backends this build reaches. + fn backends() -> Vec<&'static str> { + let mut b = Vec::new(); + if cfg!(all(feature = "quantum_fabric_cuda", not(target_arch = "wasm32"))) { + b.push("cuda"); + } + if cfg!(all(feature = "quantum_fabric_hip", not(target_arch = "wasm32"))) { + b.push("hip"); + } + if cfg!(all(feature = "quantum_fabric_opencl", not(target_arch = "wasm32"))) { + b.push("opencl"); + } + b + } + + // Unused in a build that reaches no accelerator. + #[allow(clippy::too_many_arguments, dead_code)] + fn enrol(r: &mut Registry, backend: &'static str, id: &str, key: &str, class: FabricClass, detail: &str, implementation: &str, cert: Result, device: Box) { + match cert { + Ok(c) if c.parity == Parity::BitExact && c.cases > 0 && c.kernel == KERNEL && c.member == id && c.implementation == implementation => { + r.members.push(Accelerator { id: id.into(), key: key.into(), class, backend, certificate: c, detail: detail.into(), device }); + } + Ok(c) => r.refused.push(json!({ "backend": backend, "member": id, "key": key, "why": format!("certified {}, not bit-exact: never placed", tier(&c.parity)["tier"].as_str().unwrap_or("uncertified")) })), + Err(e) => r.refused.push(json!({ "backend": backend, "member": id, "key": key, "why": format!("the state vector did not certify: {e}") })), + } + } + + #[allow(unused_mut)] + fn discover() -> Registry { + let mut r = Registry { members: Vec::new(), refused: Vec::new(), unavailable: Vec::new() }; + #[cfg(all(feature = "quantum_fabric_cuda", not(target_arch = "wasm32")))] + { + struct Cuda(crate::quantum_fabric_cuda::CudaSv); + impl Device for Cuda { + fn max_qubits(&self) -> u32 { + self.0.max_qubits() + } + fn run(&self, re: &[f64], im: &[f64], launches: &[Launch]) -> Result<(Vec, Vec), String> { + self.0.run_launches(re, im, launches).map_err(|e| e.to_string()) + } + } + let d = crate::quantum_fabric_cuda::discover(); + if let Some(why) = d.unavailable { + r.unavailable.push(json!({ "backend": "cuda", "why": why })); + } + for x in d.refused { + r.refused.push(json!({ "backend": "cuda", "member": x.device, "key": x.key, "why": x.error.to_string() })); + } + for m in d.found { + match m.sv() { + Ok(sv) => { + let (implementation, cert) = (sv.implementation().to_string(), sv.certify(sv64::SV_DEFAULT).map_err(|e| e.to_string())); + enrol(&mut r, "cuda", m.id(), m.key(), m.class(), m.detail(), &implementation, cert, Box::new(Cuda(sv))); + } + Err(e) => r.refused.push(json!({ "backend": "cuda", "member": m.id(), "key": m.key(), "why": e.to_string() })), + } + } + } + #[cfg(all(feature = "quantum_fabric_hip", not(target_arch = "wasm32")))] + { + struct Hip(crate::quantum_fabric_hip::HipSv); + impl Device for Hip { + fn max_qubits(&self) -> u32 { + self.0.max_qubits() + } + fn run(&self, re: &[f64], im: &[f64], launches: &[Launch]) -> Result<(Vec, Vec), String> { + self.0.run_launches(re, im, launches).map_err(|e| e.to_string()) + } + } + let d = crate::quantum_fabric_hip::discover(); + if let Some(why) = d.unavailable { + r.unavailable.push(json!({ "backend": "hip", "why": why })); + } + for x in d.refused { + r.refused.push(json!({ "backend": "hip", "member": x.device, "key": x.key, "why": x.error.to_string() })); + } + for m in d.found { + match m.sv() { + Ok(sv) => { + let (implementation, cert) = (sv.implementation().to_string(), sv.certify(sv64::SV_DEFAULT).map_err(|e| e.to_string())); + enrol(&mut r, "hip", m.id(), m.key(), m.class(), m.detail(), &implementation, cert, Box::new(Hip(sv))); + } + Err(e) => r.refused.push(json!({ "backend": "hip", "member": m.id(), "key": m.key(), "why": e.to_string() })), + } + } + } + #[cfg(all(feature = "quantum_fabric_opencl", not(target_arch = "wasm32")))] + { + struct OpenCl(crate::quantum_fabric_opencl::OpenClSv); + impl Device for OpenCl { + fn max_qubits(&self) -> u32 { + self.0.max_qubits() + } + fn run(&self, re: &[f64], im: &[f64], launches: &[Launch]) -> Result<(Vec, Vec), String> { + self.0.run_launches(re, im, launches).map_err(|e| e.to_string()) + } + } + let d = crate::quantum_fabric_opencl::discover(); + if let Some(why) = d.unavailable { + r.unavailable.push(json!({ "backend": "opencl", "why": why })); + } + for x in d.refused { + r.refused.push(json!({ "backend": "opencl", "member": x.device, "key": x.key, "why": x.error.to_string() })); + } + for m in d.found { + if !m.has_binary64() { + r.refused.push(json!({ "backend": "opencl", "member": m.id(), "key": m.key(), "why": "the device has no binary64" })); + continue; + } + match m.sv() { + Ok(sv) => { + let (implementation, cert) = (sv.implementation().to_string(), sv.certify(sv64::SV_DEFAULT).map_err(|e| e.to_string())); + enrol(&mut r, "opencl", m.id(), m.key(), m.class(), m.detail(), &implementation, cert, Box::new(OpenCl(sv))); + } + Err(e) => r.refused.push(json!({ "backend": "opencl", "member": m.id(), "key": m.key(), "why": e.to_string() })), + } + } + } + // GPUs first, then by backend as listed, then by id: the same order + // on every run. + let order = |b: &str| backends().iter().position(|x| *x == b).unwrap_or(usize::MAX); + r.members.sort_by(|a, b| (a.class != FabricClass::Gpu, order(a.backend), &a.id).cmp(&(b.class != FabricClass::Gpu, order(b.backend), &b.id))); + r + } + + fn tier(p: &Parity) -> Value { + match *p { + Parity::BitExact => json!({ "tier": "bit-exact" }), + Parity::Within { max_ulp, max_abs } => json!({ "tier": "within", "max_ulp": max_ulp, "max_abs": max_abs }), + Parity::Statistical { fidelity, shots } => json!({ "tier": "statistical", "fidelity": fidelity, "shots": shots }), + Parity::Uncertified => json!({ "tier": "uncertified" }), + } + } + + /// A partition's runner, owned. + type BoxedRunner<'a> = Box Result<(), String> + Sync + 'a>; + + /// One partition's member, or the whole state's. + pub(super) enum Part<'a> { + Cpu, + Member(&'a Accelerator), + } + + pub(super) enum Placed<'a> { + Cpu, + One(&'a Accelerator), + Split(Vec>), + } + + fn cpu_id() -> String { + crate::quantum_fabric::detect_local().id + } + + /// The member `name` names: `cpu` or the CPU's id, or an accelerator by + /// its id, or by its key when one member alone has it. + fn named<'a>(reg: &'a Registry, name: &str) -> Result, String> { + if name == "cpu" || name == cpu_id() { + return Ok(Part::Cpu); + } + if let Some(m) = reg.members.iter().find(|m| m.id == name) { + return Ok(Part::Member(m)); + } + let by_key: Vec<&Accelerator> = reg.members.iter().filter(|m| m.key == name).collect(); + match by_key[..] { + [m] => Ok(Part::Member(m)), + [] => Err(tag(refusal::FABRIC, format!("fabric: no member {name} here; {}", here(reg)))), + _ => Err(tag(refusal::FABRIC, format!("fabric: {} members have the key {name}; name one by its id ({})", by_key.len(), by_key.iter().map(|m| m.id.as_str()).collect::>().join(", ")))), + } + } + + /// What this host has to place on, in a sentence. + fn here(reg: &Registry) -> String { + let mut parts = vec![format!("the members are cpu{}", reg.members.iter().map(|m| format!(", {} ({})", m.key, m.id)).collect::())]; + for u in ®.unavailable { + parts.push(format!("{}: {}", u["backend"].as_str().unwrap_or(""), u["why"].as_str().unwrap_or(""))); + } + for x in ®.refused { + parts.push(format!("{} {} not placed: {}", x["backend"].as_str().unwrap_or(""), x["key"].as_str().unwrap_or(""), x["why"].as_str().unwrap_or(""))); + } + if backends().is_empty() { + parts.push("this build reaches no accelerator (the engine's quantum_fabric_cuda, quantum_fabric_hip and quantum_fabric_opencl features)".into()); + } + parts.join("; ") + } + + pub(super) fn resolve<'a>(ask: &Ask, n: u32, widest: u32) -> Result, String> { + match ask { + Ask::Cpu => Ok(Placed::Cpu), + Ask::Auto if n < AUTO_MIN_QUBITS || backends().is_empty() => Ok(Placed::Cpu), + Ask::Auto => Ok(registry().members.iter().find(|m| m.device.max_qubits() >= n).map_or(Placed::Cpu, Placed::One)), + Ask::Accelerator => { + let reg = registry(); + if reg.members.is_empty() { + return Err(tag(refusal::FABRIC, format!("fabric accelerator: no certified accelerator member here; {}", here(reg)))); + } + reg.members.iter().find(|m| m.device.max_qubits() >= n).map(Placed::One).ok_or_else(|| tag(refusal::FABRIC, format!("fabric accelerator: a state of {n} qubits; the largest member here holds {} (give a list of members to split it)", reg.members.iter().map(|m| m.device.max_qubits()).max().unwrap_or(0)))) + } + Ask::Member(name) => { + let reg = registry(); + match named(reg, name)? { + Part::Cpu => Ok(Placed::Cpu), + Part::Member(m) if m.device.max_qubits() >= n => Ok(Placed::One(m)), + Part::Member(m) => Err(tag(refusal::FABRIC, format!("fabric {name}: a state of {n} qubits; {} holds at most {} (give a list of members to split it)", m.key, m.device.max_qubits()))), + } + } + Ask::Split(names) => { + let p = names.len().trailing_zeros(); + if n <= p { + return Err(tag(refusal::FABRIC, format!("fabric: {} partitions of a {n}-qubit state leave no qubit in a partition", names.len()))); + } + let local = n - p; + if local < widest { + return Err(tag(refusal::FABRIC, format!("fabric: {} partitions leave {local} qubits in each, fewer than the {widest} a gate of this job acts on at once; give fewer partitions or a smaller fusion", names.len()))); + } + let needs = names.iter().any(|x| x != "cpu"); + let reg = if needs { Some(registry()) } else { None }; + let mut parts = Vec::with_capacity(names.len()); + for name in names { + let part = match reg { + Some(reg) => named(reg, name)?, + None => Part::Cpu, + }; + if let Part::Member(m) = &part + && m.device.max_qubits() < local + { + return Err(tag(refusal::FABRIC, format!("fabric: a partition of {local} qubits; {} holds at most {}", m.key, m.device.max_qubits()))); + } + parts.push(part); + } + Ok(Placed::Split(parts)) + } + } + } + + fn label(p: &Part<'_>) -> String { + match p { + Part::Cpu => "cpu".into(), + Part::Member(m) => m.key.clone(), + } + } + + pub(super) fn said(ask: &Ask, p: &Placed<'_>) -> Option { + match p { + Placed::Cpu if *ask == Ask::Auto => None, + Placed::Cpu => Some("on the CPU, as the job asked".into()), + Placed::One(m) => Some(format!("its state on {} ({}), certified bit-exact against the CPU", m.key, m.id)), + Placed::Split(parts) => Some(format!("its state split by its top {} qubits into {} partitions, on {}, each certified bit-exact against the CPU", parts.len().trailing_zeros(), parts.len(), parts.iter().map(label).collect::>().join(", "))), + } + } + + fn cpu_json() -> Value { + let id = cpu_id(); + let c = Certificate::reference(KERNEL, &id); + json!({ "member": id, "key": "cpu", "class": "cpu", "implementation": crate::quantum_fabric::REFERENCE, "parity": tier(&c.parity), "certificate": hex(&c.hash()), "generator": c.generator, "cases": c.cases }) + } + + fn member_json(m: &Accelerator) -> Value { + let c = &m.certificate; + json!({ "member": m.id, "key": m.key, "class": m.class.label(), "implementation": c.implementation, "parity": tier(&c.parity), "certificate": hex(&c.hash()), "corpus": hex(&c.corpus), "generator": c.generator, "cases": c.cases }) + } + + fn part_json(p: &Part<'_>) -> Value { + match p { + Part::Cpu => cpu_json(), + Part::Member(m) => member_json(m), + } + } + + fn cpu_run(n: u32, gates: &[crate::gates::Gate], width: usize) -> Result { + let mut sv = crate::quantum_sv::StateVector::zero(n).map_err(|e| format!("{e:?}"))?; + sv.run(gates, width).map_err(|e| format!("{e:?}"))?; + Ok(sv) + } + + fn state(n: u32, re: Vec, im: Vec) -> crate::quantum_sv::StateVector { + crate::quantum_sv::StateVector { n, re, im } + } + + pub(super) fn run(ask: &Ask, p: &Placed<'_>, n: u32, gates: &[crate::gates::Gate], width: usize) -> Result<(crate::quantum_sv::StateVector, Option), String> { + let receipt = |mut body: Value, why: Option| -> Value { + body["kernel"] = json!(KERNEL); + body["asked"] = ask.json(); + body["energy"] = unmetered(); + if let Some(w) = why { + body["why"] = json!(w); + } + body + }; + match p { + Placed::Cpu => { + let sv = cpu_run(n, gates, width)?; + let r = (*ask != Ask::Auto).then(|| receipt(cpu_json(), said(ask, p))); + Ok((sv, r)) + } + Placed::One(m) => { + let launches = sv64::plan(n, gates, width).map_err(|e| format!("{e:?}"))?; + let len = 1usize << n; + let mut re = vec![0.0; len]; + re[0] = 1.0; + match m.device.run(&re, &vec![0.0; len], &launches) { + Ok((re, im)) => Ok((state(n, re, im), Some(receipt(member_json(m), said(ask, p))))), + // A member that fails during an auto run hands the job + // back to the CPU, and the receipt says so. + Err(e) if *ask == Ask::Auto => { + let sv = cpu_run(n, gates, width)?; + let mut body = receipt(cpu_json(), Some(format!("{} failed during the run, and the CPU ran the job: {e}", m.key))); + body["fell_back_from"] = member_json(m); + Ok((sv, Some(body))) + } + Err(e) => Err(tag(refusal::FABRIC, format!("fabric: {} failed during the run: {e}", m.key))), + } + } + Placed::Split(parts) => { + let launches = sv64::plan(n, gates, width).map_err(|e| format!("{e:?}"))?; + // One runner for the CPU and one for each member named, so a + // member's partitions run one after another. + let mut keys: Vec> = Vec::new(); + let mut owner = Vec::with_capacity(parts.len()); + for part in parts { + let k = match part { + Part::Cpu => None, + Part::Member(m) => Some(m.id.as_str()), + }; + owner.push(keys.iter().position(|x| *x == k).unwrap_or_else(|| { + keys.push(k); + keys.len() - 1 + })); + } + let cpu = |re: &mut [f64], im: &mut [f64], l: &[Launch]| -> Result<(), String> { + sv64::replay(re, im, l); + Ok(()) + }; + let devices: Vec> = keys + .iter() + .map(|k| -> BoxedRunner<'_> { + match k.and_then(|id| parts.iter().find_map(|x| if let Part::Member(m) = x { (m.id == id).then_some(*m) } else { None })) { + None => Box::new(cpu), + Some(m) => Box::new(move |re: &mut [f64], im: &mut [f64], l: &[Launch]| { + let (r, i) = m.device.run(re, im, l).map_err(|e| format!("{} failed during the run: {e}", m.key))?; + re.copy_from_slice(&r); + im.copy_from_slice(&i); + Ok(()) + }), + } + }) + .collect(); + let runners: Vec> = devices.iter().map(|b| &**b as PartRunner<'_>).collect(); + let len = 1usize << n; + let (mut re, mut im) = (vec![0.0; len], vec![0.0; len]); + re[0] = 1.0; + let done = sv64::run_split(&mut re, &mut im, &launches, &owner, &runners).map_err(|e| tag(refusal::FABRIC, format!("fabric: {e}")))?; + let body = receipt( + json!({ + "partitions": parts.iter().map(part_json).collect::>(), + "partition_qubits": parts.len().trailing_zeros(), + "local_qubits": n - parts.len().trailing_zeros(), + "segments": done.segments, + "exchanges": done.exchanges, + "parity": { "tier": "bit-exact" }, + }), + said(ask, p), + ); + Ok((state(n, re, im), Some(body))) + } + } + } + + pub(super) fn list(job_bytes: u64) -> Value { + let reg = registry(); + let mut members = vec![cpu_json()]; + members[0]["detail"] = cpu_detail(job_bytes); + for m in ®.members { + let mut j = member_json(m); + j["detail"] = json!({ "max_qubits": m.device.max_qubits(), "memory": "two f64 arrays of 2^n within half the device's free memory at discovery, n at most 25", "backend": m.backend, "device": m.detail }); + members.push(j); + } + json!({ + "kernel": KERNEL, + "auto_min_qubits": AUTO_MIN_QUBITS, + "members": members, + "refused": reg.refused, + "unavailable": reg.unavailable, + "backends": backends(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn a_job_s_fabric_reads_or_is_refused_with_its_code() { + let ask = |f: Value| asked(&json!({ "qasm": "", "fabric": f })); + assert_eq!(asked(&json!({ "qasm": "" })).unwrap(), Ask::Auto); + assert_eq!(ask(json!("auto")).unwrap(), Ask::Auto); + assert_eq!(ask(json!("cpu")).unwrap(), Ask::Cpu); + assert_eq!(ask(json!("accelerator")).unwrap(), Ask::Accelerator); + assert_eq!(ask(json!("gpu-cuda-sm89")).unwrap(), Ask::Member("gpu-cuda-sm89".into())); + assert_eq!(ask(json!(["cpu", "cpu"])).unwrap(), Ask::Split(vec!["cpu".into(), "cpu".into()])); + for bad in [json!(""), json!(3), json!({ "member": "cpu" }), json!(["cpu", 2]), json!(["auto", "cpu"])] { + assert!(ask(bad.clone()).unwrap_err().ends_with("[J003]"), "{bad}"); + } + for odd in [json!(["cpu"]), json!(["cpu", "cpu", "cpu"]), json!(vec!["cpu"; 128])] { + assert!(ask(odd.clone()).unwrap_err().ends_with("[J013]"), "{odd}"); + } + } + + const CAP: u64 = 8 << 30; + + /// A circuit at arbitrary angles whose gates reach every qubit, the top + /// ones included, and a job of it asking for every answer. + fn job(n: u32, extra: Value) -> Value { + let mut q = format!("OPENQASM 3.0;\nqubit[{n}] q;\nbit[{n}] c;\n"); + for layer in 0..4 { + for i in 0..n { + q.push_str(&format!("rx({}) q[{i}];\nry({}) q[{i}];\n", 0.11 + 0.37 * f64::from(i + layer), 0.29 * f64::from(layer + 1))); + } + for i in (layer % 2..n - 1).step_by(2) { + q.push_str(&format!("cx q[{i}], q[{}];\nrzz({}) q[{}], q[{i}];\n", i + 1, 0.4 + 0.1 * f64::from(i), (i + 2) % n)); + } + q.push_str(&format!("cp(0.7) q[0], q[{}];\n", n - 1)); + } + q.push_str("c = measure q;\n"); + let mut v = json!({ "qasm": q, "shots": 2000, "seed": 9, "method": "statevector", "observables": ["Z0 Z1", "0.5 X2", format!("Y{} Z0", n - 1)], "amplitudes": ["0".repeat(n as usize), format!("1{}", "0".repeat(n as usize - 1))] }); + if let (Some(o), Some(e)) = (v.as_object_mut(), extra.as_object()) { + o.extend(e.clone()); + } + v + } + + fn run(v: &Value) -> Result { + let p = super::super::catalog::plan(v, CAP)?; + super::super::run::run(v, &p) + } + + /// The answers: the result without where it ran and how long it took. + fn answers(out: &Value) -> Vec { + let mut o = out.clone(); + for k in ["fabric", "elapsed_ms"] { + o.as_object_mut().unwrap().remove(k); + } + super::super::receipt::canonical(&o) + } + + /// With no member asked for and none placed, a job runs as it always did: + /// no `fabric` in its result and none in its plan's reasons. A job that + /// asks for the CPU, or for partitions on the CPU, has the same answers + /// byte for byte, and its result names where its state ran. + #[test] + fn a_placement_changes_where_the_state_runs_and_not_a_byte_of_the_answers() { + for n in [6u32, 9] { + let plain = run(&job(n, json!({}))).unwrap(); + assert!(plain.get("fabric").is_none(), "{plain}"); + let p = super::super::catalog::plan(&job(n, json!({})), CAP).unwrap(); + assert!(!p.why.contains("partition") && !p.why.contains("CPU, as"), "{}", p.why); + let want = answers(&plain); + let cpu = run(&job(n, json!({ "fabric": "cpu" }))).unwrap(); + assert_eq!(answers(&cpu), want, "n={n}"); + assert_eq!((cpu["fabric"]["key"].as_str(), cpu["fabric"]["asked"].as_str()), (Some("cpu"), Some("cpu")), "{}", cpu["fabric"]); + assert_eq!(cpu["fabric"]["parity"]["tier"], "bit-exact"); + assert_eq!(cpu["fabric"]["certificate"].as_str().map(str::len), Some(64)); + for parts in [2usize, 4, 8] { + if n - parts.trailing_zeros() < 3 { + continue; + } + let split = run(&job(n, json!({ "fabric": vec!["cpu"; parts] }))).unwrap(); + assert_eq!(answers(&split), want, "n={n} partitions={parts}"); + let f = &split["fabric"]; + assert_eq!(f["partitions"].as_array().map(Vec::len), Some(parts), "{f}"); + assert_eq!(f["partition_qubits"], parts.trailing_zeros()); + assert!(f["exchanges"].as_u64().unwrap() > 0 && f["segments"].as_u64().unwrap() > 1, "{f}"); + let plan = super::super::catalog::plan(&job(n, json!({ "fabric": vec!["cpu"; parts] })), CAP).unwrap(); + assert!(plan.why.contains(&format!("into {parts} partitions")), "{}", plan.why); + } + } + // A fusion width the partitions cannot hold is refused, a smaller one taken. + let e = run(&job(6, json!({ "fabric": vec!["cpu"; 16] }))).unwrap_err(); + assert!(e.ends_with("[J013]") && e.contains("fewer than the 3"), "{e}"); + let fine = run(&job(6, json!({ "fabric": vec!["cpu"; 16], "options": { "fusion": 2 } }))).unwrap(); + assert_eq!(answers(&fine), answers(&run(&job(6, json!({ "options": { "fusion": 2 } }))).unwrap())); + } + + #[test] + fn a_placement_this_host_cannot_honour_is_refused_never_made_elsewhere() { + let code = |v: Value| run(&v).map(|_| ()).unwrap_err(); + let bell = |extra: Value| { + let mut v = json!({ "qasm": "OPENQASM 3.0;\nqubit[2] q;\nbit[2] c;\nh q[0];\ncx q[0], q[1];\nc = measure q;\n", "shots": 100 }); + v.as_object_mut().unwrap().extend(extra.as_object().unwrap().clone()); + v + }; + // Another method is never placed; auto with a member asked for takes the state vector. + assert!(code(bell(json!({ "method": "stabilizer", "fabric": "accelerator" }))).ends_with("[J013]")); + assert!(code(bell(json!({ "method": "exact", "fabric": ["cpu", "cpu"] }))).ends_with("[J013]")); + let ghz = json!({ "qasm": "OPENQASM 3.0;\nqubit[4] q;\nbit[4] c;\nh q[0];\ncx q[0], q[1];\ncx q[1], q[2];\ncx q[2], q[3];\nc = measure q;\n", "shots": 100, "fabric": ["cpu", "cpu"] }); + let p = super::super::catalog::plan(&ghz, CAP).unwrap(); + assert_eq!(p.method, "statevector", "{}", p.why); + assert!(run(&bell(json!({ "fabric": ["cpu", "cpu"] }))).unwrap_err().ends_with("[J013]"), "a Bell pair in two partitions leaves one qubit in each"); + // The CPU runs every CPU method as asked. + assert!(run(&bell(json!({ "method": "stabilizer", "fabric": "cpu" }))).is_ok()); + // A member this host does not have, by name or by asking for any. + if backends_reached().is_empty() { + let e = code(job(6, json!({ "fabric": "accelerator" }))); + assert!(e.ends_with("[J013]") && e.contains("no certified accelerator member here"), "{e}"); + let e = code(job(6, json!({ "fabric": "gpu-somewhere" }))); + assert!(e.ends_with("[J013]") && e.contains("no member gpu-somewhere"), "{e}"); + let e = code(job(6, json!({ "fabric": ["cpu", "gpu-somewhere"] }))); + assert!(e.ends_with("[J013]"), "{e}"); + } + // A program that measures in the middle runs on the CPU alone. + let mid = json!({ "qasm": "OPENQASM 3.0;\nqubit[2] q;\nbit[2] c;\nrx(0.3) q[0];\nc[0] = measure q[0];\ncx q[0], q[1];\nc[1] = measure q[1];\n", "shots": 50, "method": "statevector", "fabric": ["cpu", "cpu"] }); + assert!(code(mid).ends_with("[J013]")); + // Partitions that leave no qubit. + assert!(code(bell(json!({ "method": "statevector", "fabric": ["cpu", "cpu", "cpu", "cpu"] }))).ends_with("[J013]")); + } + + /// The result that names where its state ran follows the job result's + /// schema, read strictly, and its provenance names the members. + #[test] + fn a_placed_result_and_its_provenance_follow_their_schemas() { + let r = super::super::schema::Registry::engine(); + for f in [json!("cpu"), json!(["cpu", "cpu", "cpu", "cpu"])] { + let v = job(7, json!({ "fabric": f })); + let p = super::super::catalog::plan(&v, CAP).unwrap(); + let out = super::super::run::run_with_provenance(&v, &p, "a test 1.0").unwrap(); + let errs = r.check("job-result.v1.json", &out); + assert!(errs.is_empty(), "{errs:?}"); + let errs = r.check("job-request.v1.json", &v); + assert!(errs.is_empty(), "{errs:?}"); + assert!(out["provenance"]["computer"]["fabric"]["members"].as_array().is_some_and(|m| !m.is_empty()), "{}", out["provenance"]); + assert!(r.check("provenance.v1.json", &out["provenance"]).is_empty()); + } + let listed = list(CAP); + let errs = r.check("tools.v1.json#/$defs/fabric_members", &listed); + assert!(errs.is_empty(), "{errs:?} {listed}"); + assert_eq!(listed["members"][0]["key"], "cpu"); + } + + fn backends_reached() -> Vec { + list(CAP)["backends"].as_array().into_iter().flatten().filter_map(|b| b.as_str().map(str::to_string)).collect() + } +} diff --git a/wai/wai-quantum/src/engine/guide.rs b/wai/wai-quantum/src/engine/guide.rs index dfcc39195..8684361b3 100644 --- a/wai/wai-quantum/src/engine/guide.rs +++ b/wai/wai-quantum/src/engine/guide.rs @@ -96,6 +96,9 @@ pub const VERDICTS: &str = "wai-quantum://docs/verdicts"; /// The order `auto` tries the methods in. pub const AUTO: &str = "auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen."; +/// Where the statevector method's state runs, in a paragraph. +pub const FABRIC: &str = "The statevector method's state runs where the job's `fabric` says: auto (the default) places a state of 20 qubits or more on the first accelerator member of the fabric found here and certified bit-exact against the CPU (`wai-quantum fabric`, or list_fabric, lists them), and keeps a smaller one on the CPU; cpu, accelerator (any certified accelerator member) or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere."; + /// The language in a paragraph, for `AGENTS.md`. pub const SUMMARY: &str = "Programs are OpenQASM 3.1, or the OpenQASM 2 forms in common use, read by one reader on every surface: registers, the standard gates, `gate` and `def` definitions, the `ctrl @`, `negctrl @`, `inv @` and `pow @` modifiers, classical types and expressions, measurement and `reset` anywhere, `if`, `switch` and bounded `while` on measured bits, timing carried, and calibrations kept for export. Generators (integer `input`s, `const`s and `for` loops) describe a family of circuits. Every refusal and warning names its line and ends with a stable code (`[Q103]`), which the diagnostics resource explains."; @@ -139,6 +142,7 @@ A program that measures a qubit and then acts on it, resets one after its first - On this machine: `wai-quantum run`, or the local MCP server (`wai-quantum mcp`). Results are signed with the user's key and nothing leaves the machine. - On the free job service, for a program too large for this machine: `wai-quantum submit`, `POST https://wai.transaction.science/quantum-jobs/v1/run`, or its MCP server at https://wai.transaction.science/quantum-jobs/mcp. No account and no key. - {AUTO} +- {FABRIC} ", feature_matrix().trim_end(), catalog::NOISE_CHANNELS.join(", "), @@ -238,7 +242,7 @@ pub fn verdicts() -> Value { /// The methods, their reach in `job_bytes` and their accuracy classes, as the /// `methods` resource gives them. pub fn methods(job_bytes: u64) -> Value { - json!({ "methods": catalog::describe(job_bytes), "accuracy_classes": catalog::accuracy_classes(), "auto": AUTO }) + json!({ "methods": catalog::describe(job_bytes), "accuracy_classes": catalog::accuracy_classes(), "auto": AUTO, "fabric": FABRIC }) } /// A worked example: a program, what it must do, and how it is run. diff --git a/wai/wai-quantum/src/engine/mod.rs b/wai/wai-quantum/src/engine/mod.rs index fce6fc23b..09f94f8ed 100644 --- a/wai/wai-quantum/src/engine/mod.rs +++ b/wai/wai-quantum/src/engine/mod.rs @@ -202,6 +202,7 @@ pub mod energy; pub mod equiv; pub mod estimate; pub mod formats; +pub mod fabric; pub mod guide; pub mod latex; #[cfg(feature = "quantum_noise")] diff --git a/wai/wai-quantum/src/engine/refusal.rs b/wai/wai-quantum/src/engine/refusal.rs index 3c2186571..38c61fd31 100644 --- a/wai/wai-quantum/src/engine/refusal.rs +++ b/wai/wai-quantum/src/engine/refusal.rs @@ -87,6 +87,7 @@ table! { UNKNOWN_METHOD = "J010", Refused, "A method that does not exist: the methods list names them."; METHOD_REFUSES = "J011", Refused, "The method named cannot take this job: a gate it does not hold, more qubits, memory or work than it takes here, noise it does not model, or an answer it does not give; the message says which, and `auto` picks a method that can."; NO_METHOD = "J012", Refused, "No method takes this job: each method's reason is listed, so the job can be changed to suit one."; + FABRIC = "J013", Refused, "A placement on the fabric (`fabric`) this host cannot honour: no member by that name, no certified accelerator member here, a state or a partition larger than a member holds, a partition count that is not a power of two, or a method or program the fabric's members do not run (the message says which, and what is here)."; // Intents and repairs. BAD_INTENT = "J020", Refused, "An intent that does not read: not one of `distribution`, `equivalent` or `prepares`, a distribution whose outcomes are not the program's bits or whose probabilities do not sum to 1, or a reference program that does not read."; diff --git a/wai/wai-quantum/src/engine/run.rs b/wai/wai-quantum/src/engine/run.rs index b58d98e2a..0227f0a0d 100644 --- a/wai/wai-quantum/src/engine/run.rs +++ b/wai/wai-quantum/src/engine/run.rs @@ -180,6 +180,15 @@ pub fn provenance(request: &Value, plan: &Plan, result: &Value, passes: Option = match f.get("partitions").and_then(Value::as_array) { + Some(parts) => parts.iter().map(|p| p["member"].clone()).collect(), + None => vec![f["member"].clone()], + }; + computer["fabric"] = json!({ "kernel": f["kernel"], "members": members }); + } json!({ "schema": PROVENANCE, "circuit": { @@ -304,9 +313,13 @@ fn run_job(request: &Value, plan: &Plan, passes: &mut Option) -> Result { let gates = r.program.matrices(); let width = r.options.get("fusion").and_then(Value::as_u64).unwrap_or(3).clamp(1, 5) as usize; - let mut sv = crate::quantum_sv::StateVector::zero(n).map_err(|e| format!("{e:?}"))?; - sv.run(&gates, width).map_err(|e| format!("{e:?}"))?; + // On the CPU, or on the fabric's member the job's placement + // names: the CPU's bits either way. + let (sv, placed) = crate::engine::fabric::statevector(request, n, &gates, width, crate::engine::fabric::widest_of(&r))?; out["accuracy"] = json!({ "class": "exact", "fusion": width }); + if let Some(f) = placed { + out["fabric"] = f; + } if r.shots > 0 { let mut map: HashMap = HashMap::new(); for x in sv.sample(r.shots as usize, r.seed) { diff --git a/wai/wai-quantum/src/quantum_fabric/sv64.rs b/wai/wai-quantum/src/quantum_fabric/sv64.rs index fdcc576f1..5d6c244fa 100644 --- a/wai/wai-quantum/src/quantum_fabric/sv64.rs +++ b/wai/wai-quantum/src/quantum_fabric/sv64.rs @@ -246,6 +246,207 @@ pub fn replay(re: &mut [f64], im: &mut [f64], launches: &[Launch]) { } } +/// The index bits `l` reads and writes, as its parameters name them: a +/// diagonal's in its gate order, a one-qubit gate's one, a wider gate's +/// ascending. +pub fn launch_bits(l: &Launch) -> Vec { + match l { + Launch::Diag { bitpos, .. } => bitpos.clone(), + Launch::One { s, .. } => vec![s.trailing_zeros()], + Launch::Many { sorted, .. } => sorted.clone(), + } +} + +/// Whether every launch acts within a state of `2^n` amplitudes: each bit it +/// names below `n`, a one-qubit gate's stride a power of two, and a wider +/// gate's offsets made of its own bits. A device that runs a launch outside +/// its state writes past its buffers, so a runner checks this first. +pub fn fits(launches: &[Launch], n: u32) -> bool { + launches.iter().all(|l| match l { + Launch::Diag { bitpos, diag } => bitpos.len() <= MAX_D.trailing_zeros() as usize && bitpos.iter().all(|&p| p < n) && diag.len() == 1 << bitpos.len(), + Launch::One { s, .. } => s.is_power_of_two() && s.trailing_zeros() < n, + Launch::Many { sorted, offsets, m } => { + let mask = sorted.iter().fold(0u64, |a, &p| a | (1u64 << p.min(63))); + sorted.len() <= MAX_D.trailing_zeros() as usize && offsets.len() == 1 << sorted.len() && sorted.iter().all(|&p| p < n) && sorted.windows(2).all(|w| w[0] < w[1]) && m.len() == offsets.len() * offsets.len() && offsets.iter().all(|&o| o & !mask == 0) + } + }) +} + +/// `l` with each index bit `b` moved to `pos[b]`: the same formula on the same +/// amplitudes, held at other indices. Each group keeps its members in their +/// local order, so every output is computed exactly as before. +pub fn remap(l: &Launch, pos: &[u32]) -> Launch { + let bits = |o: u64| (0..64u32).filter(|&b| o >> b & 1 == 1).fold(0u64, |a, b| a | (1u64 << pos[b as usize])); + match l { + Launch::Diag { bitpos, diag } => Launch::Diag { bitpos: bitpos.iter().map(|&b| pos[b as usize]).collect(), diag: diag.clone() }, + Launch::One { s, m } => Launch::One { s: 1u64 << pos[s.trailing_zeros() as usize], m: *m }, + Launch::Many { sorted, offsets, m } => { + let mut s: Vec = sorted.iter().map(|&b| pos[b as usize]).collect(); + s.sort_unstable(); + Launch::Many { sorted: s, offsets: offsets.iter().map(|&o| bits(o)).collect(), m: m.clone() } + } + } +} + +/// Exchanges index bits `a` and `b` of a state: the amplitude at each index +/// whose two bits differ moves to the index with them swapped. Data movement +/// alone; no amplitude is computed. +pub fn swap_bits(re: &mut [f64], im: &mut [f64], a: u32, b: u32) { + if a == b { + return; + } + let (lo, hi) = (a.min(b), a.max(b)); + let (l, h) = (1usize << lo, 1usize << hi); + for x in 0..re.len() { + if x & h != 0 && x & l == 0 { + let y = x ^ h ^ l; + re.swap(x, y); + im.swap(x, y); + } + } +} + +/// What a partitioned run did ([`run_split`]). +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub struct SplitRun { + /// The runs of launches each partition took in turn, between exchanges. + pub segments: u64, + /// The index bits exchanged between a partition bit and a local one, each + /// through the host's copy of the state. + pub exchanges: u64, +} + +/// A partition's runner: `launches`, every index bit below the partition's +/// own qubits, on its amplitudes, in place. +pub type PartRunner<'a> = &'a (dyn Fn(&mut [f64], &mut [f64], &[Launch]) -> Result<(), String> + Sync); + +/// Runs `launches` (planned for the whole state, [`plan`]) on `re`/`im` held +/// as `owner.len()` partitions by the top index bits: partition `i` is the +/// amplitudes whose top `log2(owner.len())` bits read `i`, run by +/// `runners[owner[i]]`. +/// +/// A launch whose bits are all below the partitions' bits runs on each +/// partition, the same formula on its own amplitudes. One that touches a +/// partition bit first has that bit exchanged with a local bit it does not +/// touch, through these arrays, and runs on the new layout ([`remap`]). +/// Every amplitude goes through the formulas [`replay`] applies to it, in the +/// same order, so a runner that is [`replay`] bit for bit gives the state +/// [`replay`] gives. The layout is put back at the end. +/// +/// Partitions that share a runner run one after another; each runner runs on +/// a thread of its own where the target has threads. Refused: a partition count that is not a power of +/// two of at least two, a state smaller than that, an owner past the +/// runners, or a launch wider than a partition holds. +pub fn run_split(re: &mut [f64], im: &mut [f64], launches: &[Launch], owner: &[usize], runners: &[PartRunner<'_>]) -> Result { + let len = re.len(); + if !len.is_power_of_two() || im.len() != len { + return Err("the state is not 2^n amplitudes".into()); + } + let parts = owner.len(); + if parts < 2 || !parts.is_power_of_two() { + return Err(format!("{parts} partitions: a partitioned state takes a power of two of them, at least two")); + } + let n = len.trailing_zeros(); + let p = parts.trailing_zeros(); + if p >= n { + return Err(format!("{parts} partitions of a {n}-qubit state leave no qubit in a partition")); + } + if let Some(&o) = owner.iter().find(|&&o| o >= runners.len()) { + return Err(format!("partition owner {o} names no runner")); + } + if !fits(launches, n) { + return Err("a launch acts outside the state".into()); + } + let local = n - p; + // pos[b]: where logical index bit b is held; at[q]: which logical bit + // physical bit q holds. + let mut pos: Vec = (0..n).collect(); + let mut at: Vec = (0..n).collect(); + let mut run = SplitRun::default(); + let mut segment: Vec = Vec::new(); + let flush = |re: &mut [f64], im: &mut [f64], segment: &mut Vec, run: &mut SplitRun| -> Result<(), String> { + if segment.is_empty() { + return Ok(()); + } + run.segments += 1; + let size = 1usize << local; + let mut mine: Vec> = (0..runners.len()).map(|_| Vec::new()).collect(); + for (i, (r, m)) in re.chunks_mut(size).zip(im.chunks_mut(size)).enumerate() { + mine[owner[i]].push((r, m)); + } + let seg: &[Launch] = segment; + // One runner, or a target with no threads (WebAssembly): one after + // another, the same arithmetic on each partition. + if cfg!(target_arch = "wasm32") || mine.iter().filter(|p| !p.is_empty()).count() < 2 { + for (k, parts) in mine.into_iter().enumerate() { + for (r, m) in parts { + runners[k](r, m, seg)?; + } + } + segment.clear(); + return Ok(()); + } + let results: Vec> = std::thread::scope(|scope| { + let handles: Vec<_> = mine + .into_iter() + .enumerate() + .filter(|(_, parts)| !parts.is_empty()) + .map(|(k, parts)| { + let runner = runners[k]; + scope.spawn(move || { + for (r, m) in parts { + runner(r, m, seg)?; + } + Ok(()) + }) + }) + .collect(); + handles.into_iter().map(|h| h.join().unwrap_or_else(|_| Err("a partition's runner panicked".into()))).collect() + }); + segment.clear(); + results.into_iter().collect::, String>>().map(|_| ()) + }; + for l in launches { + let bits = launch_bits(l); + if bits.len() as u32 > local { + return Err(format!("a gate on {} qubits is wider than a partition's {local}", bits.len())); + } + if bits.iter().any(|&b| pos[b as usize] >= local) { + flush(re, im, &mut segment, &mut run)?; + for &b in &bits { + let from = pos[b as usize]; + if from < local { + continue; + } + // The highest local bit this launch leaves alone. + let to = (0..local).rev().find(|&q| !bits.iter().any(|&c| pos[c as usize] == q)).ok_or("no local bit is free for an exchange")?; + swap_bits(re, im, from, to); + let other = at[to as usize]; + pos[other as usize] = from; + at[from as usize] = other; + pos[b as usize] = to; + at[to as usize] = b; + run.exchanges += 1; + } + } + segment.push(remap(l, &pos)); + } + flush(re, im, &mut segment, &mut run)?; + // The layout back: logical bit b at physical bit b. + for b in 0..n { + let from = pos[b as usize]; + if from != b { + swap_bits(re, im, from, b); + let other = at[b as usize]; + pos[other as usize] = from; + at[from as usize] = other; + pos[b as usize] = b; + at[b as usize] = b; + } + } + Ok(run) +} + /// A corpus of gate lists: the state vector's named gates at angles drawn /// from a seed, run at fusion widths 0, 2 and 3 in turn. #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -453,6 +654,124 @@ mod tests { assert!(differs, "the corpus cannot tell a reassociated formula from the reference"); } + /// The CPU's own formulas as a partition's runner. + fn cpu(re: &mut [f64], im: &mut [f64], l: &[Launch]) -> Result<(), String> { + replay(re, im, l); + Ok(()) + } + + /// Brickwork on `n` qubits whose gates reach the top qubits often, so a + /// partitioned run must exchange. + fn reaching(n: u32, layers: u32) -> Vec { + let mut gates = Vec::new(); + let mut a = 0.3f64; + for layer in 0..layers { + for q in 0..n { + a += 0.917; + gates.push(match (q + layer) % 6 { + 0 => Gate::rx(q, a), + 1 => Gate::ry(q, a), + 2 => Gate::rz(q, a), + 3 => Gate::sqrt_w(q), + 4 => Gate::h(q), + _ => Gate::t(q), + }); + } + let mut q = layer % 2; + while q + 1 < n { + gates.push(if q % 3 == 0 { Gate::fsim(q, q + 1, a, 0.5 * a) } else { Gate::cz(q, q + 1) }); + q += 2; + } + gates.push(Gate::iswap(0, n - 1)); + gates.push(Gate::fsim(1, n - 2, a, 0.25 * a)); + } + gates + } + + /// Ground truth first: the partitioned run on CPU partitions is the CPU's + /// state vector bit for bit, over the pinned corpus at every partition + /// count a case's width admits and on wide states whose gates reach the + /// partition bits, with exchanges made. + #[test] + fn a_partitioned_run_is_the_cpu_run_bit_for_bit() { + let mut runs = 0; + let mut exchanged = 0; + let runner: PartRunner<'_> = &cpu; + for case in SV_DEFAULT.cases() { + let launches = plan(case.n, &case.gates, case.width).unwrap(); + let widest = launches.iter().map(|l| launch_bits(l).len() as u32).max().unwrap_or(1); + let want = bits(&case.reference().unwrap()); + for p in 1..case.n { + if case.n - p < widest { + break; + } + let dim = 1usize << case.n; + let (mut re, mut im) = (vec![0.0; dim], vec![0.0; dim]); + re[0] = 1.0; + let owner = vec![0usize; 1 << p]; + let r = run_split(&mut re, &mut im, &launches, &owner, &[runner]).unwrap(); + assert_eq!(bits(&state_output(&re, &im)), want, "n={} width={} partitions={}", case.n, case.width, 1 << p); + runs += 1; + exchanged += u64::from(r.exchanges > 0); + } + } + for (n, width, p) in [(12u32, 0usize, 1u32), (12, 3, 2), (14, 2, 3), (16, 3, 2)] { + let gates = reaching(n, 6); + let launches = plan(n, &gates, width).unwrap(); + let mut sv = StateVector::zero(n).unwrap(); + sv.run(&gates, width).unwrap(); + let dim = 1usize << n; + let (mut re, mut im) = (vec![0.0; dim], vec![0.0; dim]); + re[0] = 1.0; + // Two runners, owning alternate partitions. + let owner: Vec = (0..1usize << p).map(|i| i % 2).collect(); + let r = run_split(&mut re, &mut im, &launches, &owner, &[runner, runner]).unwrap(); + assert!(r.exchanges > 0 && r.segments > 1, "n={n}: {r:?}"); + let same = |a: &[f64], b: &[f64]| a.iter().zip(b).all(|(x, y)| x.to_bits() == y.to_bits()); + assert!(same(&re, &sv.re) && same(&im, &sv.im), "n={n} width={width} partitions={}", 1 << p); + runs += 1; + exchanged += 1; + } + assert!(runs > 100 && exchanged > 50, "{runs} runs, {exchanged} with exchanges"); + } + + #[test] + fn exchanges_and_remaps_move_amplitudes_and_compute_nothing() { + let (mut re, mut im): (Vec, Vec) = ((0..32).map(|x| x as f64).collect(), (0..32).map(|x| -(x as f64)).collect()); + swap_bits(&mut re, &mut im, 0, 4); + for x in 0..32usize { + let y = (x & !0b10001) | ((x & 1) << 4) | ((x >> 4) & 1); + assert_eq!((re[x], im[x]), (y as f64, -(y as f64))); + } + swap_bits(&mut re, &mut im, 4, 0); + assert!(re.iter().enumerate().all(|(x, &v)| v == x as f64)); + // A launch remapped by the identity is itself, and every remap fits. + let launches = plan(5, &reaching(5, 2), 3).unwrap(); + let id: Vec = (0..5).collect(); + let rev: Vec = (0..5).rev().collect(); + for l in &launches { + assert_eq!(&remap(l, &id), l); + assert!(fits(std::slice::from_ref(&remap(l, &rev)), 5)); + } + assert!(fits(&launches, 5) && !fits(&launches, 4)); + } + + #[test] + fn a_split_refuses_what_it_cannot_hold() { + let runner: PartRunner<'_> = &cpu; + let launches = plan(4, &[Gate::fsim(0, 1, 0.3, 0.1), Gate::h(3)], 3).unwrap(); + let (mut re, mut im) = (vec![0.0; 16], vec![0.0; 16]); + re[0] = 1.0; + assert!(run_split(&mut re, &mut im, &launches, &[0, 0, 0], &[runner]).unwrap_err().contains("power of two")); + assert!(run_split(&mut re, &mut im, &launches, &[0], &[runner]).unwrap_err().contains("power of two")); + assert!(run_split(&mut re, &mut im, &launches, &[0, 1], &[runner]).unwrap_err().contains("names no runner")); + // Eight partitions of four qubits leave one qubit each: a two-qubit gate does not fit. + assert!(run_split(&mut re, &mut im, &launches, &[0; 8], &[runner]).unwrap_err().contains("wider than a partition")); + let failing = |_: &mut [f64], _: &mut [f64], _: &[Launch]| -> Result<(), String> { Err("device lost".into()) }; + let f: PartRunner<'_> = &failing; + assert_eq!(run_split(&mut re, &mut im, &launches, &[0, 1], &[runner, f]).unwrap_err(), "device lost"); + } + #[test] fn plans_refuse_what_the_state_vector_refuses() { let bad = Gate { qubits: vec![0, 0], matrix: vec![C { re: 1.0, im: 0.0 }; 16] }; diff --git a/wai/wai-quantum/src/quantum_fabric_cuda.rs b/wai/wai-quantum/src/quantum_fabric_cuda.rs index 3837e0480..91ef71941 100644 --- a/wai/wai-quantum/src/quantum_fabric_cuda.rs +++ b/wai/wai-quantum/src/quantum_fabric_cuda.rs @@ -686,25 +686,49 @@ impl CudaSv { &self.implementation } + /// The most qubits a state of this member holds: two f64 arrays of + /// `2^n` in half its free memory at discovery. + pub fn max_qubits(&self) -> u32 { + u32::from(self.member.max_qubits.saturating_sub(1)) + } + /// `gates` on `n` qubits from `|0…0⟩`, fused to `width` as the CPU fuses /// them: the real and imaginary parts. pub fn run(&self, n: u32, gates: &[crate::gates::Gate], width: usize) -> Result<(Vec, Vec), CudaError> { - use crate::quantum_fabric::sv64::{Launch, plan}; + use crate::quantum_fabric::sv64::plan; let launches = plan(n, gates, width).map_err(|_| CudaError::Internal("a gate the state vector refuses"))?; // Two f64 arrays of 2^n. - if n == 0 || n > u32::from(self.member.max_qubits.saturating_sub(1)) { + if n == 0 || n > self.max_qubits() { return Err(CudaError::TooWide { n_qubits: n.min(255) as u8, max: self.member.max_qubits.saturating_sub(1) }); } let len = 1usize << n; + let mut re = vec![0.0f64; len]; + re[0] = 1.0; + self.run_launches(&re, &vec![0.0f64; len], &launches) + } + + /// `launches` ([`sv64::plan`](crate::quantum_fabric::sv64::plan)'s, or a + /// partition's) on the state `(re, im)`: the state after them. Refused + /// unless the state is `2^n` amplitudes this member holds and every launch + /// acts within it. + pub fn run_launches(&self, re: &[f64], im: &[f64], launches: &[crate::quantum_fabric::sv64::Launch]) -> Result<(Vec, Vec), CudaError> { + use crate::quantum_fabric::sv64::{Launch, fits}; + let len = re.len(); + if !len.is_power_of_two() || len < 2 || im.len() != len { + return Err(CudaError::Internal("a state that is not 2^n amplitudes, n at least 1")); + } + let n = len.trailing_zeros(); + if n > self.max_qubits() { + return Err(CudaError::TooWide { n_qubits: n.min(255) as u8, max: self.member.max_qubits.saturating_sub(1) }); + } + if !fits(launches, n) { + return Err(CudaError::Internal("a launch outside the state")); + } let stream = &self.member.stream; - let mut init = vec![0.0f64; len]; - init[0] = 1.0; - let mut re = stream.clone_htod(&init).map_err(driver)?; - init[0] = 0.0; - let mut im = stream.clone_htod(&init).map_err(driver)?; - drop(init); + let mut re = stream.clone_htod(re).map_err(driver)?; + let mut im = stream.clone_htod(im).map_err(driver)?; let flat = |m: &[crate::linalg::C]| -> Vec { m.iter().flat_map(|c| [c.re, c.im]).collect() }; - for l in &launches { + for l in launches { match l { Launch::Diag { bitpos, diag } => { let bp = stream.clone_htod(bitpos).map_err(driver)?; diff --git a/wai/wai-quantum/src/quantum_fabric_hip.rs b/wai/wai-quantum/src/quantum_fabric_hip.rs index d7862f135..7e22074e7 100644 --- a/wai/wai-quantum/src/quantum_fabric_hip.rs +++ b/wai/wai-quantum/src/quantum_fabric_hip.rs @@ -949,27 +949,51 @@ impl HipSv { &self.implementation } + /// The most qubits a state of this member holds: two f64 arrays of + /// `2^n` in half its free memory at discovery. + pub fn max_qubits(&self) -> u32 { + u32::from(self.member.max_qubits.saturating_sub(1)) + } + /// `gates` on `n` qubits from `|0…0⟩`, fused to `width` as the CPU fuses /// them: the real and imaginary parts. pub fn run(&self, n: u32, gates: &[crate::gates::Gate], width: usize) -> Result<(Vec, Vec), HipError> { - use crate::quantum_fabric::sv64::{Launch, plan}; + use crate::quantum_fabric::sv64::plan; let launches = plan(n, gates, width).map_err(|_| HipError::Internal("a gate the state vector refuses"))?; // Two f64 arrays of 2^n. - if n == 0 || n > u32::from(self.member.max_qubits.saturating_sub(1)) { + if n == 0 || n > self.max_qubits() { return Err(HipError::TooWide { n_qubits: n.min(255) as u8, max: self.member.max_qubits.saturating_sub(1) }); } + let len = 1usize << n; + let mut re = vec![0.0f64; len]; + re[0] = 1.0; + self.run_launches(&re, &vec![0.0f64; len], &launches) + } + + /// `launches` ([`sv64::plan`](crate::quantum_fabric::sv64::plan)'s, or a + /// partition's) on the state `(re, im)`: the state after them. Refused + /// unless the state is `2^n` amplitudes this member holds and every launch + /// acts within it. + pub fn run_launches(&self, re: &[f64], im: &[f64], launches: &[crate::quantum_fabric::sv64::Launch]) -> Result<(Vec, Vec), HipError> { + use crate::quantum_fabric::sv64::{Launch, fits}; + let len = re.len(); + if !len.is_power_of_two() || len < 2 || im.len() != len { + return Err(HipError::Internal("a state that is not 2^n amplitudes, n at least 1")); + } + let n = len.trailing_zeros(); + if n > self.max_qubits() { + return Err(HipError::TooWide { n_qubits: n.min(255) as u8, max: self.member.max_qubits.saturating_sub(1) }); + } + if !fits(launches, n) { + return Err(HipError::Internal("a launch outside the state")); + } let a = self.member.api; self.member.select()?; - let len = 1usize << n; - let mut init = vec![0.0f64; len]; - init[0] = 1.0; - let re = DeviceBuffer::upload(a, &init)?; - init[0] = 0.0; - let im = DeviceBuffer::upload(a, &init)?; - drop(init); + let re = DeviceBuffer::upload(a, re)?; + let im = DeviceBuffer::upload(a, im)?; let flat = |m: &[crate::linalg::C]| -> Vec { m.iter().flat_map(|c| [c.re, c.im]).collect() }; let [diag, one, many] = [0, 1, 2].map(|k| self.kernels.functions[k]); - for l in &launches { + for l in launches { match l { Launch::Diag { bitpos, diag: d } => { let bp = DeviceBuffer::upload(a, bitpos)?; diff --git a/wai/wai-quantum/src/quantum_fabric_opencl.rs b/wai/wai-quantum/src/quantum_fabric_opencl.rs index aae1b7586..d393947f6 100644 --- a/wai/wai-quantum/src/quantum_fabric_opencl.rs +++ b/wai/wai-quantum/src/quantum_fabric_opencl.rs @@ -722,26 +722,51 @@ impl OpenClSv { &self.implementation } + /// The most qubits a state of this member holds: two f64 arrays of + /// `2^n`, each within one allocation and together within half its memory. + pub fn max_qubits(&self) -> u32 { + u32::from(self.member.max_qubits.saturating_sub(1)) + } + /// `gates` on `n` qubits from `|0…0⟩`, fused to `width` as the CPU fuses /// them: the real and imaginary parts. pub fn run(&self, n: u32, gates: &[crate::gates::Gate], width: usize) -> Result<(Vec, Vec), OpenClError> { - use crate::quantum_fabric::sv64::{Launch, plan}; + use crate::quantum_fabric::sv64::plan; let launches = plan(n, gates, width).map_err(|_| OpenClError::Internal("a gate the state vector refuses"))?; let max = self.member.max_qubits.saturating_sub(1); if n == 0 || n > u32::from(max) { return Err(OpenClError::TooWide { n_qubits: n.min(255) as u8, max }); } let len = 1usize << n; - let mut init = vec![0.0f64; len]; - init[0] = 1.0; - let re = self.member.upload(&init)?; - init[0] = 0.0; - let im = self.member.upload(&init)?; - drop(init); + let mut re = vec![0.0f64; len]; + re[0] = 1.0; + self.run_launches(&re, &vec![0.0f64; len], &launches) + } + + /// `launches` ([`sv64::plan`](crate::quantum_fabric::sv64::plan)'s, or a + /// partition's) on the state `(re, im)`: the state after them. Refused + /// unless the state is `2^n` amplitudes this member holds and every launch + /// acts within it. + pub fn run_launches(&self, re: &[f64], im: &[f64], launches: &[crate::quantum_fabric::sv64::Launch]) -> Result<(Vec, Vec), OpenClError> { + use crate::quantum_fabric::sv64::{Launch, fits}; + let len = re.len(); + if !len.is_power_of_two() || len < 2 || im.len() != len { + return Err(OpenClError::Internal("a state that is not 2^n amplitudes, n at least 1")); + } + let n = len.trailing_zeros(); + let max = self.member.max_qubits.saturating_sub(1); + if n > u32::from(max) { + return Err(OpenClError::TooWide { n_qubits: n.min(255) as u8, max }); + } + if !fits(launches, n) { + return Err(OpenClError::Internal("a launch outside the state")); + } + let re = self.member.upload(re)?; + let im = self.member.upload(im)?; let flat = |m: &[crate::linalg::C]| -> Vec { m.iter().flat_map(|c| [c.re, c.im]).collect() }; { let k = self.kernels.lock().unwrap_or_else(|p| p.into_inner()); - for l in &launches { + for l in launches { match l { Launch::Diag { bitpos, diag } => { let bp = self.member.upload(bitpos)?; diff --git a/wai/wai-quantum/tests/fabric_placement.rs b/wai/wai-quantum/tests/fabric_placement.rs new file mode 100644 index 000000000..1215b831b --- /dev/null +++ b/wai/wai-quantum/tests/fabric_placement.rs @@ -0,0 +1,183 @@ +//! Jobs placed on the fabric's members of the machine that runs this: a +//! `statevector` job on each accelerator member certified bit-exact here, and +//! split over several, must give the CPU's answers byte for byte, and name +//! where its state ran. +//! +//! The machine declares the members it expects placement to find in +//! `WAI_QUANTUM_FABRIC_EXPECT` (their keys, sorted and comma-separated, or +//! `none`; a build that reaches no accelerator expects none unless told); `WAI_QUANTUM_FABRIC_SPLIT` (optional) names a list of members, +//! comma-separated, to split one state over; `WAI_QUANTUM_FABRIC_REPORT` names +//! a file the established lines are appended to. +#![cfg(not(target_arch = "wasm32"))] + +use serde_json::{Value, json}; +use std::io::Write; +use std::time::Instant; +use wai_quantum::engine::{catalog, fabric, receipt, run}; + +const CAP: u64 = 12 << 30; + +fn report(line: &str) { + println!("{line}"); + if let Some(path) = std::env::var_os("WAI_QUANTUM_FABRIC_REPORT") { + let mut f = std::fs::OpenOptions::new().create(true).append(true).open(&path).expect("the report file opens"); + writeln!(f, "{line}").expect("the report line is written"); + } +} + +/// The accelerator members placement found, by key, each with the most +/// qubits it holds, as declared. +fn members() -> Vec<(String, u64)> { + let listed = fabric::list(CAP); + let mut found: Vec<(String, u64)> = listed["members"].as_array().unwrap().iter().filter(|m| m["key"] != "cpu").map(|m| (m["key"].as_str().unwrap().to_string(), m["detail"]["max_qubits"].as_u64().unwrap())).collect(); + found.sort(); + let keys: Vec<&str> = found.iter().map(|m| m.0.as_str()).collect(); + let found_list = if keys.is_empty() { "none".to_string() } else { keys.join(",") }; + // A build that reaches no accelerator has nothing to declare; one that + // does must say what it expects to find. + let reaches = listed["backends"].as_array().is_some_and(|b| !b.is_empty()); + let expect = match std::env::var("WAI_QUANTUM_FABRIC_EXPECT") { + Ok(e) => e, + Err(_) if !reaches => "none".to_string(), + Err(_) => panic!("WAI_QUANTUM_FABRIC_EXPECT is not set; found {found_list}; listed {listed}"), + }; + assert_eq!(found_list, expect, "the members placement found are not the declared ones: {listed}"); + found +} + +/// Brickwork at arbitrary angles on `n` qubits that reaches the top qubits, +/// asking for counts, expectation values and amplitudes. +fn job(n: u32, extra: Value) -> Value { + let mut q = format!("OPENQASM 3.0;\nqubit[{n}] q;\nbit[{n}] c;\n"); + for layer in 0..5u32 { + for i in 0..n { + q.push_str(&format!("rx({}) q[{i}];\nrz({}) q[{i}];\n", 0.13 + 0.41 * f64::from(i + layer), 0.23 * f64::from(layer + 1) + 0.01 * f64::from(i))); + } + for i in (layer % 2..n - 1).step_by(2) { + q.push_str(&format!("cx q[{i}], q[{}];\nry({}) q[{}];\n", i + 1, 0.3 + 0.07 * f64::from(i), i + 1)); + } + q.push_str(&format!("cp(0.9) q[0], q[{}];\nswap q[1], q[{}];\n", n - 1, n - 2)); + } + q.push_str("c = measure q;\n"); + let mut v = json!({ "qasm": q, "shots": 4000, "seed": 3, "method": "statevector", "observables": ["Z0 Z1", "X2", format!("Y{} Z0", n - 1)], "amplitudes": ["0".repeat(n as usize), format!("1{}", "0".repeat(n as usize - 1))] }); + if let (Some(o), Some(e)) = (v.as_object_mut(), extra.as_object()) { + o.extend(e.clone()); + } + v +} + +fn ran(v: &Value) -> Result { + let p = catalog::plan(v, CAP)?; + run::run(v, &p) +} + +/// The answers, without where the state ran and how long it took. +fn answers(out: &Value) -> Vec { + let mut o = out.clone(); + for k in ["fabric", "elapsed_ms"] { + o.as_object_mut().unwrap().remove(k); + } + receipt::canonical(&o) +} + +#[test] +fn p0_each_member_gives_the_cpus_answers_byte_for_byte() { + let found = members(); + report(&format!("fabric members: as declared ({})", if found.is_empty() { "none".to_string() } else { found.iter().map(|m| m.0.as_str()).collect::>().join(",") })); + for (key, max) in &found { + for n in [12u32, 18] { + let cpu = ran(&job(n, json!({ "fabric": "cpu" }))).unwrap(); + let placed = ran(&job(n, json!({ "fabric": key }))).unwrap_or_else(|e| panic!("{key}: {e}")); + assert_eq!(placed["fabric"]["key"], json!(key), "{}", placed["fabric"]); + assert_eq!(placed["fabric"]["parity"]["tier"], "bit-exact"); + assert_eq!(answers(&placed), answers(&cpu), "{key}: n={n}: the answers differ from the CPU's"); + } + report(&format!("fabric placed: key={key} max_qubits={max} 12 and 18 qubits give the CPU's answers byte for byte")); + } +} + +#[test] +fn p1_auto_places_a_wide_state_and_keeps_a_small_one_on_the_cpu() { + let found = members(); + let small = ran(&job(8, json!({}))).unwrap(); + assert!(small.get("fabric").is_none(), "a state below the auto threshold stays on the CPU, unnamed: {}", small["fabric"]); + let Some((first, _)) = found.first() else { + let wide = ran(&job(fabric::AUTO_MIN_QUBITS, json!({}))).unwrap(); + assert!(wide.get("fabric").is_none(), "with no member, a job runs as it always did"); + report("fabric auto: no member; every state stays on the CPU, its result unnamed"); + return; + }; + let n = fabric::AUTO_MIN_QUBITS + 1; + let t = Instant::now(); + let cpu = ran(&job(n, json!({ "fabric": "cpu" }))).unwrap(); + let cpu_ms = t.elapsed().as_millis(); + let t = Instant::now(); + let auto = ran(&job(n, json!({}))).unwrap(); + let auto_ms = t.elapsed().as_millis(); + let listed = fabric::list(CAP); + let want_first = listed["members"][1]["key"].as_str().unwrap(); + assert_eq!(auto["fabric"]["key"].as_str(), Some(want_first), "auto takes the first member listed: {}", auto["fabric"]); + assert_eq!(auto["fabric"]["asked"], "auto"); + assert_eq!(answers(&auto), answers(&cpu), "auto: the answers differ from the CPU's"); + report(&format!("fabric auto: {n} qubits on {want_first} (of {first} and the rest), the CPU's answers byte for byte; cpu {cpu_ms} ms, placed {auto_ms} ms")); +} + +#[test] +fn p2_a_state_split_over_members_is_the_cpus() { + let found = members(); + let mut lists: Vec> = Vec::new(); + if let Some((k, _)) = found.first() { + lists.push(vec![k.clone(), "cpu".into()]); + lists.push(vec![k.clone(), k.clone()]); + lists.push(vec![k.clone(), "cpu".into(), k.clone(), "cpu".into()]); + } + if let Ok(s) = std::env::var("WAI_QUANTUM_FABRIC_SPLIT") { + lists.push(s.split(',').map(str::to_string).collect()); + } + lists.push(vec!["cpu".into(), "cpu".into()]); + for list in &lists { + for n in [14u32, 19] { + let cpu = ran(&job(n, json!({ "fabric": "cpu" }))).unwrap(); + let split = ran(&job(n, json!({ "fabric": list }))).unwrap_or_else(|e| panic!("{list:?}: {e}")); + let f = &split["fabric"]; + assert_eq!(f["partitions"].as_array().map(Vec::len), Some(list.len()), "{f}"); + assert!(f["exchanges"].as_u64().unwrap() > 0, "{f}"); + assert_eq!(answers(&split), answers(&cpu), "{list:?}: n={n}: the answers differ from the CPU's"); + } + report(&format!("fabric split: {} over 14 and 19 qubits gives the CPU's answers byte for byte", list.join("+"))); + } +} + +#[test] +fn p3_a_state_past_a_member_is_refused_before_it_runs() { + for (key, max) in members() { + let n = (max + 1) as u32; + // Planned only: the refusal comes before any memory is taken. + let e = catalog::plan(&job(n, json!({ "fabric": key, "shots": 1, "observables": [], "amplitudes": [] })), 64 << 30).unwrap_err(); + assert!(e.ends_with("[J013]") && e.contains(&format!("holds at most {max}")), "{key}: {e}"); + report(&format!("fabric refused: key={key} a state of {n} qubits, past the {max} it holds")); + } +} + +/// Where auto's threshold comes from: the time of the same job on the CPU and +/// on each member, from 14 to 24 qubits, reported and not asserted. +#[test] +fn p4_the_time_of_a_job_on_the_cpu_and_on_each_member() { + for (key, max) in members() { + for n in (14u32..=24).step_by(2).filter(|&n| u64::from(n) <= max) { + let shots = json!({ "shots": 1, "observables": [], "amplitudes": [] }); + let mut cpu = job(n, json!({ "fabric": "cpu" })); + let mut placed = job(n, json!({ "fabric": key })); + cpu.as_object_mut().unwrap().extend(shots.as_object().unwrap().clone()); + placed.as_object_mut().unwrap().extend(shots.as_object().unwrap().clone()); + let t = Instant::now(); + let a = ran(&cpu).unwrap(); + let cpu_ms = t.elapsed().as_secs_f64() * 1e3; + let t = Instant::now(); + let b = ran(&placed).unwrap(); + let placed_ms = t.elapsed().as_secs_f64() * 1e3; + assert_eq!(answers(&a), answers(&b), "{key}: n={n}"); + report(&format!("fabric timing: key={key} n={n} cpu={cpu_ms:.1}ms placed={placed_ms:.1}ms")); + } + } +} -- 2.54.0 (Apple Git-157) From 57638f48a534d306ca4f98fd3d8e5d7bc1e0a80f Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Fri, 30 Oct 2026 12:14:23 -0400 Subject: [PATCH 2/7] wai-quantum: Clifford+T circuits as sums of stabilizer states (stabilizer_rank) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A T gate is (e^{iπ/8} I + e^{−iπ/8} S) / (2 cos π/8), and T† its conjugate, so a circuit with t of them is a sum of 2^t Clifford circuits of equal weight. quantum_stabrank walks every branch on the phased tableau, whose new PhasedTableau::amplitudes gives every amplitude of a stabilizer state exactly from one reduction of the stabilizers (d = x ⊕ r in the X span, the phase read off the product of pivot rows). Every term is a power of 1/√2 at a whole number of sixteenths of a turn, counted as a whole number (ExactSum), so the sum does not depend on how the branches are split between threads and is evaluated once in double precision. An expectation value is the amplitude ⟨0|U†PU|0⟩ of one circuit with twice the T gates. Exact mode: terms grow as 2^t (4^t for an expectation value). Sampled mode (terms, or epsilon, at confidence): branches drawn uniformly, seeded, each from a stream of its own; the estimate is unbiased with mean squared distance (sec²(π/8)^t − 1)/terms, so each value is within sqrt((sec²(π/8)^t − 1)/(terms·(1 − confidence))) with the stated probability, computed from t, terms and confidence and stated beside each value. Program::clifford_t lowers t, tdg, p/rz/rx/ry at odd multiples of π/4, cp at odd multiples of π/2, ccz and ccx, with the global phase kept exactly. Ground truth first: every amplitude of random Clifford+T circuits (up to 7 qubits, 10 T gates) and of random programs through the job engine equals the dense state vector's, phase and all, within 1e-12, by fidelity; expectation values likewise; the sampled bound holds in at least its stated fraction of seeds, measured on the whole state. The planner names stabilizer_rank and auto chooses it by T count (amplitudes or expectation values past the dense state vector, its branches within one job's work, calibrated at about 4e10 tableau word operations a second on a 16-core host). Optional t_count, terms, bound and confidence in the result schema; the methods list, both MCP servers, the service and the docs name it. Co-Authored-By: Claude Opus 5.5 --- wai/CHANGELOG.md | 15 + wai/wai-quantum-cli/README.md | 1 + wai/wai-quantum-cli/README.zh-CN.md | 1 + wai/wai-quantum-cli/docs/llms-full.txt | 13 +- wai/wai-quantum-cli/docs/local-mcp.json | 13271 +---------------- wai/wai-quantum-cli/docs/service-mcp.json | 14553 +------------------ wai/wai-quantum-cli/src/main.rs | 7 +- wai/wai-quantum-service/README.md | 3 +- wai/wai-quantum-service/src/discovery.rs | 2 +- wai/wai-quantum-service/src/mcp.rs | 2 +- wai/wai-quantum/README.md | 50 + wai/wai-quantum/README.zh-CN.md | 24 + wai/wai-quantum/schemas/job-result.v1.json | 32 +- wai/wai-quantum/src/engine/catalog.rs | 121 +- wai/wai-quantum/src/engine/guide.rs | 2 +- wai/wai-quantum/src/engine/run.rs | 176 + wai/wai-quantum/src/lib.rs | 3 + wai/wai-quantum/src/qasm.rs | 89 + wai/wai-quantum/src/quantum_stabrank.rs | 644 + wai/wai-quantum/src/quantum_tableau.rs | 92 + 20 files changed, 1767 insertions(+), 27334 deletions(-) create mode 100644 wai/wai-quantum/src/quantum_stabrank.rs diff --git a/wai/CHANGELOG.md b/wai/CHANGELOG.md index cd8fc0113..d3adc200f 100644 --- a/wai/CHANGELOG.md +++ b/wai/CHANGELOG.md @@ -300,6 +300,21 @@ wire format may change and such changes are recorded here. - **CI**: `tests/fabric_placement.rs` on jetson-hub (CUDA and OpenCL) and framework-128gb (HIP and OpenCL) in the hardware workflows, each with its declared members and a split over them, and absent where there is no device; the split and the planner's refusals in the containers. +- **Stabilizer-rank Clifford+T** (`quantum_stabrank`, the method `stabilizer_rank`): a T gate is a sum of two + Clifford gates of equal weight, so a circuit with `t` T and T† gates is a sum of `2^t` stabilizer states, each run + exactly on the phased tableau, whose new `PhasedTableau::amplitudes` gives every amplitude of a stabilizer state + exactly from one reduction. Every term is counted as a whole number (`ExactSum`), so the sum does not depend on + how the branches are split between threads; an expectation value is the amplitude `⟨0|U†PU|0⟩`. The exact mode's + terms grow as `2^t` (`4^t` for an expectation value); the sampled mode (`terms`, or `epsilon`, at `confidence`) + draws branches uniformly and states the bound `sqrt((sec²(π/8)^t − 1) / (terms · (1 − confidence)))` on each + value with its confidence, computed from the T count, the terms and the confidence. `Program::clifford_t` lowers + `t`, `tdg`, `p`, `rz`, `rx` and `ry` at odd multiples of π/4, `cp` at odd multiples of π/2, `ccz` and `ccx` with + the global phase kept exactly. Held to the dense state vector by every amplitude and by fidelity, never by hash. + `auto` takes it for amplitudes or expectation values past the dense state vector when its branches fit one job's + work, so it is chosen by the T count; it reaches the methods list, both MCP servers and the service by the same + name. The result's accuracy, amplitudes and expectation values gain optional `t_count`, `terms`, `bound` and + `confidence` (`wai.quantum.job-result/1`), and the class `estimate` now also covers a bound with the probability it + holds. ### wai-quantum: the variational and algorithm library diff --git a/wai/wai-quantum-cli/README.md b/wai/wai-quantum-cli/README.md index 7066e5882..1aac9d23f 100644 --- a/wai/wai-quantum-cli/README.md +++ b/wai/wai-quantum-cli/README.md @@ -96,6 +96,7 @@ wai-quantum instance ghz-family.qasm --input n=3 | pauli | Pauli dynamics, for expectation values | | tensor_network | amplitudes | | cutrank | a Clifford circuit with a layer of rotations | +| stabilizer_rank | Clifford+T circuits, as a sum of stabilizer states: amplitudes and expectation values, exact, or sampled with a stated bound (`--option terms=N` or `--option epsilon=E`) | | density_matrix, trajectories | noise | `wai-quantum methods` lists each method's reach in a job's memory here (`--memory-gb`, default 16). diff --git a/wai/wai-quantum-cli/README.zh-CN.md b/wai/wai-quantum-cli/README.zh-CN.md index 59804445f..a77d4f6a1 100644 --- a/wai/wai-quantum-cli/README.zh-CN.md +++ b/wai/wai-quantum-cli/README.zh-CN.md @@ -99,6 +99,7 @@ wai-quantum instance ghz-family.qasm --input n=3 | pauli | Pauli 动力学,用于期望值 | | tensor_network | 振幅 | | cutrank | 带一层旋转的 Clifford 线路 | +| stabilizer_rank | Clifford+T 线路,写成稳定子态之和:振幅和期望值,精确,或以给定界抽样(`--option terms=N` 或 `--option epsilon=E`) | | density_matrix, trajectories | 噪声 | `wai-quantum methods` 列出每种方法在本机一个作业的内存(`--memory-gb`,默认 16)内能达到的规模。 diff --git a/wai/wai-quantum-cli/docs/llms-full.txt b/wai/wai-quantum-cli/docs/llms-full.txt index 79824e8e5..1f23088b2 100644 --- a/wai/wai-quantum-cli/docs/llms-full.txt +++ b/wai/wai-quantum-cli/docs/llms-full.txt @@ -501,7 +501,7 @@ Parameters: - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, density_matrix, trajectories): Leave as auto unless you need a particular method. +- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, stabilizer_rank, density_matrix, trajectories): Leave as auto unless you need a particular method. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. @@ -521,7 +521,7 @@ Parameters: - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, density_matrix, trajectories): Leave as auto unless you need a particular method. +- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, stabilizer_rank, density_matrix, trajectories): Leave as auto unless you need a particular method. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. @@ -543,7 +543,7 @@ Parameters: - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, density_matrix, trajectories): Leave as auto unless you need a particular method. +- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, stabilizer_rank, density_matrix, trajectories): Leave as auto unless you need a particular method. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. @@ -907,7 +907,7 @@ A program that measures a qubit and then acts on it, resets one after its first - On this machine: `wai-quantum run`, or the local MCP server (`wai-quantum mcp`). Results are signed with the user's key and nothing leaves the machine. - On the free job service, for a program too large for this machine: `wai-quantum submit`, `POST https://wai.transaction.science/quantum-jobs/v1/run`, or its MCP server at https://wai.transaction.science/quantum-jobs/mcp. No account and no key. -- auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen. +- auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, stabilizer_rank, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, stabilizer_rank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen; stabilizer_rank is chosen by its T count, its exact sum taken when its branches are within one job's work. - The statevector method's state runs where the job's `fabric` says: auto (the default) places a state of 20 qubits or more on the first accelerator member of the fabric found here and certified bit-exact against the CPU (`wai-quantum fabric`, or list_fabric, lists them), and keeps a smaller one on the CPU; cpu, accelerator (any certified accelerator member) or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere. ### `wai-quantum://docs/diagnostics`: the reader's diagnostics @@ -1036,6 +1036,7 @@ Every code: | `stabilizer` | exact; with Pauli noise, counts are noisy samples and expectations estimates | Clifford (rotations by whole quarter turns, controlled phases by whole half turns), optionally with depolarizing, dephasing and readout noise | counts, expectations | | `pauli` | bounded | any | expectations | | `mps` | exact when nothing is truncated, otherwise heuristic | any; best on low-entanglement circuits | counts, expectations, amplitudes | +| `stabilizer_rank` | exact; with terms or epsilon, an estimate with its bound | Clifford+T (t, tdg, and p, rz, rx, ry at odd multiples of π/4, cp at odd multiples of π/2, ccz and ccx), each T gate doubling the sum's terms: the state as a sum of stabilizer states | amplitudes, expectations | | `tensor_network` | exact | any | amplitudes | | `cutrank` | exact; single when only a single-precision table fits | a Clifford circuit, then one layer of one-qubit gates at any angles: each qubit's gates from its first non-Clifford one on act on that qubit alone; the cost is set by the state's cut-rank along an order of the qubits, not by their number | counts, amplitudes | | `cutrank_single` | single | as for cutrank; the table on a GPU, its arithmetic in single precision | counts, amplitudes | @@ -1047,10 +1048,10 @@ The accuracy classes: - bit-exact: the same bits on every machine: amplitudes in 30-bit fixed point, every output an exact function of them; counts are seeded samples - exact: no approximation beyond IEEE double-precision rounding; counts are seeded samples of the exact distribution - bounded: an approximation with a rigorous bound on |exact − value| reported beside each value -- estimate: a statistical estimate, reported with its standard error +- estimate: a statistical estimate, reported with its standard error, or with a bound on its error and the probability that the bound holds - heuristic: an approximation reported with the standard estimate of its error (a matrix product state's fidelity estimate), not a bound -auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen. +auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, stabilizer_rank, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, stabilizer_rank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen; stabilizer_rank is chosen by its T count, its exact sum taken when its branches are within one job's work. The statevector method's state runs where the job's `fabric` says: auto (the default) places a state of 20 qubits or more on the first accelerator member of the fabric found here and certified bit-exact against the CPU (`wai-quantum fabric`, or list_fabric, lists them), and keeps a smaller one on the CPU; cpu, accelerator (any certified accelerator member) or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere. diff --git a/wai/wai-quantum-cli/docs/local-mcp.json b/wai/wai-quantum-cli/docs/local-mcp.json index dd98785fc..fc5b423eb 100644 --- a/wai/wai-quantum-cli/docs/local-mcp.json +++ b/wai/wai-quantum-cli/docs/local-mcp.json @@ -7,45 +7,10 @@ "description": "Run an OpenQASM program on this machine, planned as the quantum job service plans it: measurement counts, Pauli expectation values and/or amplitudes, the method chosen and why, its accuracy class, and a receipt signed with this user's key. Give `intent` (an exact distribution, or a reference program it must equal or whose state it must prepare) and the engine checks it with the run. Every answer carries `verdict`: the level the engine checked to (proof, evidence, executed, parsed, refused), whether the intent holds and a plain statement, sealed in the receipt. Quote the verdict and the numbers; do not estimate them or claim more.", "inputSchema": { "type": "object", - "anyOf": [ - { - "required": [ - "qasm" - ] - }, - { - "required": [ - "source" - ] - } + "required": [ + "qasm" ], "properties": { - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", - "properties": { - "format": { - "type": "string", - "enum": [ - "qasm", - "qir", - "jeff" - ], - "description": "Its format." - }, - "program": { - "type": "string", - "description": "The program's text: QIR (LLVM text) or OpenQASM." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64: jeff." - } - } - }, "qasm": { "type": "string", "description": "The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in \"inputs\"). while, inv and pow are refused with their line." @@ -69,7 +34,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." + "description": "auto (the default: the strongest method the program admits), or one of list_methods' names." }, "observables": { "type": "array", @@ -409,128 +374,6 @@ } } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050)." } } }, @@ -602,11 +445,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -614,30 +452,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -652,7 +466,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -1200,13 +1014,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -1231,121 +1038,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -1468,23 +1160,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -1544,7 +1237,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -1606,6 +1303,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -3369,237 +3075,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -3853,11 +3328,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -3865,30 +3335,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -3903,7 +3349,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -4451,13 +3897,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -4482,121 +3921,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -4717,23 +4041,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -4793,7 +4118,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -4855,6 +4184,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -6618,237 +5956,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -7705,45 +6812,10 @@ "description": "The method a program would run on and why, the memory and work it would take, without running it.", "inputSchema": { "type": "object", - "anyOf": [ - { - "required": [ - "qasm" - ] - }, - { - "required": [ - "source" - ] - } + "required": [ + "qasm" ], "properties": { - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", - "properties": { - "format": { - "type": "string", - "enum": [ - "qasm", - "qir", - "jeff" - ], - "description": "Its format." - }, - "program": { - "type": "string", - "description": "The program's text: QIR (LLVM text) or OpenQASM." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64: jeff." - } - } - }, "qasm": { "type": "string", "description": "The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in \"inputs\"). while, inv and pow are refused with their line." @@ -7767,7 +6839,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." + "description": "auto (the default: the strongest method the program admits), or one of list_methods' names." }, "observables": { "type": "array", @@ -8107,128 +7179,6 @@ } } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050)." } } }, @@ -13540,274 +12490,6 @@ ] } }, - { - "name": "convert_program", - "title": "Convert a program between formats", - "description": "Carry a program between OpenQASM 3, QIR (LLVM text, read under its base and adaptive profiles, written as QIR 2.0) and jeff (its Cap'n Proto message, as base64). The answer is the program written, the program as OpenQASM 3 (what every other tool takes), each note with its code (a rotation at an arbitrary angle, a custom gate read by its name, what a format leaves out), what was read and written, and the check: the output read back and held to the program by the equivalence ladder. A construct a reader cannot hold exactly is refused with its code (Q700 to Q721) and its place: quote the code, and never guess around it.", - "inputSchema": { - "type": "object", - "required": [ - "to" - ], - "properties": { - "program": { - "type": "string", - "description": "The program's text: OpenQASM or QIR." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64: jeff." - }, - "from": { - "type": "string", - "enum": [ - "qasm", - "qir", - "jeff" - ], - "description": "Its format; found from its bytes when not given." - }, - "to": { - "type": "string", - "enum": [ - "qasm", - "qir", - "jeff" - ], - "description": "The format to write." - }, - "profile": { - "type": "string", - "enum": [ - "base", - "adaptive" - ], - "description": "QIR's profile to write: by default base when the program's measurements all come at the end, else adaptive." - }, - "check": { - "type": "boolean", - "description": "false: write it without the check." - } - } - }, - "outputSchema": { - "$id": "wai-quantum://schemas/convert_program/1", - "type": "object", - "description": "A program carried from one format to another (OpenQASM 3, QIR as LLVM text, jeff as its Cap'n Proto message) and checked (engine::formats::convert_json): the program written, the program as read in OpenQASM 3, the readers' and writer's notes with their codes, what was read and written, and the check that holds the output to the input.", - "anyOf": [ - { - "type": "object", - "description": "A program carried from one format to another (OpenQASM 3, QIR as LLVM text, jeff as its Cap'n Proto message) and checked (engine::formats::convert_json): the program written, the program as read in OpenQASM 3, the readers' and writer's notes with their codes, what was read and written, and the check that holds the output to the input.", - "required": [ - "ok", - "format", - "from", - "to", - "qasm", - "notes", - "read", - "written", - "check" - ], - "properties": { - "ok": { - "const": true - }, - "format": { - "const": "wai.quantum.convert/1" - }, - "from": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "to": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program written, for a text format (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program written, for a binary format (jeff), as standard base64." - }, - "qasm": { - "type": "string", - "description": "The program as read, as OpenQASM 3: what every other tool takes." - }, - "notes": { - "type": "array", - "items": { - "type": "object", - "description": "One of the reader's diagnostics: its code, what happens to the construct it is about, its message (without the line or the code), and where it stands.", - "required": [ - "code", - "outcome", - "message" - ], - "properties": { - "code": { - "type": "string" - }, - "outcome": { - "enum": [ - "refused", - "lowered", - "carried", - "preserved", - "warned" - ] - }, - "message": { - "type": "string" - }, - "line": { - "type": "integer", - "minimum": 1 - }, - "column": { - "type": "integer", - "minimum": 1 - }, - "length": { - "type": "integer", - "minimum": 0 - } - } - }, - "description": "Each warning and note, with its code (Q7xx for the formats) and, for QIR, its line." - }, - "read": { - "type": "object", - "required": [ - "format" - ], - "description": "What was read: the format, its version, a QIR module's profile, entry point, qubits, results and declared capabilities, a jeff module's tool, entry point, qubits and bits." - }, - "written": { - "type": "object", - "required": [ - "format" - ], - "description": "What was written: the format, its version, and QIR's profile." - }, - "check": { - "anyOf": [ - { - "type": "null" - }, - { - "type": "object", - "required": [ - "what", - "verdict" - ], - "properties": { - "what": { - "type": "string", - "description": "What was held to what." - }, - "verdict": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "tableau", - "exact", - "rewrites", - "random", - "state", - "shape", - "steps", - "distribution", - "identity", - "none" - ], - "description": "The equivalence ladder's check (tableau, exact and rewrites are proofs; random is evidence); steps: the same steps one for one; distribution: every outcome's probability the same (evidence); identity: OpenQASM passed through; none: unchecked." - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": [ - "number", - "null" - ] - } - } - } - } - } - ], - "description": "The output read back and held to the program read (or, for a program read into OpenQASM, written back to its format and read again), or null when no check was asked." - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, { "name": "improve_qasm", "title": "Improve an OpenQASM program", @@ -20204,10 +18886,10 @@ "outputSchema": { "$id": "wai-quantum://schemas/verify_quantum_result/1", "type": "object", - "description": "Whether a job's receipt seals its request and its result, and the key that signed it; for an estimate, also every estimate's receipt and the request re-run here; for an answer of the variational and algorithm library, also its digest chain and the answer re-run here.", + "description": "Whether a job's receipt seals its request and its result, and the key that signed it; for an estimate, also every estimate's receipt and the request re-run here.", "anyOf": [ { - "description": "Whether a job's receipt seals its request and its result, and the key that signed it; for an estimate, also every estimate's receipt and the request re-run here; for an answer of the variational and algorithm library, also its digest chain and the answer re-run here.", + "description": "Whether a job's receipt seals its request and its result, and the key that signed it; for an estimate, also every estimate's receipt and the request re-run here.", "anyOf": [ { "type": "object", @@ -20267,48 +18949,6 @@ "type": "integer" } } - }, - { - "type": "object", - "description": "Whether a sealed answer of the library holds: its receipt over the request and the result, an optimisation's digest chain, and the answer run again to the same bytes (every call is deterministic and carries no clock).", - "required": [ - "valid", - "signed", - "chain", - "rerun", - "key" - ], - "properties": { - "valid": { - "type": "boolean" - }, - "signed": { - "type": "boolean" - }, - "chain": { - "type": [ - "boolean", - "null" - ], - "description": "An optimisation's chain: every step's digest the link over that step, from the request; null for an answer with no steps." - }, - "rerun": { - "type": "boolean" - }, - "rerun_error": { - "type": [ - "string", - "null" - ] - }, - "key": { - "type": [ - "string", - "null" - ], - "description": "The signing key, 32 bytes in hex." - } - } } ] }, @@ -28243,45 +26883,11 @@ "description": "Run an OpenQASM program here as it would run on a device target: compiled exactly to the target's native gates, placed on the qubits and routes most likely to succeed (the expected success given beside the fewest-swaps layout's), checked against the circuit, and simulated under the noise its calibration gives (each gate's error, T1, T2 and durations, idling, and each qubit's readout), on the density matrix or by trajectories. Counts and expectation values, their distance from the ideal distribution, the noise derived, and a receipt signed with this user's key that binds the target's hash. A model of the device, not a run on it: quote it as such. Every angle must be a dyadic multiple of 2π.", "inputSchema": { "type": "object", - "anyOf": [ - { - "required": [ - "qasm" - ] - }, - { - "required": [ - "source" - ] - } + "required": [ + "qasm", + "target" ], "properties": { - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", - "properties": { - "format": { - "type": "string", - "enum": [ - "qasm", - "qir", - "jeff" - ], - "description": "Its format." - }, - "program": { - "type": "string", - "description": "The program's text: QIR (LLVM text) or OpenQASM." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64: jeff." - } - } - }, "qasm": { "type": "string", "description": "The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in \"inputs\"). while, inv and pow are refused with their line." @@ -28305,7 +26911,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." + "description": "auto (the default: the strongest method the program admits), or one of list_methods' names." }, "observables": { "type": "array", @@ -28645,133 +27251,8 @@ } } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050)." } - }, - "required": [ - "target" - ] + } }, "outputSchema": { "$id": "wai-quantum://schemas/run_on_target/1", @@ -28841,11 +27322,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -28853,30 +27329,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -28891,7 +27343,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -29439,13 +27891,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -29470,121 +27915,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -29707,23 +28037,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -29783,7 +28114,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -29845,6 +28180,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -31608,237 +29952,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -32092,11 +30205,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -32104,30 +30212,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -32142,7 +30226,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -32690,13 +30774,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -32721,121 +30798,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -32956,23 +30918,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -33032,7 +30995,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -33094,6 +31061,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -34857,237 +32833,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -37343,9912 +35088,6 @@ ] } }, - { - "name": "pulse_schedule", - "title": "Read a pulse program into its schedule", - "description": "Read a pulse program (OpenPulse calibrations: ports, frames, waveforms, play, delay, shift_phase, set_phase, shift_frequency, set_frequency, captures and barriers) into its schedule on frames: every instruction at its sample, each waveform's samples (gaussian, drag, gaussian_square, constant, sech, sine, or explicit), each gate call with the samples its calibration spans, and the digests a pulse run's receipt binds (the program, its calibrations, the schedule). Durations are whole samples of dt (pulse.dt_ns, default 0.5 ns) or refused. A construct the reader does not take is refused with a Q code and its line. Sealed with this user's key. To run it, give the program to run_quantum_circuit with method \"pulse\".", - "inputSchema": { - "type": "object", - "required": [ - "qasm" - ], - "properties": { - "qasm": { - "type": "string", - "description": "A pulse program: OpenQASM 3 with `defcalgrammar \"openpulse\";`, `cal` blocks declaring ports (d0 drives qubit 0, m0 is its measurement port, a0 its acquisition port), frames (newframe(port, frequency Hz, phase)) and waveforms, a `defcal` for every gate it calls on physical qubits ($0), and the calls." - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/pulse_schedule/1", - "type": "object", - "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.pulse/1", - "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A schedule or a check, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A pulse program's schedule (pulse_schedule, wai-quantum pulse schedule, POST /v1/pulse/schedule): its frames and ports, every instruction at its sample, each waveform's samples, the gate calls, the reader's notes, and the digests a run binds.", - "required": [ - "answer", - "dt_ns", - "duration", - "frames", - "waveforms", - "instructions", - "calls", - "calibration" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.pulse/1" - }, - "answer": { - "const": "schedule" - }, - "dt_ns": { - "type": "number", - "description": "The sample period, ns." - }, - "duration": { - "type": "integer", - "description": "The latest time of any frame, samples." - }, - "duration_ns": { - "type": "number" - }, - "grammar": { - "type": [ - "string", - "null" - ] - }, - "ports": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer" - } - } - } - }, - "frames": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "frequency_hz": { - "type": "number" - }, - "phase": { - "type": "number" - } - } - } - }, - "waveforms": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "length": { - "type": "integer" - }, - "samples": { - "type": "array", - "items": { - "type": "array", - "items": { - "type": "number" - }, - "minItems": 2, - "maxItems": 2 - } - }, - "samples_every": { - "type": "integer", - "description": "Each k-th sample is drawn, when the schedule holds more than the view writes out." - } - } - } - }, - "instructions": { - "type": "array", - "items": { - "type": "object", - "required": [ - "frame", - "op", - "start", - "length" - ], - "properties": { - "frame": { - "type": "integer" - }, - "op": { - "enum": [ - "play", - "delay", - "shift_phase", - "set_phase", - "shift_frequency", - "set_frequency", - "capture", - "barrier" - ] - }, - "start": { - "type": "integer" - }, - "length": { - "type": "integer" - }, - "line": { - "type": "integer" - }, - "waveform": { - "type": "integer" - }, - "phase": { - "type": "number" - }, - "frequency_hz": { - "type": "number" - }, - "carrier": { - "type": "number", - "description": "The carrier's phase at the play's first sample, cycles in [0, 1)." - }, - "value": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "calls": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "params": { - "type": "array", - "items": { - "type": "number" - } - }, - "start": { - "type": "integer" - }, - "end": { - "type": "integer" - }, - "line": { - "type": "integer" - } - } - } - }, - "bits": { - "type": "array", - "items": { - "type": "string" - } - }, - "qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "decimated": { - "type": "string" - }, - "diagnostics": { - "type": "array", - "items": { - "type": "object", - "description": "A reader's note or warning (qasm::diag).", - "properties": { - "code": { - "type": "string" - }, - "outcome": { - "type": "string" - }, - "message": { - "type": "string" - }, - "line": { - "type": "integer" - }, - "column": { - "type": "integer" - }, - "length": { - "type": "integer" - } - } - } - }, - "calibration": { - "type": "object", - "description": "What a pulse run's receipt binds of the program: the BLAKE3 of the control program's text, of its calibrations as written (every cal, defcal and defcalgrammar, joined by newlines), and of the schedule's JSON; a run adds the device's and the target snapshot's.", - "required": [ - "program", - "calibrations", - "schedule" - ], - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - } - } - }, - { - "type": "object", - "description": "A pulse job checked (pulse_check, wai-quantum pulse check, POST /v1/pulse/check): its receipt's signature, its program's digest, and the request run again with the result held to the one given.", - "required": [ - "answer", - "verified", - "signature", - "program", - "reproduced", - "differences", - "statement" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.pulse/1" - }, - "answer": { - "const": "check" - }, - "verified": { - "type": "boolean" - }, - "signature": { - "type": "boolean" - }, - "key": {}, - "program": { - "type": "boolean" - }, - "reproduced": { - "type": "boolean" - }, - "differences": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Each field (or field.member) whose value differs from the run here." - }, - "density_hash": { - "type": "object", - "properties": { - "given": {}, - "recomputed": {} - } - }, - "calibration": {}, - "statement": { - "type": "string" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "pulse_check", - "title": "Check a pulse run by running it again", - "description": "Check a pulse job as a host returned it ({\"request\", \"result\"}, the result with its receipt): the receipt's signature, the program's digest against the request's text, and the request run again here with the result held to the one given field by field (the density matrix's digest among them), each difference named. A pulse run is the same bits on every platform, so a result that does not reproduce was not made from that request by this engine. Sealed with this user's key. Quote `verified` and the statement.", - "inputSchema": { - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The pulse job's request." - }, - "result": { - "type": "object", - "description": "Its result, with its receipt." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/pulse_check/1", - "type": "object", - "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.pulse/1", - "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A schedule or a check, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A pulse program's schedule (pulse_schedule, wai-quantum pulse schedule, POST /v1/pulse/schedule): its frames and ports, every instruction at its sample, each waveform's samples, the gate calls, the reader's notes, and the digests a run binds.", - "required": [ - "answer", - "dt_ns", - "duration", - "frames", - "waveforms", - "instructions", - "calls", - "calibration" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.pulse/1" - }, - "answer": { - "const": "schedule" - }, - "dt_ns": { - "type": "number", - "description": "The sample period, ns." - }, - "duration": { - "type": "integer", - "description": "The latest time of any frame, samples." - }, - "duration_ns": { - "type": "number" - }, - "grammar": { - "type": [ - "string", - "null" - ] - }, - "ports": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer" - } - } - } - }, - "frames": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "frequency_hz": { - "type": "number" - }, - "phase": { - "type": "number" - } - } - } - }, - "waveforms": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "length": { - "type": "integer" - }, - "samples": { - "type": "array", - "items": { - "type": "array", - "items": { - "type": "number" - }, - "minItems": 2, - "maxItems": 2 - } - }, - "samples_every": { - "type": "integer", - "description": "Each k-th sample is drawn, when the schedule holds more than the view writes out." - } - } - } - }, - "instructions": { - "type": "array", - "items": { - "type": "object", - "required": [ - "frame", - "op", - "start", - "length" - ], - "properties": { - "frame": { - "type": "integer" - }, - "op": { - "enum": [ - "play", - "delay", - "shift_phase", - "set_phase", - "shift_frequency", - "set_frequency", - "capture", - "barrier" - ] - }, - "start": { - "type": "integer" - }, - "length": { - "type": "integer" - }, - "line": { - "type": "integer" - }, - "waveform": { - "type": "integer" - }, - "phase": { - "type": "number" - }, - "frequency_hz": { - "type": "number" - }, - "carrier": { - "type": "number", - "description": "The carrier's phase at the play's first sample, cycles in [0, 1)." - }, - "value": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "calls": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "params": { - "type": "array", - "items": { - "type": "number" - } - }, - "start": { - "type": "integer" - }, - "end": { - "type": "integer" - }, - "line": { - "type": "integer" - } - } - } - }, - "bits": { - "type": "array", - "items": { - "type": "string" - } - }, - "qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "decimated": { - "type": "string" - }, - "diagnostics": { - "type": "array", - "items": { - "type": "object", - "description": "A reader's note or warning (qasm::diag).", - "properties": { - "code": { - "type": "string" - }, - "outcome": { - "type": "string" - }, - "message": { - "type": "string" - }, - "line": { - "type": "integer" - }, - "column": { - "type": "integer" - }, - "length": { - "type": "integer" - } - } - } - }, - "calibration": { - "type": "object", - "description": "What a pulse run's receipt binds of the program: the BLAKE3 of the control program's text, of its calibrations as written (every cal, defcal and defcalgrammar, joined by newlines), and of the schedule's JSON; a run adds the device's and the target snapshot's.", - "required": [ - "program", - "calibrations", - "schedule" - ], - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - } - } - }, - { - "type": "object", - "description": "A pulse job checked (pulse_check, wai-quantum pulse check, POST /v1/pulse/check): its receipt's signature, its program's digest, and the request run again with the result held to the one given.", - "required": [ - "answer", - "verified", - "signature", - "program", - "reproduced", - "differences", - "statement" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.pulse/1" - }, - "answer": { - "const": "check" - }, - "verified": { - "type": "boolean" - }, - "signature": { - "type": "boolean" - }, - "key": {}, - "program": { - "type": "boolean" - }, - "reproduced": { - "type": "boolean" - }, - "differences": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Each field (or field.member) whose value differs from the run here." - }, - "density_hash": { - "type": "object", - "properties": { - "given": {}, - "recomputed": {} - } - }, - "calibration": {}, - "statement": { - "type": "string" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "gradient_qasm", - "title": "The exact gradient of a Hamiltonian's expectation by a program's parameters", - "description": "The expectation E = ⟨ψ|H|ψ⟩ of a Hamiltonian at a program's parameters, and its gradient by each parameter, exactly: by adjoint differentiation or the parameter-shift rule on the double-precision state vector (at most 20 qubits, no noise, measurements only at the end). The reader follows each parameter into the gates, so an argument may be any expression of the built-in functions. The answer states its method, that it is f64 and approximate, and a bound on the rounding of the value and of each component (precision.rounding_bound). Sealed with this user's key. Quote the gradient with its bound.", - "inputSchema": { - "type": "object", - "required": [ - "qasm", - "params", - "hamiltonian" - ], - "properties": { - "qasm": { - "type": "string", - "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." - }, - "hamiltonian": { - "type": "array", - "minItems": 1, - "maxItems": 4096, - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "pauli" - ], - "properties": { - "pauli": { - "type": "string" - }, - "coeff": { - "type": "number" - } - } - } - ] - }, - "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ], - "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/gradient_qasm/1", - "type": "object", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.algorithms/1", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", - "required": [ - "call", - "value", - "gradient", - "params", - "method", - "how", - "evaluations", - "qubits", - "gates", - "moved_gates", - "parameters", - "terms", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "gradient" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "value": { - "type": "number", - "description": "⟨ψ|H|ψ⟩ at the params." - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "∂E/∂p for each parameter p, by name." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The point, by name." - }, - "method": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "how": { - "type": "string" - }, - "evaluations": { - "type": "integer", - "minimum": 0, - "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "moved_gates": { - "type": "integer", - "minimum": 0, - "description": "Gates a parameter moves." - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0, - "description": "The Hamiltonian's Pauli terms." - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "optimize" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - } - } - }, - { - "type": "object", - "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "reference" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "vqe" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "reference": { - "anyOf": [ - { - "type": "object", - "required": [ - "ground_energy", - "how", - "gap" - ], - "properties": { - "ground_energy": { - "type": "number" - }, - "first_excited": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "how": { - "type": "string" - }, - "gap": { - "type": "number", - "description": "The best energy found above the ground energy." - } - } - }, - { - "type": "object", - "required": [ - "unchecked" - ], - "properties": { - "unchecked": { - "type": "string" - } - } - } - ] - }, - "ansatz": { - "type": "object", - "required": [ - "qasm", - "params", - "kind" - ], - "properties": { - "qasm": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "kind": { - "const": "hardware_efficient" - } - } - } - } - }, - { - "type": "object", - "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "graph", - "layers", - "program", - "hamiltonian", - "maxcut" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "qaoa" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 0 - }, - "edges": { - "type": "array", - "items": { - "type": "array", - "minItems": 3, - "maxItems": 3 - } - } - } - }, - "layers": { - "type": "integer", - "minimum": 0 - }, - "program": { - "type": "string" - }, - "hamiltonian": { - "type": "array" - }, - "maxcut": { - "type": "object", - "required": [ - "max_cut", - "optimal", - "optimal_count", - "how", - "expected_cut", - "ratio", - "most_likely", - "p_optimal", - "bits" - ], - "properties": { - "max_cut": { - "type": "number" - }, - "optimal": { - "type": "array", - "items": { - "type": "string" - } - }, - "optimal_count": { - "type": "integer", - "minimum": 0 - }, - "how": { - "type": "string" - }, - "expected_cut": { - "type": "number" - }, - "ratio": { - "type": "number" - }, - "most_likely": { - "type": "object", - "required": [ - "bits", - "probability", - "cut", - "optimal" - ], - "properties": { - "bits": { - "type": "string" - }, - "probability": { - "type": "number" - }, - "cut": { - "type": "number" - }, - "optimal": { - "type": "boolean" - } - } - }, - "p_optimal": { - "type": "number" - }, - "bits": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", - "required": [ - "call", - "algorithm", - "qasm", - "qubits", - "gates", - "reads", - "expected", - "check" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "build" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "qasm": { - "type": "string" - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "reads": { - "type": "object", - "description": "How to read the program's result." - }, - "expected": { - "type": "object", - "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." - }, - "check": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "exact", - "random", - "none" - ] - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": "number" - }, - "reference": { - "type": "string" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "optimize_qasm", - "title": "Minimise a Hamiltonian's expectation over a program's parameters", - "description": "Minimise E = ⟨ψ|H|ψ⟩ over a program's parameters from the given params, deterministically: gradient descent with a fixed step, Adam, or SPSA from a seeded stream (at most 2000 steps). Every step's parameters and value (and gradient, or SPSA's perturbation and estimate) are listed, each step a link of a digest chain from the request, best and final given; the same request gives the same bytes on every platform. Sealed with this user's key: the receipt binds the program, every step, the method and the seed, and verify_quantum_result (or wai-quantum verify) re-runs it. A minimum found is a minimum along this path, not a proof of the global one.", - "inputSchema": { - "type": "object", - "required": [ - "qasm", - "params", - "hamiltonian" - ], - "properties": { - "qasm": { - "type": "string", - "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." - }, - "hamiltonian": { - "type": "array", - "minItems": 1, - "maxItems": 4096, - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "pauli" - ], - "properties": { - "pauli": { - "type": "string" - }, - "coeff": { - "type": "number" - } - } - } - ] - }, - "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." - }, - "optimizer": { - "anyOf": [ - { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - } - } - } - ], - "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." - }, - "steps": { - "type": "integer", - "minimum": 1, - "maximum": 2000, - "description": "Steps to take (default 100)." - }, - "step_size": { - "type": "number", - "exclusiveMinimum": 0, - "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ], - "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." - }, - "seed": { - "type": "integer", - "minimum": 0, - "description": "SPSA's seed (default 1)." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/optimize_qasm/1", - "type": "object", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.algorithms/1", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", - "required": [ - "call", - "value", - "gradient", - "params", - "method", - "how", - "evaluations", - "qubits", - "gates", - "moved_gates", - "parameters", - "terms", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "gradient" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "value": { - "type": "number", - "description": "⟨ψ|H|ψ⟩ at the params." - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "∂E/∂p for each parameter p, by name." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The point, by name." - }, - "method": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "how": { - "type": "string" - }, - "evaluations": { - "type": "integer", - "minimum": 0, - "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "moved_gates": { - "type": "integer", - "minimum": 0, - "description": "Gates a parameter moves." - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0, - "description": "The Hamiltonian's Pauli terms." - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "optimize" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - } - } - }, - { - "type": "object", - "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "reference" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "vqe" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "reference": { - "anyOf": [ - { - "type": "object", - "required": [ - "ground_energy", - "how", - "gap" - ], - "properties": { - "ground_energy": { - "type": "number" - }, - "first_excited": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "how": { - "type": "string" - }, - "gap": { - "type": "number", - "description": "The best energy found above the ground energy." - } - } - }, - { - "type": "object", - "required": [ - "unchecked" - ], - "properties": { - "unchecked": { - "type": "string" - } - } - } - ] - }, - "ansatz": { - "type": "object", - "required": [ - "qasm", - "params", - "kind" - ], - "properties": { - "qasm": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "kind": { - "const": "hardware_efficient" - } - } - } - } - }, - { - "type": "object", - "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "graph", - "layers", - "program", - "hamiltonian", - "maxcut" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "qaoa" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 0 - }, - "edges": { - "type": "array", - "items": { - "type": "array", - "minItems": 3, - "maxItems": 3 - } - } - } - }, - "layers": { - "type": "integer", - "minimum": 0 - }, - "program": { - "type": "string" - }, - "hamiltonian": { - "type": "array" - }, - "maxcut": { - "type": "object", - "required": [ - "max_cut", - "optimal", - "optimal_count", - "how", - "expected_cut", - "ratio", - "most_likely", - "p_optimal", - "bits" - ], - "properties": { - "max_cut": { - "type": "number" - }, - "optimal": { - "type": "array", - "items": { - "type": "string" - } - }, - "optimal_count": { - "type": "integer", - "minimum": 0 - }, - "how": { - "type": "string" - }, - "expected_cut": { - "type": "number" - }, - "ratio": { - "type": "number" - }, - "most_likely": { - "type": "object", - "required": [ - "bits", - "probability", - "cut", - "optimal" - ], - "properties": { - "bits": { - "type": "string" - }, - "probability": { - "type": "number" - }, - "cut": { - "type": "number" - }, - "optimal": { - "type": "boolean" - } - } - }, - "p_optimal": { - "type": "number" - }, - "bits": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", - "required": [ - "call", - "algorithm", - "qasm", - "qubits", - "gates", - "reads", - "expected", - "check" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "build" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "qasm": { - "type": "string" - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "reads": { - "type": "object", - "description": "How to read the program's result." - }, - "expected": { - "type": "object", - "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." - }, - "check": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "exact", - "random", - "none" - ] - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": "number" - }, - "reference": { - "type": "string" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "vqe_ground_state", - "title": "Find a Hamiltonian's ground energy by the variational eigensolver", - "description": "The variational eigensolver: an ansatz (the program given as qasm with params, or ansatz {\"layers\": L}: layers of ry and rz on every qubit and a ring of cx, its parameters t0, t1, … from 0.1) optimised on the Hamiltonian as optimize_qasm does. At most 8 qubits the answer sets the energy found beside the exact ground energy by diagonalisation (reference.ground_energy and gap); the energy found is never below it. Sealed with this user's key. Report the gap: an ansatz that cannot reach the ground state stops above it.", - "inputSchema": { - "type": "object", - "required": [ - "hamiltonian" - ], - "properties": { - "hamiltonian": { - "type": "array", - "minItems": 1, - "maxItems": 4096, - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "pauli" - ], - "properties": { - "pauli": { - "type": "string" - }, - "coeff": { - "type": "number" - } - } - } - ] - }, - "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." - }, - "qasm": { - "type": "string", - "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." - }, - "ansatz": { - "type": "object", - "properties": { - "layers": { - "type": "integer", - "minimum": 1, - "maximum": 16 - }, - "qubits": { - "type": "integer", - "minimum": 1, - "maximum": 20 - } - }, - "description": "The built-in ansatz in place of qasm (layers default 2, qubits the Hamiltonian's)." - }, - "optimizer": { - "anyOf": [ - { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - } - } - } - ], - "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." - }, - "steps": { - "type": "integer", - "minimum": 1, - "maximum": 2000, - "description": "Steps to take (default 100)." - }, - "step_size": { - "type": "number", - "exclusiveMinimum": 0, - "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ], - "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." - }, - "seed": { - "type": "integer", - "minimum": 0, - "description": "SPSA's seed (default 1)." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/vqe_ground_state/1", - "type": "object", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.algorithms/1", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", - "required": [ - "call", - "value", - "gradient", - "params", - "method", - "how", - "evaluations", - "qubits", - "gates", - "moved_gates", - "parameters", - "terms", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "gradient" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "value": { - "type": "number", - "description": "⟨ψ|H|ψ⟩ at the params." - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "∂E/∂p for each parameter p, by name." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The point, by name." - }, - "method": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "how": { - "type": "string" - }, - "evaluations": { - "type": "integer", - "minimum": 0, - "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "moved_gates": { - "type": "integer", - "minimum": 0, - "description": "Gates a parameter moves." - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0, - "description": "The Hamiltonian's Pauli terms." - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "optimize" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - } - } - }, - { - "type": "object", - "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "reference" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "vqe" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "reference": { - "anyOf": [ - { - "type": "object", - "required": [ - "ground_energy", - "how", - "gap" - ], - "properties": { - "ground_energy": { - "type": "number" - }, - "first_excited": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "how": { - "type": "string" - }, - "gap": { - "type": "number", - "description": "The best energy found above the ground energy." - } - } - }, - { - "type": "object", - "required": [ - "unchecked" - ], - "properties": { - "unchecked": { - "type": "string" - } - } - } - ] - }, - "ansatz": { - "type": "object", - "required": [ - "qasm", - "params", - "kind" - ], - "properties": { - "qasm": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "kind": { - "const": "hardware_efficient" - } - } - } - } - }, - { - "type": "object", - "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "graph", - "layers", - "program", - "hamiltonian", - "maxcut" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "qaoa" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 0 - }, - "edges": { - "type": "array", - "items": { - "type": "array", - "minItems": 3, - "maxItems": 3 - } - } - } - }, - "layers": { - "type": "integer", - "minimum": 0 - }, - "program": { - "type": "string" - }, - "hamiltonian": { - "type": "array" - }, - "maxcut": { - "type": "object", - "required": [ - "max_cut", - "optimal", - "optimal_count", - "how", - "expected_cut", - "ratio", - "most_likely", - "p_optimal", - "bits" - ], - "properties": { - "max_cut": { - "type": "number" - }, - "optimal": { - "type": "array", - "items": { - "type": "string" - } - }, - "optimal_count": { - "type": "integer", - "minimum": 0 - }, - "how": { - "type": "string" - }, - "expected_cut": { - "type": "number" - }, - "ratio": { - "type": "number" - }, - "most_likely": { - "type": "object", - "required": [ - "bits", - "probability", - "cut", - "optimal" - ], - "properties": { - "bits": { - "type": "string" - }, - "probability": { - "type": "number" - }, - "cut": { - "type": "number" - }, - "optimal": { - "type": "boolean" - } - } - }, - "p_optimal": { - "type": "number" - }, - "bits": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", - "required": [ - "call", - "algorithm", - "qasm", - "qubits", - "gates", - "reads", - "expected", - "check" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "build" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "qasm": { - "type": "string" - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "reads": { - "type": "object", - "description": "How to read the program's result." - }, - "expected": { - "type": "object", - "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." - }, - "check": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "exact", - "random", - "none" - ] - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": "number" - }, - "reference": { - "type": "string" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "qaoa_maxcut", - "title": "Solve Max-Cut on a graph by QAOA", - "description": "Max-Cut by the quantum approximate optimisation algorithm: the program (|+⟩ⁿ, then for each layer rzz(gamma·w) on every edge and rx(2·beta) on every qubit) and its cost Hamiltonian built from the graph (at most 20 vertices, 16 layers), optimised as optimize_qasm does from the params or a linear ramp, and read against the maximum cut found by brute force: the expected cut and its ratio to the maximum, the likeliest assignment and whether it is optimal, and the probability of an optimal one. Sealed with this user's key.", - "inputSchema": { - "type": "object", - "required": [ - "graph" - ], - "properties": { - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 2, - "maximum": 20 - }, - "edges": { - "type": "array", - "minItems": 1, - "maxItems": 400, - "items": { - "type": "array", - "minItems": 2, - "maxItems": 3, - "items": { - "type": "number" - } - }, - "description": "Each edge [i, j] or [i, j, weight]." - } - } - }, - "layers": { - "type": "integer", - "minimum": 1, - "maximum": 16, - "description": "QAOA's p (default 1)." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "gamma_0, beta_0, … to start from." - }, - "optimizer": { - "anyOf": [ - { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - } - } - } - ], - "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." - }, - "steps": { - "type": "integer", - "minimum": 1, - "maximum": 2000, - "description": "Steps to take (default 100)." - }, - "step_size": { - "type": "number", - "exclusiveMinimum": 0, - "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ], - "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." - }, - "seed": { - "type": "integer", - "minimum": 0, - "description": "SPSA's seed (default 1)." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/qaoa_maxcut/1", - "type": "object", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.algorithms/1", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", - "required": [ - "call", - "value", - "gradient", - "params", - "method", - "how", - "evaluations", - "qubits", - "gates", - "moved_gates", - "parameters", - "terms", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "gradient" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "value": { - "type": "number", - "description": "⟨ψ|H|ψ⟩ at the params." - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "∂E/∂p for each parameter p, by name." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The point, by name." - }, - "method": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "how": { - "type": "string" - }, - "evaluations": { - "type": "integer", - "minimum": 0, - "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "moved_gates": { - "type": "integer", - "minimum": 0, - "description": "Gates a parameter moves." - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0, - "description": "The Hamiltonian's Pauli terms." - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "optimize" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - } - } - }, - { - "type": "object", - "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "reference" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "vqe" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "reference": { - "anyOf": [ - { - "type": "object", - "required": [ - "ground_energy", - "how", - "gap" - ], - "properties": { - "ground_energy": { - "type": "number" - }, - "first_excited": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "how": { - "type": "string" - }, - "gap": { - "type": "number", - "description": "The best energy found above the ground energy." - } - } - }, - { - "type": "object", - "required": [ - "unchecked" - ], - "properties": { - "unchecked": { - "type": "string" - } - } - } - ] - }, - "ansatz": { - "type": "object", - "required": [ - "qasm", - "params", - "kind" - ], - "properties": { - "qasm": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "kind": { - "const": "hardware_efficient" - } - } - } - } - }, - { - "type": "object", - "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "graph", - "layers", - "program", - "hamiltonian", - "maxcut" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "qaoa" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 0 - }, - "edges": { - "type": "array", - "items": { - "type": "array", - "minItems": 3, - "maxItems": 3 - } - } - } - }, - "layers": { - "type": "integer", - "minimum": 0 - }, - "program": { - "type": "string" - }, - "hamiltonian": { - "type": "array" - }, - "maxcut": { - "type": "object", - "required": [ - "max_cut", - "optimal", - "optimal_count", - "how", - "expected_cut", - "ratio", - "most_likely", - "p_optimal", - "bits" - ], - "properties": { - "max_cut": { - "type": "number" - }, - "optimal": { - "type": "array", - "items": { - "type": "string" - } - }, - "optimal_count": { - "type": "integer", - "minimum": 0 - }, - "how": { - "type": "string" - }, - "expected_cut": { - "type": "number" - }, - "ratio": { - "type": "number" - }, - "most_likely": { - "type": "object", - "required": [ - "bits", - "probability", - "cut", - "optimal" - ], - "properties": { - "bits": { - "type": "string" - }, - "probability": { - "type": "number" - }, - "cut": { - "type": "number" - }, - "optimal": { - "type": "boolean" - } - } - }, - "p_optimal": { - "type": "number" - }, - "bits": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", - "required": [ - "call", - "algorithm", - "qasm", - "qubits", - "gates", - "reads", - "expected", - "check" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "build" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "qasm": { - "type": "string" - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "reads": { - "type": "object", - "description": "How to read the program's result." - }, - "expected": { - "type": "object", - "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." - }, - "check": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "exact", - "random", - "none" - ] - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": "number" - }, - "reference": { - "type": "string" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "build_algorithm", - "title": "Write the program for a standard algorithm, checked against its reference", - "description": "An OpenQASM 3 program for a standard algorithm, with how to read its result, what it gives, and the equivalence ladder's verdict on it against a reference matrix or truth table built from the definitions (check: exact on every basis state up to 8 qubits, the adder's up to 16; past that unchecked). qpe: the phase φ of p(2πφ) on counting qubits; amplitude_estimation: the amplitude a that A = ry(2·arcsin √a) gives the good state, by phase estimation of the Grover operator; adder: the ripple-carry adder of bits-bit integers in place (with a and b, prepared and measured); qsvt: quantum signal processing from phases, of a signal x or of a real symmetric 2 × 2 matrix through its block encoding (all phases zero give the Chebyshev polynomial). Sealed with this user's key. Run the program with run_quantum_circuit.", - "inputSchema": { - "type": "object", - "required": [ - "algorithm" - ], - "properties": { - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "counting": { - "type": "integer", - "minimum": 1, - "maximum": 20, - "description": "qpe, amplitude_estimation: counting qubits (default 4)." - }, - "phase": { - "type": "number", - "description": "qpe: the phase φ, in turns." - }, - "amplitude": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "amplitude_estimation: the good state's probability a." - }, - "bits": { - "type": "integer", - "minimum": 1, - "maximum": 32, - "description": "adder: the integers' width." - }, - "a": { - "type": "integer", - "minimum": 0, - "description": "adder: the first addend, prepared." - }, - "b": { - "type": "integer", - "minimum": 0, - "description": "adder: the second, which the sum replaces." - }, - "carry_in": { - "type": "boolean", - "description": "adder: a carry in." - }, - "phases": { - "type": "array", - "minItems": 2, - "maxItems": 64, - "items": { - "type": "number" - }, - "description": "qsvt: φ₀ … φ_d, radians." - }, - "x": { - "type": "number", - "minimum": -1, - "maximum": 1, - "description": "qsvt: the signal." - }, - "matrix": { - "type": "array", - "description": "qsvt: [[a, b], [b, c]], real and symmetric, its eigenvalues within [-1, 1]." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/build_algorithm/1", - "type": "object", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.algorithms/1", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", - "required": [ - "call", - "value", - "gradient", - "params", - "method", - "how", - "evaluations", - "qubits", - "gates", - "moved_gates", - "parameters", - "terms", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "gradient" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "value": { - "type": "number", - "description": "⟨ψ|H|ψ⟩ at the params." - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "∂E/∂p for each parameter p, by name." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The point, by name." - }, - "method": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "how": { - "type": "string" - }, - "evaluations": { - "type": "integer", - "minimum": 0, - "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "moved_gates": { - "type": "integer", - "minimum": 0, - "description": "Gates a parameter moves." - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0, - "description": "The Hamiltonian's Pauli terms." - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "optimize" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - } - } - }, - { - "type": "object", - "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "reference" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "vqe" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "reference": { - "anyOf": [ - { - "type": "object", - "required": [ - "ground_energy", - "how", - "gap" - ], - "properties": { - "ground_energy": { - "type": "number" - }, - "first_excited": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "how": { - "type": "string" - }, - "gap": { - "type": "number", - "description": "The best energy found above the ground energy." - } - } - }, - { - "type": "object", - "required": [ - "unchecked" - ], - "properties": { - "unchecked": { - "type": "string" - } - } - } - ] - }, - "ansatz": { - "type": "object", - "required": [ - "qasm", - "params", - "kind" - ], - "properties": { - "qasm": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "kind": { - "const": "hardware_efficient" - } - } - } - } - }, - { - "type": "object", - "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "graph", - "layers", - "program", - "hamiltonian", - "maxcut" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "qaoa" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 0 - }, - "edges": { - "type": "array", - "items": { - "type": "array", - "minItems": 3, - "maxItems": 3 - } - } - } - }, - "layers": { - "type": "integer", - "minimum": 0 - }, - "program": { - "type": "string" - }, - "hamiltonian": { - "type": "array" - }, - "maxcut": { - "type": "object", - "required": [ - "max_cut", - "optimal", - "optimal_count", - "how", - "expected_cut", - "ratio", - "most_likely", - "p_optimal", - "bits" - ], - "properties": { - "max_cut": { - "type": "number" - }, - "optimal": { - "type": "array", - "items": { - "type": "string" - } - }, - "optimal_count": { - "type": "integer", - "minimum": 0 - }, - "how": { - "type": "string" - }, - "expected_cut": { - "type": "number" - }, - "ratio": { - "type": "number" - }, - "most_likely": { - "type": "object", - "required": [ - "bits", - "probability", - "cut", - "optimal" - ], - "properties": { - "bits": { - "type": "string" - }, - "probability": { - "type": "number" - }, - "cut": { - "type": "number" - }, - "optimal": { - "type": "boolean" - } - } - }, - "p_optimal": { - "type": "number" - }, - "bits": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", - "required": [ - "call", - "algorithm", - "qasm", - "qubits", - "gates", - "reads", - "expected", - "check" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "build" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "qasm": { - "type": "string" - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "reads": { - "type": "object", - "description": "How to read the program's result." - }, - "expected": { - "type": "object", - "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." - }, - "check": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "exact", - "random", - "none" - ] - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": "number" - }, - "reference": { - "type": "string" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, { "name": "providers_list", "title": "List the person's quantum providers", @@ -47577,11 +35416,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -47589,30 +35423,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -47627,7 +35437,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -48175,13 +35985,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -48206,121 +36009,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -48443,23 +36131,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -48519,7 +36208,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -48581,6 +36274,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -50344,237 +38046,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -50828,11 +38299,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -50840,30 +38306,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -50878,7 +38320,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -51426,13 +38868,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -51457,121 +38892,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -51692,23 +39012,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -51768,7 +39089,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -51830,6 +39155,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -53593,237 +40927,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, diff --git a/wai/wai-quantum-cli/docs/service-mcp.json b/wai/wai-quantum-cli/docs/service-mcp.json index 25b4b26f9..5bf5f1565 100644 --- a/wai/wai-quantum-cli/docs/service-mcp.json +++ b/wai/wai-quantum-cli/docs/service-mcp.json @@ -7,17 +7,8 @@ "description": "Run an OpenQASM program and return measurement counts, Pauli expectation values and/or amplitudes. The service chooses the method (bit-exact or double-precision state vector up to 32 qubits, single precision on a GPU to 33, stabilizer tableau for Clifford circuits up to 32768 qubits, matrix product states up to 4096, sparse Pauli dynamics for expectation values up to 1024 with an error bound, an exact density matrix or trajectories for noise), reports why and how accurate, and signs the result. Give `intent` (an exact distribution, or a reference program it must equal or whose state it must prepare) and the engine checks it with the run. Every answer carries `verdict`: the level the engine checked to (proof, evidence, executed, parsed, refused), whether the intent holds and a plain statement, sealed in the receipt. Waits up to 50 s; a longer job answers with status running and an id for get_quantum_job.", "inputSchema": { "type": "object", - "anyOf": [ - { - "required": [ - "qasm" - ] - }, - { - "required": [ - "source" - ] - } + "required": [ + "qasm" ], "properties": { "qasm": { @@ -78,11 +69,11 @@ "tensor_network", "cutrank", "cutrank_single", + "stabilizer_rank", "density_matrix", - "trajectories", - "pulse" + "trajectories" ], - "description": "Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." + "description": "Leave as auto unless you need a particular method." }, "seed": { "type": "integer", @@ -380,154 +371,6 @@ } } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } - }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", - "properties": { - "format": { - "type": "string", - "enum": [ - "qasm", - "qir", - "jeff" - ], - "description": "Its format." - }, - "program": { - "type": "string", - "description": "The program's text: QIR (LLVM text) or OpenQASM." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64: jeff." - } - } - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes." } } }, @@ -607,11 +450,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -619,30 +457,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -657,7 +471,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -1205,13 +1019,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -1236,121 +1043,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -1473,23 +1165,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -1549,7 +1242,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -1611,6 +1308,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -3374,237 +3080,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -3858,11 +3333,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -3870,30 +3340,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -3908,7 +3354,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -4456,13 +3902,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -4487,121 +3926,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -4722,23 +4046,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -4798,7 +4123,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -4860,6 +4189,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -6623,237 +5961,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -9125,11 +8232,11 @@ "tensor_network", "cutrank", "cutrank_single", + "stabilizer_rank", "density_matrix", - "trajectories", - "pulse" + "trajectories" ], - "description": "Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." + "description": "Leave as auto unless you need a particular method." }, "seed": { "type": "integer", @@ -9428,128 +8535,6 @@ } ] }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes." - }, "programs": { "type": "array", "minItems": 1, @@ -9658,11 +8643,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -9670,30 +8650,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -9708,7 +8664,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -10256,13 +9212,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -10287,121 +9236,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -10524,23 +9358,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -10600,7 +9435,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -10662,6 +9501,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -12425,237 +11273,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -12909,11 +11526,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -12921,30 +11533,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -12959,7 +11547,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -13507,13 +12095,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -13538,121 +12119,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -13773,23 +12239,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -13849,7 +12316,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -13911,6 +12382,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -15674,237 +14154,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -18176,11 +16425,11 @@ "tensor_network", "cutrank", "cutrank_single", + "stabilizer_rank", "density_matrix", - "trajectories", - "pulse" + "trajectories" ], - "description": "Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." + "description": "Leave as auto unless you need a particular method." }, "seed": { "type": "integer", @@ -18479,128 +16728,6 @@ } ] }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes." - }, "programs": { "type": "array", "minItems": 1, @@ -18630,32 +16757,6 @@ } }, "description": "Each input of qasm and its values: every combination runs, the names in sorted order, the first varying slowest; an integer input's values are whole numbers." - }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", - "properties": { - "format": { - "type": "string", - "enum": [ - "qasm", - "qir", - "jeff" - ], - "description": "Its format." - }, - "program": { - "type": "string", - "description": "The program's text: QIR (LLVM text) or OpenQASM." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64: jeff." - } - } } } }, @@ -19739,11 +17840,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -19751,30 +17847,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -19789,7 +17861,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -20337,13 +18409,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -20368,121 +18433,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -20605,23 +18555,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -20681,7 +18632,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -20743,6 +18698,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -22506,237 +20470,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -22990,11 +20723,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -23002,30 +20730,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -23040,7 +20744,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -23588,13 +21292,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -23619,121 +21316,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -23854,23 +21436,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -23930,7 +21513,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -23992,6 +21579,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -25755,237 +23351,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -31388,324 +28753,6 @@ ] } }, - { - "name": "convert_program", - "title": "Convert a program between formats", - "description": "Carry a program between OpenQASM 3, QIR (LLVM text, read under its base and adaptive profiles, written as QIR 2.0) and jeff (its Cap'n Proto message, as base64). The answer is the program written, the program as OpenQASM 3 (what every other tool takes), each note with its code (a rotation at an arbitrary angle, a custom gate read by its name, what a format leaves out), what was read and written, and the check: the output read back and held to the program by the equivalence ladder. A construct a reader cannot hold exactly is refused with its code (Q700 to Q721) and its place: quote the code, and never guess around it. A conversion larger than the service takes is refused with the command that runs it locally.", - "inputSchema": { - "type": "object", - "required": [ - "to" - ], - "properties": { - "program": { - "type": "string", - "description": "The program's text: OpenQASM or QIR." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64: jeff." - }, - "from": { - "type": "string", - "enum": [ - "qasm", - "qir", - "jeff" - ], - "description": "Its format; found from its bytes when not given." - }, - "to": { - "type": "string", - "enum": [ - "qasm", - "qir", - "jeff" - ], - "description": "The format to write." - }, - "profile": { - "type": "string", - "enum": [ - "base", - "adaptive" - ], - "description": "QIR's profile to write: by default base when the program's measurements all come at the end, else adaptive." - }, - "check": { - "type": "boolean", - "description": "false: write it without the check." - } - } - }, - "annotations": { - "readOnlyHint": true - }, - "outputSchema": { - "$id": "wai-quantum://schemas/convert_program/1", - "type": "object", - "description": "What convert_program answers.", - "anyOf": [ - { - "anyOf": [ - { - "type": "object", - "description": "A program carried from one format to another (OpenQASM 3, QIR as LLVM text, jeff as its Cap'n Proto message) and checked (engine::formats::convert_json): the program written, the program as read in OpenQASM 3, the readers' and writer's notes with their codes, what was read and written, and the check that holds the output to the input.", - "required": [ - "ok", - "format", - "from", - "to", - "qasm", - "notes", - "read", - "written", - "check" - ], - "properties": { - "ok": { - "const": true - }, - "format": { - "const": "wai.quantum.convert/1" - }, - "from": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "to": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program written, for a text format (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program written, for a binary format (jeff), as standard base64." - }, - "qasm": { - "type": "string", - "description": "The program as read, as OpenQASM 3: what every other tool takes." - }, - "notes": { - "type": "array", - "items": { - "type": "object", - "description": "One of the reader's diagnostics: its code, what happens to the construct it is about, its message (without the line or the code), and where it stands.", - "required": [ - "code", - "outcome", - "message" - ], - "properties": { - "code": { - "type": "string" - }, - "outcome": { - "enum": [ - "refused", - "lowered", - "carried", - "preserved", - "warned" - ] - }, - "message": { - "type": "string" - }, - "line": { - "type": "integer", - "minimum": 1 - }, - "column": { - "type": "integer", - "minimum": 1 - }, - "length": { - "type": "integer", - "minimum": 0 - } - } - }, - "description": "Each warning and note, with its code (Q7xx for the formats) and, for QIR, its line." - }, - "read": { - "type": "object", - "required": [ - "format" - ], - "description": "What was read: the format, its version, a QIR module's profile, entry point, qubits, results and declared capabilities, a jeff module's tool, entry point, qubits and bits." - }, - "written": { - "type": "object", - "required": [ - "format" - ], - "description": "What was written: the format, its version, and QIR's profile." - }, - "check": { - "anyOf": [ - { - "type": "null" - }, - { - "type": "object", - "required": [ - "what", - "verdict" - ], - "properties": { - "what": { - "type": "string", - "description": "What was held to what." - }, - "verdict": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "tableau", - "exact", - "rewrites", - "random", - "state", - "shape", - "steps", - "distribution", - "identity", - "none" - ], - "description": "The equivalence ladder's check (tableau, exact and rewrites are proofs; random is evidence); steps: the same steps one for one; distribution: every outcome's probability the same (evidence); identity: OpenQASM passed through; none: unchecked." - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": [ - "number", - "null" - ] - } - } - } - } - } - ], - "description": "The output read back and held to the program read (or, for a program read into OpenQASM, written back to its format and read again), or null when no check was asked." - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, { "name": "improve_qasm", "title": "Improve a quantum program", @@ -40094,20 +37141,9 @@ "inputSchema": { "type": "object", "required": [ + "qasm", "target" ], - "anyOf": [ - { - "required": [ - "qasm" - ] - }, - { - "required": [ - "source" - ] - } - ], "properties": { "qasm": { "type": "string", @@ -40154,12 +37190,85 @@ } } }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes." + "mitigate": { + "description": "Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object.", + "anyOf": [ + { + "type": "string", + "enum": [ + "zne", + "pea", + "pec", + "cdr", + "vd", + "readout" + ] + }, + { + "type": "object", + "required": [ + "method" + ], + "properties": { + "method": { + "type": "string", + "enum": [ + "zne", + "pea", + "pec", + "cdr", + "vd", + "readout" + ] + }, + "shots": { + "type": "integer", + "minimum": 1, + "maximum": 1000000, + "description": "Shots per circuit (default 10000; 2000 per sampled circuit for pec)." + }, + "seed": { + "type": "integer", + "minimum": 0 + }, + "factors": { + "type": "array", + "items": { + "type": "number" + }, + "description": "zne: odd whole numbers (default 1, 3, 5); pea: factors from 1 to 10 (default 1, 1.5, 2)." + }, + "extrapolation": { + "type": "string", + "enum": [ + "richardson", + "linear", + "exponential" + ] + }, + "samples": { + "type": "integer", + "minimum": 2, + "description": "pec: sampled circuits (default 200)." + }, + "training": { + "type": "integer", + "minimum": 3, + "description": "cdr: training circuits (default 16)." + }, + "keep": { + "type": "integer", + "minimum": 0, + "description": "cdr: non-Clifford gates each training circuit keeps (default 2, and always one fewer than the program has)." + }, + "learn_shots": { + "type": "integer", + "minimum": 100, + "description": "pea, pec: shots per depth of the cycle benchmarking that learns the noise (default 60000)." + } + } + } + ] }, "seed": { "type": "integer", @@ -40377,227 +37486,6 @@ }, "repair": { "description": "Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {\"max_iterations\": N, \"dyadic_bits\": K, \"sizes\": {\"q\": 3}}. The result's `repaired` holds the program that ran and each repair." - }, - "mitigate": { - "description": "Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object.", - "anyOf": [ - { - "type": "string", - "enum": [ - "zne", - "pea", - "pec", - "cdr", - "vd", - "readout" - ] - }, - { - "type": "object", - "required": [ - "method" - ], - "properties": { - "method": { - "type": "string", - "enum": [ - "zne", - "pea", - "pec", - "cdr", - "vd", - "readout" - ] - }, - "shots": { - "type": "integer", - "minimum": 1, - "maximum": 1000000, - "description": "Shots per circuit (default 10000; 2000 per sampled circuit for pec)." - }, - "seed": { - "type": "integer", - "minimum": 0 - }, - "factors": { - "type": "array", - "items": { - "type": "number" - }, - "description": "zne: odd whole numbers (default 1, 3, 5); pea: factors from 1 to 10 (default 1, 1.5, 2)." - }, - "extrapolation": { - "type": "string", - "enum": [ - "richardson", - "linear", - "exponential" - ] - }, - "samples": { - "type": "integer", - "minimum": 2, - "description": "pec: sampled circuits (default 200)." - }, - "training": { - "type": "integer", - "minimum": 3, - "description": "cdr: training circuits (default 16)." - }, - "keep": { - "type": "integer", - "minimum": 0, - "description": "cdr: non-Clifford gates each training circuit keeps (default 2, and always one fewer than the program has)." - }, - "learn_shots": { - "type": "integer", - "minimum": 100, - "description": "pea, pec: shots per depth of the cycle benchmarking that learns the noise (default 60000)." - } - } - } - ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } - }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", - "properties": { - "format": { - "type": "string", - "enum": [ - "qasm", - "qir", - "jeff" - ], - "description": "Its format." - }, - "program": { - "type": "string", - "description": "The program's text: QIR (LLVM text) or OpenQASM." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64: jeff." - } - } } } }, @@ -40677,11 +37565,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -40689,30 +37572,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -40727,7 +37586,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -41275,13 +38134,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -41306,121 +38158,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -41543,23 +38280,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -41619,7 +38357,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -41681,6 +38423,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -43444,237 +40195,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -43928,11 +40448,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -43940,30 +40455,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -43978,7 +40469,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -44526,13 +41017,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -44557,121 +41041,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } }, @@ -44792,23 +41161,24 @@ "batch": { "type": "integer" }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "minimum": 0, + "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." }, - "truncation_bound": { + "confidence": { "type": "number", - "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." - }, - "rounding_estimate": { - "type": "number", - "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." - }, - "tolerance": { - "type": "number" - }, - "norm": { - "type": "string" + "description": "The probability a stated bound holds." } } }, @@ -44868,7 +41238,11 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." }, "peak_terms": { "type": "integer" @@ -44930,6 +41304,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } } @@ -46693,237 +43076,6 @@ } } } - }, - "pulse": { - "type": "object", - "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", - "required": [ - "read", - "outcome_bits", - "populations", - "simulated_qubits", - "density_hash", - "integrator", - "device", - "calibration" - ], - "properties": { - "read": { - "type": "string", - "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." - }, - "outcome_bits": { - "type": "array", - "items": { - "type": "string" - }, - "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." - }, - "distribution": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "number" - }, - "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." - }, - "populations": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." - }, - "simulated_qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "captures": { - "type": "array", - "items": { - "type": "object", - "properties": { - "frame": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "start": { - "type": "integer" - }, - "start_ns": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - }, - "p1": { - "type": "number" - }, - "p2": { - "type": "number" - } - } - } - }, - "leakage": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "p2": { - "type": "number" - } - } - }, - "description": "With three levels: each qubit's final probability of level 2." - }, - "trace": { - "type": "number" - }, - "density_hash": { - "type": "string", - "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." - }, - "duration": { - "type": "integer" - }, - "duration_ns": { - "type": "number" - }, - "integrator": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "order": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "substeps": { - "type": "integer" - }, - "step_ns": { - "type": "number" - }, - "steps": { - "type": "integer" - }, - "norm_max": { - "type": "number" - }, - "frame": { - "type": "string" - } - } - }, - "device": { - "type": "object", - "properties": { - "levels": { - "type": "integer" - }, - "dt_ns": { - "type": "number" - }, - "qubits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "qubit": { - "type": "integer" - }, - "frequency_hz": { - "type": "number" - }, - "rabi_hz": { - "type": "number" - }, - "anharmonicity_hz": { - "type": "number" - }, - "t1_ns": { - "type": "number" - }, - "t2_ns": { - "type": "number" - }, - "from": { - "type": "object", - "additionalProperties": { - "enum": [ - "pulse", - "target", - "default", - "none" - ] - } - } - } - } - }, - "couplings": { - "type": "array" - }, - "model": { - "type": "string" - } - } - }, - "calibration": { - "type": "object", - "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "not_modelled": { - "type": "array", - "items": { - "type": "string" - } - } - } } } }, @@ -47359,11 +43511,6 @@ "required": [ "programs" ] - }, - { - "required": [ - "source" - ] } ], "properties": { @@ -47371,30 +43518,6 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, - "source": { - "type": "object", - "required": [ - "format" - ], - "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", - "properties": { - "format": { - "enum": [ - "qasm", - "qir", - "jeff" - ] - }, - "program": { - "type": "string", - "description": "The program's text (OpenQASM, QIR)." - }, - "program_base64": { - "type": "string", - "description": "The program's bytes as base64 (jeff)." - } - } - }, "shots": { "type": "integer", "minimum": 0, @@ -47409,7 +43532,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." }, "observables": { "type": "array", @@ -47957,13 +44080,6 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." - }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -47988,121 +44104,6 @@ ] } ] - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } } } } @@ -50294,9912 +46295,6 @@ } ] } - }, - { - "name": "pulse_schedule", - "title": "Read a pulse program into its schedule", - "description": "Read a pulse program (OpenPulse calibrations: ports, frames, waveforms, play, delay, shift_phase, set_phase, shift_frequency, set_frequency, captures and barriers) into its schedule on frames: every instruction at its sample, each waveform's samples (gaussian, drag, gaussian_square, constant, sech, sine, or explicit), each gate call with the samples its calibration spans, and the digests a pulse run's receipt binds (the program, its calibrations, the schedule). Durations are whole samples of dt (pulse.dt_ns, default 0.5 ns) or refused. A construct the reader does not take is refused with a Q code and its line. Sealed with the service's key. To run it, give the program to run_quantum_circuit with method \"pulse\".", - "inputSchema": { - "type": "object", - "required": [ - "qasm" - ], - "properties": { - "qasm": { - "type": "string", - "description": "A pulse program: OpenQASM 3 with `defcalgrammar \"openpulse\";`, `cal` blocks declaring ports (d0 drives qubit 0, m0 is its measurement port, a0 its acquisition port), frames (newframe(port, frequency Hz, phase)) and waveforms, a `defcal` for every gate it calls on physical qubits ($0), and the calls." - }, - "pulse": { - "type": "object", - "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", - "additionalProperties": false, - "properties": { - "dt_ns": { - "type": "number", - "exclusiveMinimum": 0, - "maximum": 1000, - "description": "The sample period, ns (default 0.5)." - }, - "levels": { - "type": "integer", - "enum": [ - 2, - 3 - ], - "description": "Levels kept per qubit (default 2; 3 shows leakage)." - }, - "tolerance": { - "type": "number", - "exclusiveMinimum": 0, - "exclusiveMaximum": 1, - "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." - }, - "substeps": { - "type": "integer", - "minimum": 1, - "maximum": 4096, - "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." - }, - "qubits": { - "type": "object", - "description": "Each qubit's parameters by its index, over the target's and the defaults.", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "frequency_ghz": { - "type": "number", - "description": "Its frequency, GHz." - }, - "rabi_mhz": { - "type": "number", - "description": "Its Rabi frequency at full amplitude, MHz." - }, - "anharmonicity_mhz": { - "type": "number", - "description": "Its anharmonicity, MHz." - }, - "t1_us": { - "type": "number", - "description": "Its relaxation time, µs." - }, - "t2_us": { - "type": "number", - "description": "Its coherence time, µs (at most 2·T1)." - } - } - } - }, - "couplings": { - "type": "array", - "description": "Static ZZ couplings.", - "items": { - "type": "object", - "required": [ - "qubits", - "zz_khz" - ], - "additionalProperties": false, - "properties": { - "qubits": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0 - }, - "minItems": 2, - "maxItems": 2 - }, - "zz_khz": { - "type": "number", - "description": "The coupling's rate, kHz." - } - } - } - }, - "ports": { - "type": "object", - "description": "Ports by name: what each is for and the qubit it reaches.", - "additionalProperties": { - "type": "object", - "required": [ - "kind", - "qubit" - ], - "additionalProperties": false, - "properties": { - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer", - "minimum": 0 - } - } - } - } - } - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/pulse_schedule/1", - "type": "object", - "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.pulse/1", - "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A schedule or a check, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A pulse program's schedule (pulse_schedule, wai-quantum pulse schedule, POST /v1/pulse/schedule): its frames and ports, every instruction at its sample, each waveform's samples, the gate calls, the reader's notes, and the digests a run binds.", - "required": [ - "answer", - "dt_ns", - "duration", - "frames", - "waveforms", - "instructions", - "calls", - "calibration" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.pulse/1" - }, - "answer": { - "const": "schedule" - }, - "dt_ns": { - "type": "number", - "description": "The sample period, ns." - }, - "duration": { - "type": "integer", - "description": "The latest time of any frame, samples." - }, - "duration_ns": { - "type": "number" - }, - "grammar": { - "type": [ - "string", - "null" - ] - }, - "ports": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer" - } - } - } - }, - "frames": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "frequency_hz": { - "type": "number" - }, - "phase": { - "type": "number" - } - } - } - }, - "waveforms": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "length": { - "type": "integer" - }, - "samples": { - "type": "array", - "items": { - "type": "array", - "items": { - "type": "number" - }, - "minItems": 2, - "maxItems": 2 - } - }, - "samples_every": { - "type": "integer", - "description": "Each k-th sample is drawn, when the schedule holds more than the view writes out." - } - } - } - }, - "instructions": { - "type": "array", - "items": { - "type": "object", - "required": [ - "frame", - "op", - "start", - "length" - ], - "properties": { - "frame": { - "type": "integer" - }, - "op": { - "enum": [ - "play", - "delay", - "shift_phase", - "set_phase", - "shift_frequency", - "set_frequency", - "capture", - "barrier" - ] - }, - "start": { - "type": "integer" - }, - "length": { - "type": "integer" - }, - "line": { - "type": "integer" - }, - "waveform": { - "type": "integer" - }, - "phase": { - "type": "number" - }, - "frequency_hz": { - "type": "number" - }, - "carrier": { - "type": "number", - "description": "The carrier's phase at the play's first sample, cycles in [0, 1)." - }, - "value": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "calls": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "params": { - "type": "array", - "items": { - "type": "number" - } - }, - "start": { - "type": "integer" - }, - "end": { - "type": "integer" - }, - "line": { - "type": "integer" - } - } - } - }, - "bits": { - "type": "array", - "items": { - "type": "string" - } - }, - "qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "decimated": { - "type": "string" - }, - "diagnostics": { - "type": "array", - "items": { - "type": "object", - "description": "A reader's note or warning (qasm::diag).", - "properties": { - "code": { - "type": "string" - }, - "outcome": { - "type": "string" - }, - "message": { - "type": "string" - }, - "line": { - "type": "integer" - }, - "column": { - "type": "integer" - }, - "length": { - "type": "integer" - } - } - } - }, - "calibration": { - "type": "object", - "description": "What a pulse run's receipt binds of the program: the BLAKE3 of the control program's text, of its calibrations as written (every cal, defcal and defcalgrammar, joined by newlines), and of the schedule's JSON; a run adds the device's and the target snapshot's.", - "required": [ - "program", - "calibrations", - "schedule" - ], - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - } - } - }, - { - "type": "object", - "description": "A pulse job checked (pulse_check, wai-quantum pulse check, POST /v1/pulse/check): its receipt's signature, its program's digest, and the request run again with the result held to the one given.", - "required": [ - "answer", - "verified", - "signature", - "program", - "reproduced", - "differences", - "statement" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.pulse/1" - }, - "answer": { - "const": "check" - }, - "verified": { - "type": "boolean" - }, - "signature": { - "type": "boolean" - }, - "key": {}, - "program": { - "type": "boolean" - }, - "reproduced": { - "type": "boolean" - }, - "differences": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Each field (or field.member) whose value differs from the run here." - }, - "density_hash": { - "type": "object", - "properties": { - "given": {}, - "recomputed": {} - } - }, - "calibration": {}, - "statement": { - "type": "string" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "pulse_check", - "title": "Check a pulse run by running it again", - "description": "Check a pulse job as a host returned it ({\"request\", \"result\"}, the result with its receipt): the receipt's signature, the program's digest against the request's text, and the request run again here with the result held to the one given field by field (the density matrix's digest among them), each difference named. A pulse run is the same bits on every platform, so a result that does not reproduce was not made from that request by this engine. Sealed with the service's key. Quote `verified` and the statement.", - "inputSchema": { - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The pulse job's request." - }, - "result": { - "type": "object", - "description": "Its result, with its receipt." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/pulse_check/1", - "type": "object", - "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.pulse/1", - "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A schedule or a check, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A pulse program's schedule (pulse_schedule, wai-quantum pulse schedule, POST /v1/pulse/schedule): its frames and ports, every instruction at its sample, each waveform's samples, the gate calls, the reader's notes, and the digests a run binds.", - "required": [ - "answer", - "dt_ns", - "duration", - "frames", - "waveforms", - "instructions", - "calls", - "calibration" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.pulse/1" - }, - "answer": { - "const": "schedule" - }, - "dt_ns": { - "type": "number", - "description": "The sample period, ns." - }, - "duration": { - "type": "integer", - "description": "The latest time of any frame, samples." - }, - "duration_ns": { - "type": "number" - }, - "grammar": { - "type": [ - "string", - "null" - ] - }, - "ports": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "qubit": { - "type": "integer" - } - } - } - }, - "frames": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "string" - }, - "qubit": { - "type": "integer" - }, - "kind": { - "enum": [ - "drive", - "measure", - "acquire" - ] - }, - "frequency_hz": { - "type": "number" - }, - "phase": { - "type": "number" - } - } - } - }, - "waveforms": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "length": { - "type": "integer" - }, - "samples": { - "type": "array", - "items": { - "type": "array", - "items": { - "type": "number" - }, - "minItems": 2, - "maxItems": 2 - } - }, - "samples_every": { - "type": "integer", - "description": "Each k-th sample is drawn, when the schedule holds more than the view writes out." - } - } - } - }, - "instructions": { - "type": "array", - "items": { - "type": "object", - "required": [ - "frame", - "op", - "start", - "length" - ], - "properties": { - "frame": { - "type": "integer" - }, - "op": { - "enum": [ - "play", - "delay", - "shift_phase", - "set_phase", - "shift_frequency", - "set_frequency", - "capture", - "barrier" - ] - }, - "start": { - "type": "integer" - }, - "length": { - "type": "integer" - }, - "line": { - "type": "integer" - }, - "waveform": { - "type": "integer" - }, - "phase": { - "type": "number" - }, - "frequency_hz": { - "type": "number" - }, - "carrier": { - "type": "number", - "description": "The carrier's phase at the play's first sample, cycles in [0, 1)." - }, - "value": { - "type": "number" - }, - "bit": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "calls": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "params": { - "type": "array", - "items": { - "type": "number" - } - }, - "start": { - "type": "integer" - }, - "end": { - "type": "integer" - }, - "line": { - "type": "integer" - } - } - } - }, - "bits": { - "type": "array", - "items": { - "type": "string" - } - }, - "qubits": { - "type": "array", - "items": { - "type": "integer" - } - }, - "decimated": { - "type": "string" - }, - "diagnostics": { - "type": "array", - "items": { - "type": "object", - "description": "A reader's note or warning (qasm::diag).", - "properties": { - "code": { - "type": "string" - }, - "outcome": { - "type": "string" - }, - "message": { - "type": "string" - }, - "line": { - "type": "integer" - }, - "column": { - "type": "integer" - }, - "length": { - "type": "integer" - } - } - } - }, - "calibration": { - "type": "object", - "description": "What a pulse run's receipt binds of the program: the BLAKE3 of the control program's text, of its calibrations as written (every cal, defcal and defcalgrammar, joined by newlines), and of the schedule's JSON; a run adds the device's and the target snapshot's.", - "required": [ - "program", - "calibrations", - "schedule" - ], - "properties": { - "program": { - "type": "string" - }, - "calibrations": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "device": { - "type": "string" - }, - "target": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "calibration": { - "type": "object" - } - } - } - } - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - } - } - }, - { - "type": "object", - "description": "A pulse job checked (pulse_check, wai-quantum pulse check, POST /v1/pulse/check): its receipt's signature, its program's digest, and the request run again with the result held to the one given.", - "required": [ - "answer", - "verified", - "signature", - "program", - "reproduced", - "differences", - "statement" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.pulse/1" - }, - "answer": { - "const": "check" - }, - "verified": { - "type": "boolean" - }, - "signature": { - "type": "boolean" - }, - "key": {}, - "program": { - "type": "boolean" - }, - "reproduced": { - "type": "boolean" - }, - "differences": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Each field (or field.member) whose value differs from the run here." - }, - "density_hash": { - "type": "object", - "properties": { - "given": {}, - "recomputed": {} - } - }, - "calibration": {}, - "statement": { - "type": "string" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "gradient_qasm", - "title": "The exact gradient of a Hamiltonian's expectation by a program's parameters", - "description": "The expectation E = ⟨ψ|H|ψ⟩ of a Hamiltonian at a program's parameters, and its gradient by each parameter, exactly: by adjoint differentiation or the parameter-shift rule on the double-precision state vector (at most 20 qubits, no noise, measurements only at the end). The reader follows each parameter into the gates, so an argument may be any expression of the built-in functions. The answer states its method, that it is f64 and approximate, and a bound on the rounding of the value and of each component (precision.rounding_bound). Sealed with the service's key. Quote the gradient with its bound.", - "inputSchema": { - "type": "object", - "required": [ - "qasm", - "params", - "hamiltonian" - ], - "properties": { - "qasm": { - "type": "string", - "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." - }, - "hamiltonian": { - "type": "array", - "minItems": 1, - "maxItems": 4096, - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "pauli" - ], - "properties": { - "pauli": { - "type": "string" - }, - "coeff": { - "type": "number" - } - } - } - ] - }, - "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ], - "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/gradient_qasm/1", - "type": "object", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.algorithms/1", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", - "required": [ - "call", - "value", - "gradient", - "params", - "method", - "how", - "evaluations", - "qubits", - "gates", - "moved_gates", - "parameters", - "terms", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "gradient" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "value": { - "type": "number", - "description": "⟨ψ|H|ψ⟩ at the params." - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "∂E/∂p for each parameter p, by name." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The point, by name." - }, - "method": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "how": { - "type": "string" - }, - "evaluations": { - "type": "integer", - "minimum": 0, - "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "moved_gates": { - "type": "integer", - "minimum": 0, - "description": "Gates a parameter moves." - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0, - "description": "The Hamiltonian's Pauli terms." - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "optimize" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - } - } - }, - { - "type": "object", - "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "reference" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "vqe" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "reference": { - "anyOf": [ - { - "type": "object", - "required": [ - "ground_energy", - "how", - "gap" - ], - "properties": { - "ground_energy": { - "type": "number" - }, - "first_excited": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "how": { - "type": "string" - }, - "gap": { - "type": "number", - "description": "The best energy found above the ground energy." - } - } - }, - { - "type": "object", - "required": [ - "unchecked" - ], - "properties": { - "unchecked": { - "type": "string" - } - } - } - ] - }, - "ansatz": { - "type": "object", - "required": [ - "qasm", - "params", - "kind" - ], - "properties": { - "qasm": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "kind": { - "const": "hardware_efficient" - } - } - } - } - }, - { - "type": "object", - "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "graph", - "layers", - "program", - "hamiltonian", - "maxcut" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "qaoa" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 0 - }, - "edges": { - "type": "array", - "items": { - "type": "array", - "minItems": 3, - "maxItems": 3 - } - } - } - }, - "layers": { - "type": "integer", - "minimum": 0 - }, - "program": { - "type": "string" - }, - "hamiltonian": { - "type": "array" - }, - "maxcut": { - "type": "object", - "required": [ - "max_cut", - "optimal", - "optimal_count", - "how", - "expected_cut", - "ratio", - "most_likely", - "p_optimal", - "bits" - ], - "properties": { - "max_cut": { - "type": "number" - }, - "optimal": { - "type": "array", - "items": { - "type": "string" - } - }, - "optimal_count": { - "type": "integer", - "minimum": 0 - }, - "how": { - "type": "string" - }, - "expected_cut": { - "type": "number" - }, - "ratio": { - "type": "number" - }, - "most_likely": { - "type": "object", - "required": [ - "bits", - "probability", - "cut", - "optimal" - ], - "properties": { - "bits": { - "type": "string" - }, - "probability": { - "type": "number" - }, - "cut": { - "type": "number" - }, - "optimal": { - "type": "boolean" - } - } - }, - "p_optimal": { - "type": "number" - }, - "bits": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", - "required": [ - "call", - "algorithm", - "qasm", - "qubits", - "gates", - "reads", - "expected", - "check" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "build" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "qasm": { - "type": "string" - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "reads": { - "type": "object", - "description": "How to read the program's result." - }, - "expected": { - "type": "object", - "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." - }, - "check": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "exact", - "random", - "none" - ] - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": "number" - }, - "reference": { - "type": "string" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "optimize_qasm", - "title": "Minimise a Hamiltonian's expectation over a program's parameters", - "description": "Minimise E = ⟨ψ|H|ψ⟩ over a program's parameters from the given params, deterministically: gradient descent with a fixed step, Adam, or SPSA from a seeded stream (at most 2000 steps). Every step's parameters and value (and gradient, or SPSA's perturbation and estimate) are listed, each step a link of a digest chain from the request, best and final given; the same request gives the same bytes on every platform. Sealed with the service's key: the receipt binds the program, every step, the method and the seed, and verify_quantum_result (or wai-quantum verify) re-runs it. A minimum found is a minimum along this path, not a proof of the global one.", - "inputSchema": { - "type": "object", - "required": [ - "qasm", - "params", - "hamiltonian" - ], - "properties": { - "qasm": { - "type": "string", - "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." - }, - "hamiltonian": { - "type": "array", - "minItems": 1, - "maxItems": 4096, - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "pauli" - ], - "properties": { - "pauli": { - "type": "string" - }, - "coeff": { - "type": "number" - } - } - } - ] - }, - "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." - }, - "optimizer": { - "anyOf": [ - { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - } - } - } - ], - "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." - }, - "steps": { - "type": "integer", - "minimum": 1, - "maximum": 2000, - "description": "Steps to take (default 100)." - }, - "step_size": { - "type": "number", - "exclusiveMinimum": 0, - "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ], - "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." - }, - "seed": { - "type": "integer", - "minimum": 0, - "description": "SPSA's seed (default 1)." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/optimize_qasm/1", - "type": "object", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.algorithms/1", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", - "required": [ - "call", - "value", - "gradient", - "params", - "method", - "how", - "evaluations", - "qubits", - "gates", - "moved_gates", - "parameters", - "terms", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "gradient" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "value": { - "type": "number", - "description": "⟨ψ|H|ψ⟩ at the params." - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "∂E/∂p for each parameter p, by name." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The point, by name." - }, - "method": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "how": { - "type": "string" - }, - "evaluations": { - "type": "integer", - "minimum": 0, - "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "moved_gates": { - "type": "integer", - "minimum": 0, - "description": "Gates a parameter moves." - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0, - "description": "The Hamiltonian's Pauli terms." - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "optimize" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - } - } - }, - { - "type": "object", - "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "reference" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "vqe" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "reference": { - "anyOf": [ - { - "type": "object", - "required": [ - "ground_energy", - "how", - "gap" - ], - "properties": { - "ground_energy": { - "type": "number" - }, - "first_excited": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "how": { - "type": "string" - }, - "gap": { - "type": "number", - "description": "The best energy found above the ground energy." - } - } - }, - { - "type": "object", - "required": [ - "unchecked" - ], - "properties": { - "unchecked": { - "type": "string" - } - } - } - ] - }, - "ansatz": { - "type": "object", - "required": [ - "qasm", - "params", - "kind" - ], - "properties": { - "qasm": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "kind": { - "const": "hardware_efficient" - } - } - } - } - }, - { - "type": "object", - "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "graph", - "layers", - "program", - "hamiltonian", - "maxcut" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "qaoa" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 0 - }, - "edges": { - "type": "array", - "items": { - "type": "array", - "minItems": 3, - "maxItems": 3 - } - } - } - }, - "layers": { - "type": "integer", - "minimum": 0 - }, - "program": { - "type": "string" - }, - "hamiltonian": { - "type": "array" - }, - "maxcut": { - "type": "object", - "required": [ - "max_cut", - "optimal", - "optimal_count", - "how", - "expected_cut", - "ratio", - "most_likely", - "p_optimal", - "bits" - ], - "properties": { - "max_cut": { - "type": "number" - }, - "optimal": { - "type": "array", - "items": { - "type": "string" - } - }, - "optimal_count": { - "type": "integer", - "minimum": 0 - }, - "how": { - "type": "string" - }, - "expected_cut": { - "type": "number" - }, - "ratio": { - "type": "number" - }, - "most_likely": { - "type": "object", - "required": [ - "bits", - "probability", - "cut", - "optimal" - ], - "properties": { - "bits": { - "type": "string" - }, - "probability": { - "type": "number" - }, - "cut": { - "type": "number" - }, - "optimal": { - "type": "boolean" - } - } - }, - "p_optimal": { - "type": "number" - }, - "bits": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", - "required": [ - "call", - "algorithm", - "qasm", - "qubits", - "gates", - "reads", - "expected", - "check" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "build" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "qasm": { - "type": "string" - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "reads": { - "type": "object", - "description": "How to read the program's result." - }, - "expected": { - "type": "object", - "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." - }, - "check": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "exact", - "random", - "none" - ] - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": "number" - }, - "reference": { - "type": "string" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "vqe_ground_state", - "title": "Find a Hamiltonian's ground energy by the variational eigensolver", - "description": "The variational eigensolver: an ansatz (the program given as qasm with params, or ansatz {\"layers\": L}: layers of ry and rz on every qubit and a ring of cx, its parameters t0, t1, … from 0.1) optimised on the Hamiltonian as optimize_qasm does. At most 8 qubits the answer sets the energy found beside the exact ground energy by diagonalisation (reference.ground_energy and gap); the energy found is never below it. Sealed with the service's key. Report the gap: an ansatz that cannot reach the ground state stops above it.", - "inputSchema": { - "type": "object", - "required": [ - "hamiltonian" - ], - "properties": { - "hamiltonian": { - "type": "array", - "minItems": 1, - "maxItems": 4096, - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "required": [ - "pauli" - ], - "properties": { - "pauli": { - "type": "string" - }, - "coeff": { - "type": "number" - } - } - } - ] - }, - "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." - }, - "qasm": { - "type": "string", - "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." - }, - "ansatz": { - "type": "object", - "properties": { - "layers": { - "type": "integer", - "minimum": 1, - "maximum": 16 - }, - "qubits": { - "type": "integer", - "minimum": 1, - "maximum": 20 - } - }, - "description": "The built-in ansatz in place of qasm (layers default 2, qubits the Hamiltonian's)." - }, - "optimizer": { - "anyOf": [ - { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - } - } - } - ], - "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." - }, - "steps": { - "type": "integer", - "minimum": 1, - "maximum": 2000, - "description": "Steps to take (default 100)." - }, - "step_size": { - "type": "number", - "exclusiveMinimum": 0, - "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ], - "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." - }, - "seed": { - "type": "integer", - "minimum": 0, - "description": "SPSA's seed (default 1)." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/vqe_ground_state/1", - "type": "object", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.algorithms/1", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", - "required": [ - "call", - "value", - "gradient", - "params", - "method", - "how", - "evaluations", - "qubits", - "gates", - "moved_gates", - "parameters", - "terms", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "gradient" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "value": { - "type": "number", - "description": "⟨ψ|H|ψ⟩ at the params." - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "∂E/∂p for each parameter p, by name." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The point, by name." - }, - "method": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "how": { - "type": "string" - }, - "evaluations": { - "type": "integer", - "minimum": 0, - "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "moved_gates": { - "type": "integer", - "minimum": 0, - "description": "Gates a parameter moves." - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0, - "description": "The Hamiltonian's Pauli terms." - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "optimize" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - } - } - }, - { - "type": "object", - "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "reference" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "vqe" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "reference": { - "anyOf": [ - { - "type": "object", - "required": [ - "ground_energy", - "how", - "gap" - ], - "properties": { - "ground_energy": { - "type": "number" - }, - "first_excited": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "how": { - "type": "string" - }, - "gap": { - "type": "number", - "description": "The best energy found above the ground energy." - } - } - }, - { - "type": "object", - "required": [ - "unchecked" - ], - "properties": { - "unchecked": { - "type": "string" - } - } - } - ] - }, - "ansatz": { - "type": "object", - "required": [ - "qasm", - "params", - "kind" - ], - "properties": { - "qasm": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "kind": { - "const": "hardware_efficient" - } - } - } - } - }, - { - "type": "object", - "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "graph", - "layers", - "program", - "hamiltonian", - "maxcut" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "qaoa" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 0 - }, - "edges": { - "type": "array", - "items": { - "type": "array", - "minItems": 3, - "maxItems": 3 - } - } - } - }, - "layers": { - "type": "integer", - "minimum": 0 - }, - "program": { - "type": "string" - }, - "hamiltonian": { - "type": "array" - }, - "maxcut": { - "type": "object", - "required": [ - "max_cut", - "optimal", - "optimal_count", - "how", - "expected_cut", - "ratio", - "most_likely", - "p_optimal", - "bits" - ], - "properties": { - "max_cut": { - "type": "number" - }, - "optimal": { - "type": "array", - "items": { - "type": "string" - } - }, - "optimal_count": { - "type": "integer", - "minimum": 0 - }, - "how": { - "type": "string" - }, - "expected_cut": { - "type": "number" - }, - "ratio": { - "type": "number" - }, - "most_likely": { - "type": "object", - "required": [ - "bits", - "probability", - "cut", - "optimal" - ], - "properties": { - "bits": { - "type": "string" - }, - "probability": { - "type": "number" - }, - "cut": { - "type": "number" - }, - "optimal": { - "type": "boolean" - } - } - }, - "p_optimal": { - "type": "number" - }, - "bits": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", - "required": [ - "call", - "algorithm", - "qasm", - "qubits", - "gates", - "reads", - "expected", - "check" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "build" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "qasm": { - "type": "string" - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "reads": { - "type": "object", - "description": "How to read the program's result." - }, - "expected": { - "type": "object", - "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." - }, - "check": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "exact", - "random", - "none" - ] - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": "number" - }, - "reference": { - "type": "string" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "qaoa_maxcut", - "title": "Solve Max-Cut on a graph by QAOA", - "description": "Max-Cut by the quantum approximate optimisation algorithm: the program (|+⟩ⁿ, then for each layer rzz(gamma·w) on every edge and rx(2·beta) on every qubit) and its cost Hamiltonian built from the graph (at most 20 vertices, 16 layers), optimised as optimize_qasm does from the params or a linear ramp, and read against the maximum cut found by brute force: the expected cut and its ratio to the maximum, the likeliest assignment and whether it is optimal, and the probability of an optimal one. Sealed with the service's key.", - "inputSchema": { - "type": "object", - "required": [ - "graph" - ], - "properties": { - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 2, - "maximum": 20 - }, - "edges": { - "type": "array", - "minItems": 1, - "maxItems": 400, - "items": { - "type": "array", - "minItems": 2, - "maxItems": 3, - "items": { - "type": "number" - } - }, - "description": "Each edge [i, j] or [i, j, weight]." - } - } - }, - "layers": { - "type": "integer", - "minimum": 1, - "maximum": 16, - "description": "QAOA's p (default 1)." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "gamma_0, beta_0, … to start from." - }, - "optimizer": { - "anyOf": [ - { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - } - } - } - ], - "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." - }, - "steps": { - "type": "integer", - "minimum": 1, - "maximum": 2000, - "description": "Steps to take (default 100)." - }, - "step_size": { - "type": "number", - "exclusiveMinimum": 0, - "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ], - "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." - }, - "seed": { - "type": "integer", - "minimum": 0, - "description": "SPSA's seed (default 1)." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/qaoa_maxcut/1", - "type": "object", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.algorithms/1", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", - "required": [ - "call", - "value", - "gradient", - "params", - "method", - "how", - "evaluations", - "qubits", - "gates", - "moved_gates", - "parameters", - "terms", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "gradient" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "value": { - "type": "number", - "description": "⟨ψ|H|ψ⟩ at the params." - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "∂E/∂p for each parameter p, by name." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The point, by name." - }, - "method": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "how": { - "type": "string" - }, - "evaluations": { - "type": "integer", - "minimum": 0, - "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "moved_gates": { - "type": "integer", - "minimum": 0, - "description": "Gates a parameter moves." - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0, - "description": "The Hamiltonian's Pauli terms." - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "optimize" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - } - } - }, - { - "type": "object", - "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "reference" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "vqe" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "reference": { - "anyOf": [ - { - "type": "object", - "required": [ - "ground_energy", - "how", - "gap" - ], - "properties": { - "ground_energy": { - "type": "number" - }, - "first_excited": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "how": { - "type": "string" - }, - "gap": { - "type": "number", - "description": "The best energy found above the ground energy." - } - } - }, - { - "type": "object", - "required": [ - "unchecked" - ], - "properties": { - "unchecked": { - "type": "string" - } - } - } - ] - }, - "ansatz": { - "type": "object", - "required": [ - "qasm", - "params", - "kind" - ], - "properties": { - "qasm": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "kind": { - "const": "hardware_efficient" - } - } - } - } - }, - { - "type": "object", - "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "graph", - "layers", - "program", - "hamiltonian", - "maxcut" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "qaoa" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 0 - }, - "edges": { - "type": "array", - "items": { - "type": "array", - "minItems": 3, - "maxItems": 3 - } - } - } - }, - "layers": { - "type": "integer", - "minimum": 0 - }, - "program": { - "type": "string" - }, - "hamiltonian": { - "type": "array" - }, - "maxcut": { - "type": "object", - "required": [ - "max_cut", - "optimal", - "optimal_count", - "how", - "expected_cut", - "ratio", - "most_likely", - "p_optimal", - "bits" - ], - "properties": { - "max_cut": { - "type": "number" - }, - "optimal": { - "type": "array", - "items": { - "type": "string" - } - }, - "optimal_count": { - "type": "integer", - "minimum": 0 - }, - "how": { - "type": "string" - }, - "expected_cut": { - "type": "number" - }, - "ratio": { - "type": "number" - }, - "most_likely": { - "type": "object", - "required": [ - "bits", - "probability", - "cut", - "optimal" - ], - "properties": { - "bits": { - "type": "string" - }, - "probability": { - "type": "number" - }, - "cut": { - "type": "number" - }, - "optimal": { - "type": "boolean" - } - } - }, - "p_optimal": { - "type": "number" - }, - "bits": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", - "required": [ - "call", - "algorithm", - "qasm", - "qubits", - "gates", - "reads", - "expected", - "check" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "build" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "qasm": { - "type": "string" - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "reads": { - "type": "object", - "description": "How to read the program's result." - }, - "expected": { - "type": "object", - "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." - }, - "check": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "exact", - "random", - "none" - ] - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": "number" - }, - "reference": { - "type": "string" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } - }, - { - "name": "build_algorithm", - "title": "Write the program for a standard algorithm, checked against its reference", - "description": "An OpenQASM 3 program for a standard algorithm, with how to read its result, what it gives, and the equivalence ladder's verdict on it against a reference matrix or truth table built from the definitions (check: exact on every basis state up to 8 qubits, the adder's up to 16; past that unchecked). qpe: the phase φ of p(2πφ) on counting qubits; amplitude_estimation: the amplitude a that A = ry(2·arcsin √a) gives the good state, by phase estimation of the Grover operator; adder: the ripple-carry adder of bits-bit integers in place (with a and b, prepared and measured); qsvt: quantum signal processing from phases, of a signal x or of a real symmetric 2 × 2 matrix through its block encoding (all phases zero give the Chebyshev polynomial). Sealed with the service's key. Run the program with run_quantum_circuit.", - "inputSchema": { - "type": "object", - "required": [ - "algorithm" - ], - "properties": { - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "counting": { - "type": "integer", - "minimum": 1, - "maximum": 20, - "description": "qpe, amplitude_estimation: counting qubits (default 4)." - }, - "phase": { - "type": "number", - "description": "qpe: the phase φ, in turns." - }, - "amplitude": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "amplitude_estimation: the good state's probability a." - }, - "bits": { - "type": "integer", - "minimum": 1, - "maximum": 32, - "description": "adder: the integers' width." - }, - "a": { - "type": "integer", - "minimum": 0, - "description": "adder: the first addend, prepared." - }, - "b": { - "type": "integer", - "minimum": 0, - "description": "adder: the second, which the sum replaces." - }, - "carry_in": { - "type": "boolean", - "description": "adder: a carry in." - }, - "phases": { - "type": "array", - "minItems": 2, - "maxItems": 64, - "items": { - "type": "number" - }, - "description": "qsvt: φ₀ … φ_d, radians." - }, - "x": { - "type": "number", - "minimum": -1, - "maximum": 1, - "description": "qsvt: the signal." - }, - "matrix": { - "type": "array", - "description": "qsvt: [[a, b], [b, c]], real and symmetric, its eigenvalues within [-1, 1]." - } - } - }, - "annotations": { - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "outputSchema": { - "$id": "wai-quantum://schemas/build_algorithm/1", - "type": "object", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "anyOf": [ - { - "title": "wai.quantum.algorithms/1", - "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", - "type": "object", - "required": [ - "request", - "result" - ], - "properties": { - "request": { - "type": "object", - "description": "The call's request, as given." - }, - "result": { - "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", - "anyOf": [ - { - "type": "object", - "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", - "required": [ - "call", - "value", - "gradient", - "params", - "method", - "how", - "evaluations", - "qubits", - "gates", - "moved_gates", - "parameters", - "terms", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "gradient" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "value": { - "type": "number", - "description": "⟨ψ|H|ψ⟩ at the params." - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "∂E/∂p for each parameter p, by name." - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "The point, by name." - }, - "method": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "how": { - "type": "string" - }, - "evaluations": { - "type": "integer", - "minimum": 0, - "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "moved_gates": { - "type": "integer", - "minimum": 0, - "description": "Gates a parameter moves." - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0, - "description": "The Hamiltonian's Pauli terms." - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "optimize" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - } - } - }, - { - "type": "object", - "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "reference" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "vqe" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "reference": { - "anyOf": [ - { - "type": "object", - "required": [ - "ground_energy", - "how", - "gap" - ], - "properties": { - "ground_energy": { - "type": "number" - }, - "first_excited": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "how": { - "type": "string" - }, - "gap": { - "type": "number", - "description": "The best energy found above the ground energy." - } - } - }, - { - "type": "object", - "required": [ - "unchecked" - ], - "properties": { - "unchecked": { - "type": "string" - } - } - } - ] - }, - "ansatz": { - "type": "object", - "required": [ - "qasm", - "params", - "kind" - ], - "properties": { - "qasm": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "kind": { - "const": "hardware_efficient" - } - } - } - } - }, - { - "type": "object", - "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", - "required": [ - "call", - "optimizer", - "qubits", - "gates", - "parameters", - "terms", - "start", - "steps", - "chain", - "best", - "final", - "evaluations", - "precision", - "graph", - "layers", - "program", - "hamiltonian", - "maxcut" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "qaoa" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "optimizer": { - "type": "object", - "required": [ - "name", - "steps", - "step_size" - ], - "properties": { - "name": { - "enum": [ - "gradient_descent", - "adam", - "spsa" - ] - }, - "steps": { - "type": "integer", - "minimum": 0 - }, - "step_size": { - "type": "number" - }, - "gradient": { - "enum": [ - "adjoint", - "parameter_shift" - ] - }, - "beta1": { - "type": "number" - }, - "beta2": { - "type": "number" - }, - "epsilon": { - "type": "number" - }, - "c": { - "type": "number" - }, - "A": { - "type": "number" - }, - "alpha": { - "type": "number" - }, - "gamma": { - "type": "number" - }, - "seed": { - "type": "integer", - "minimum": 0 - } - } - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "parameters": { - "type": "array", - "description": "The program's parameters, in the order it declares them.", - "items": { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "enum": [ - "float", - "angle", - "float[64]" - ] - } - } - } - }, - "terms": { - "type": "integer", - "minimum": 0 - }, - "start": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "required": [ - "step", - "params", - "value", - "digest" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Gradient descent and Adam: the gradient at the step's params." - }, - "perturbation": { - "type": "array", - "items": { - "enum": [ - 1.0, - -1.0 - ] - }, - "description": "SPSA: the step's perturbation, from the seeded stream." - }, - "estimate": { - "type": "array", - "items": { - "type": "number" - }, - "description": "SPSA: the gradient's estimate." - }, - "gains": { - "type": "object", - "required": [ - "a", - "c" - ], - "properties": { - "a": { - "type": "number" - }, - "c": { - "type": "number" - } - }, - "description": "SPSA: the step's gains a_k and c_k." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." - } - } - }, - "minItems": 2 - }, - "chain": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The chain's last link." - }, - "best": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "final": { - "type": "object", - "required": [ - "step", - "params", - "value" - ], - "properties": { - "step": { - "type": "integer", - "minimum": 0 - }, - "params": { - "type": "object", - "additionalProperties": { - "type": "number" - } - }, - "value": { - "type": "number" - } - } - }, - "evaluations": { - "type": "integer", - "minimum": 0 - }, - "precision": { - "type": "object", - "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", - "required": [ - "arithmetic", - "exact", - "rounding_bound", - "reading" - ], - "properties": { - "arithmetic": { - "const": "f64" - }, - "exact": { - "const": false - }, - "rounding_bound": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "number", - "minimum": 0 - }, - "gradient": { - "type": "object", - "additionalProperties": { - "type": "number", - "minimum": 0 - }, - "description": "Each component's bound, by parameter." - } - } - }, - "reading": { - "type": "string" - } - } - }, - "note": { - "type": "string" - }, - "graph": { - "type": "object", - "required": [ - "nodes", - "edges" - ], - "properties": { - "nodes": { - "type": "integer", - "minimum": 0 - }, - "edges": { - "type": "array", - "items": { - "type": "array", - "minItems": 3, - "maxItems": 3 - } - } - } - }, - "layers": { - "type": "integer", - "minimum": 0 - }, - "program": { - "type": "string" - }, - "hamiltonian": { - "type": "array" - }, - "maxcut": { - "type": "object", - "required": [ - "max_cut", - "optimal", - "optimal_count", - "how", - "expected_cut", - "ratio", - "most_likely", - "p_optimal", - "bits" - ], - "properties": { - "max_cut": { - "type": "number" - }, - "optimal": { - "type": "array", - "items": { - "type": "string" - } - }, - "optimal_count": { - "type": "integer", - "minimum": 0 - }, - "how": { - "type": "string" - }, - "expected_cut": { - "type": "number" - }, - "ratio": { - "type": "number" - }, - "most_likely": { - "type": "object", - "required": [ - "bits", - "probability", - "cut", - "optimal" - ], - "properties": { - "bits": { - "type": "string" - }, - "probability": { - "type": "number" - }, - "cut": { - "type": "number" - }, - "optimal": { - "type": "boolean" - } - } - }, - "p_optimal": { - "type": "number" - }, - "bits": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", - "required": [ - "call", - "algorithm", - "qasm", - "qubits", - "gates", - "reads", - "expected", - "check" - ], - "properties": { - "engine": { - "type": "object", - "description": "The engine that made the result: the wai-quantum crate's name and version.", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "const": "wai-quantum" - }, - "version": { - "type": "string" - } - } - }, - "schema": { - "const": "wai.quantum.algorithms/1" - }, - "call": { - "const": "build" - }, - "receipt": { - "title": "wai.quantum.receipt/2", - "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", - "type": "object", - "required": [ - "alg", - "canon", - "key", - "digest", - "signature" - ], - "properties": { - "alg": { - "const": "ed25519" - }, - "canon": { - "const": "rfc8785", - "description": "The canonical form the digest is taken over." - }, - "key": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The signing key, 32 bytes in hex." - }, - "digest": { - "type": "string", - "minLength": 64, - "maxLength": 64, - "description": "The digest signed, 32 bytes in hex." - }, - "signature": { - "type": "string", - "minLength": 128, - "maxLength": 128, - "description": "The signature, 64 bytes in hex." - } - } - }, - "algorithm": { - "enum": [ - "qpe", - "amplitude_estimation", - "adder", - "qsvt" - ] - }, - "qasm": { - "type": "string" - }, - "qubits": { - "type": "integer", - "minimum": 0 - }, - "gates": { - "type": "integer", - "minimum": 0 - }, - "reads": { - "type": "object", - "description": "How to read the program's result." - }, - "expected": { - "type": "object", - "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." - }, - "check": { - "type": "object", - "required": [ - "verdict", - "how", - "why" - ], - "properties": { - "verdict": { - "enum": [ - "equivalent", - "different", - "unchecked" - ] - }, - "how": { - "enum": [ - "exact", - "random", - "none" - ] - }, - "why": { - "type": "string" - }, - "global_phase": { - "type": "number" - }, - "reference": { - "type": "string" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "code": { - "type": [ - "string", - "null" - ] - }, - "codes": { - "type": "array", - "items": { - "type": "string" - } - }, - "outcome": { - "enum": [ - "refused", - "retry", - "failed", - "lowered", - "carried", - "preserved", - "warned", - "dropped", - "defaulted" - ] - }, - "meaning": { - "type": "string" - } - } - } - ] - } } ] } diff --git a/wai/wai-quantum-cli/src/main.rs b/wai/wai-quantum-cli/src/main.rs index eb00740a4..855231368 100644 --- a/wai/wai-quantum-cli/src/main.rs +++ b/wai/wai-quantum-cli/src/main.rs @@ -989,13 +989,16 @@ fn print_job(body: &Value, top: usize) { println!(" … {} more (--top N)", v.len() - top); } } + // A bound that holds with a stated probability says so. + let held = |e: &Value| e.get("confidence").map(|c| format!(" (with probability {})", s(c))).unwrap_or_default(); for e in r.get("expectations").and_then(Value::as_array).into_iter().flatten() { - let bound = e.get("bound").map(|b| format!(" ± {}", s(b))).unwrap_or_default(); + let bound = e.get("bound").map(|b| format!(" ± {}{}", s(b), held(e))).unwrap_or_default(); println!("⟨{}⟩ {}{bound}", s(&e["observable"]), s(&e["value"])); } for a in r.get("amplitudes").and_then(Value::as_array).into_iter().flatten() { let (re, im) = (a["re"].as_f64().unwrap_or(f64::NAN), a["im"].as_f64().unwrap_or(f64::NAN)); - println!("|{}⟩ {re:+.12} {}{:.12}i", s(&a["bits"]), if im < 0.0 { '-' } else { '+' }, im.abs()); + let bound = a.get("bound").map(|b| format!(" ± {}{}", s(b), held(a))).unwrap_or_default(); + println!("|{}⟩ {re:+.12} {}{:.12}i{bound}", s(&a["bits"]), if im < 0.0 { '-' } else { '+' }, im.abs()); } if let Some(d) = r.get("dynamic") { println!("dynamic {d}"); diff --git a/wai/wai-quantum-service/README.md b/wai/wai-quantum-service/README.md index 549c93a48..913a04ad5 100644 --- a/wai/wai-quantum-service/README.md +++ b/wai/wai-quantum-service/README.md @@ -85,6 +85,7 @@ curl -s https://wai.transaction.science/quantum-jobs/v1/run -H 'content-type: ap | `tensor_network` | any circuit | amplitudes | exact | | `cutrank` | a Clifford circuit, then one layer of one-qubit gates at any angles, up to 4096 qubits, as wide as the state's cut-rank allows | counts, amplitudes | exact; single when only a single-precision table fits | | `cutrank_single` | as `cutrank`, with the table on the host's GPU, where it has one; only when asked for | counts, amplitudes | single | +| `stabilizer_rank` | Clifford+T circuits, up to 32768 qubits, as many T gates as one job's sum of `2^t` (an expectation value's `4^t`) branches allows | amplitudes, expectations | exact; with `terms` or `epsilon`, an estimate with its bound and the probability it holds | | `density_matrix` | noisy circuits, up to 16 qubits within a job's memory | counts, expectations | exact | | `trajectories` | noisy circuits, up to 32 qubits | counts, expectations | estimate | @@ -121,7 +122,7 @@ curl -s https://wai.transaction.science/quantum-jobs/v1/run -H 'content-type: ap "observables": ["Z2", "X2"], "shots": 1000 }' ``` -`auto` picks the first method that takes the job. With noise, it tries `density_matrix`, then `stabilizer`, then `trajectories`. For counts, it tries `stabilizer`, `exact`, `statevector`, `statevector_single`, `cutrank`, then `mps`. For expectations alone, it tries `stabilizer`, `exact`, `statevector`, `statevector_single`, `pauli`, then `mps`. For amplitudes alone, it tries `exact`, `statevector`, `statevector_single`, `cutrank`, `tensor_network`, then `mps`. The job's `why` names the method chosen and the ones that could not take it. +`auto` picks the first method that takes the job. With noise, it tries `density_matrix`, then `stabilizer`, then `trajectories`. For counts, it tries `stabilizer`, `exact`, `statevector`, `statevector_single`, `cutrank`, then `mps`. For expectations alone, it tries `stabilizer`, `exact`, `statevector`, `statevector_single`, `stabilizer_rank`, `pauli`, then `mps`. For amplitudes alone, it tries `exact`, `statevector`, `statevector_single`, `cutrank`, `stabilizer_rank`, `tensor_network`, then `mps`. The job's `why` names the method chosen and the ones that could not take it. The accuracy classes: diff --git a/wai/wai-quantum-service/src/discovery.rs b/wai/wai-quantum-service/src/discovery.rs index 6d7edce09..f275a4112 100644 --- a/wai/wai-quantum-service/src/discovery.rs +++ b/wai/wai-quantum-service/src/discovery.rs @@ -115,7 +115,7 @@ pub fn openapi(server: &str) -> Value { "required": ["qasm"], "properties": { "qasm": { "type": "string", "description": "The program: OpenQASM 3, or OpenQASM 2. Registers, standard gates (h, x, y, z, s, sdg, t, tdg, sx, rx, ry, rz, p, u, cx, cy, cz, ch, swap, iswap, cp, crx, cry, crz, ccx, ccz, cswap, rxx, ryy, rzz), the control modifiers ctrl @, ctrl(n) @ and negctrl @ on x y z h s sdg t tdg p and the controlled names, user gate definitions, measurement anywhere, reset anywhere, and `if (c[0]) …` / `if (c == 3) { … } else { … }` on measured bits (OpenQASM 2's `if(c==n) gate;` too). A program that measures in the middle, resets after a gate or acts on measured bits runs on statevector or stabilizer: counts split their shots at each measurement, expectation values are the exact mixture over the branches, of the state before the final measurements. Loops, inv @ and pow @ are refused, with the line." }, - "method": { "type": "string", "enum": ["auto", "exact", "statevector", "statevector_single", "stabilizer", "pauli", "mps", "tensor_network", "cutrank", "cutrank_single", "density_matrix", "trajectories", "pulse"], "default": "auto", "description": "pulse: a pulse program (OpenPulse calibrations on physical qubits) integrated under its pulse options, its error bounded (POST /v1/pulse/schedule draws its schedule)." }, + "method": { "type": "string", "enum": ["auto", "exact", "statevector", "statevector_single", "stabilizer", "pauli", "mps", "tensor_network", "cutrank", "cutrank_single", "stabilizer_rank", "density_matrix", "trajectories", "pulse"], "default": "auto", "description": "pulse: a pulse program (OpenPulse calibrations on physical qubits) integrated under its pulse options, its error bounded (POST /v1/pulse/schedule draws its schedule)." }, "shots": { "type": "integer", "minimum": 0, "maximum": 1000000, "description": "Measurement shots (default 1024 when nothing else is asked for)." }, "seed": { "type": "integer", "default": 1, "description": "The sampling seed: the same job and seed give the same counts." }, "observables": { "type": "array", "items": pauli }, diff --git a/wai/wai-quantum-service/src/mcp.rs b/wai/wai-quantum-service/src/mcp.rs index 6f957bc43..22071858d 100644 --- a/wai/wai-quantum-service/src/mcp.rs +++ b/wai/wai-quantum-service/src/mcp.rs @@ -223,7 +223,7 @@ fn tool_list() -> Value { "noise": { "type": "object", "description": "Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit).", "properties": { "depolarizing_1q": { "type": "number" }, "depolarizing_2q": { "type": "number" }, "amplitude_damping": { "type": "number" }, "dephasing": { "type": "number" }, "readout": { "type": "number" } } }, - "method": { "type": "string", "enum": ["auto", "exact", "statevector", "statevector_single", "stabilizer", "pauli", "mps", "tensor_network", "cutrank", "cutrank_single", "density_matrix", "trajectories", "pulse"], "description": "Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." }, + "method": { "type": "string", "enum": ["auto", "exact", "statevector", "statevector_single", "stabilizer", "pauli", "mps", "tensor_network", "cutrank", "cutrank_single", "stabilizer_rank", "density_matrix", "trajectories", "pulse"], "description": "Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." }, "seed": { "type": "integer", "description": "Sampling seed (default 1); the same job and seed give the same counts." }, "options": { "type": "object", "description": "Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories." }, "compile": { "type": "object", "description": "Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program.", "properties": compile_props() }, diff --git a/wai/wai-quantum/README.md b/wai/wai-quantum/README.md index e7703ef62..e9fc2e319 100644 --- a/wai/wai-quantum/README.md +++ b/wai/wai-quantum/README.md @@ -757,6 +757,56 @@ and one exact sample 1.1 to 1.5 s, with a largest table of 4 GiB in single precision. Amplitudes agree between orders and between precisions to about 10⁻⁷ relative. +## Clifford+T circuits as sums of stabilizer states + +```sh runnable +cat > ct.qasm <<'QASM' +OPENQASM 3.0; +qubit[40] q; +h q; +t q[0]; +cx q[0], q[1]; +tdg q[1]; +cx q[1], q[39]; +t q[39]; +h q; +QASM +wai-quantum run ct.qasm -a 0000000000000000000000000000000000000000 -o "Z0 Z1" +wai-quantum run ct.qasm --method stabilizer_rank -a 0000000000000000000000000000000000000000 --option terms=2000 --json > ct-sampled.json +``` + +A T gate is a sum of two Clifford gates of equal weight, +`T = (e^{iπ/8} I + e^{−iπ/8} S) / (2 cos π/8)`, so a circuit with `t` T and +T† gates is a sum of `2^t` stabilizer states. `quantum_stabrank` walks every +branch on the phased tableau, which gives each amplitude of a stabilizer state +exactly (`PhasedTableau::amplitudes`, from one reduction of the stabilizers), +and counts every term, a power of `1/√2` at a whole number of sixteenths of a +turn, as a whole number, so the sum is the same however the branches are split +between threads and is evaluated once in double precision. An expectation +value `⟨ψ|P|ψ⟩` is the amplitude `⟨0|U†PU|0⟩`, a sum over twice the T gates. +The job engine's `stabilizer_rank` method lowers a program's `t`, `tdg`, and +`p`, `rz`, `rx` and `ry` at odd multiples of π/4, `cp` at odd multiples of π/2, +`ccz` and `ccx` to T gates, and every Clifford gate as the tableau's, with the +global phase kept exactly; `auto` takes it for amplitudes or expectation values +past the dense state vector when its branches fit one job's work, so it is +chosen by the T count. + +The sampled mode (`--option terms=N`, or `--option epsilon=E` for as many terms +as that bound needs, at `--option confidence=C`, default 0.95) draws `N` +branches uniformly, seeded, each from a stream of its own: an unbiased estimate +of the state whose mean squared distance from it is `(sec²(π/8)^t − 1) / N`. So +each amplitude, and each expectation value through its own sum, is within +`sqrt((sec²(π/8)^t − 1) / (N (1 − C)))` of the exact one with probability at +least `C`. The result's class is `estimate`, with that bound and its +confidence beside each value: computed from the T count, the terms and the +confidence, never from the result. + +Both modes are held to the dense state vector: every amplitude of random +Clifford+T circuits up to 7 qubits and 10 T gates, phase and all, within +`10⁻¹²`, the fidelity within `10⁻¹²` of 1, every expectation value likewise; +and the sampled bound holds in at least the fraction it states, measured on the +whole state. + ## Gaussian boson sampling ```sh runnable diff --git a/wai/wai-quantum/README.zh-CN.md b/wai/wai-quantum/README.zh-CN.md index d043ddced..416408f1f 100644 --- a/wai/wai-quantum/README.zh-CN.md +++ b/wai/wai-quantum/README.zh-CN.md @@ -437,6 +437,30 @@ CUTRANK_ORDER=order.txt CUTRANK_PRECISION=single \ 一条 70 量子比特的图态采样线路,主体是最近邻的 Clifford 门,随后在每个量子比特上使用非 Clifford 基。采用退火得到的顺序时,每个切分都不超过 29 比特。在一台工作站上,一个振幅约需半秒,一个精确样本需 1.1 到 1.5 秒,单精度下最大的表为 4 GiB。不同顺序之间、不同精度之间,振幅的相对吻合程度约为 10⁻⁷。 +## 写成稳定子态之和的 Clifford+T 线路 + +```sh runnable +cat > ct.qasm <<'QASM' +OPENQASM 3.0; +qubit[40] q; +h q; +t q[0]; +cx q[0], q[1]; +tdg q[1]; +cx q[1], q[39]; +t q[39]; +h q; +QASM +wai-quantum run ct.qasm -a 0000000000000000000000000000000000000000 -o "Z0 Z1" +wai-quantum run ct.qasm --method stabilizer_rank -a 0000000000000000000000000000000000000000 --option terms=2000 --json > ct-sampled.json +``` + +一个 T 门是两个等权 Clifford 门之和,`T = (e^{iπ/8} I + e^{−iπ/8} S) / (2 cos π/8)`,因此含 `t` 个 T 和 T† 门的线路是 `2^t` 个稳定子态之和。`quantum_stabrank` 在带相位的稳定子表上遍历每个分支,表给出稳定子态每个振幅的精确值(`PhasedTableau::amplitudes`,只需对稳定子做一次约化),并把每一项(`1/√2` 的幂乘以整数个十六分之一圈的相位)作为整数计数,因此无论分支如何在线程间划分,和都相同,最后以双精度求值一次。期望值 `⟨ψ|P|ψ⟩` 是振幅 `⟨0|U†PU|0⟩`,是对两倍 T 门的求和。作业引擎的 `stabilizer_rank` 方法把程序中的 `t`、`tdg`,π/4 奇数倍的 `p`、`rz`、`rx`、`ry`,π/2 奇数倍的 `cp`,以及 `ccz` 和 `ccx` 降为 T 门,每个 Clifford 门按稳定子表的方式降低,并精确保留全局相位;当分支在一个作业的工作量之内时,`auto` 会在稠密态矢量之外为振幅或期望值选用它,因此按 T 门数来选择。 + +抽样模式(`--option terms=N`,或 `--option epsilon=E` 取达到该界所需的项数,置信度 `--option confidence=C`,默认 0.95)以种子均匀抽取 `N` 个分支,每个来自各自的流:这是态的无偏估计,与态的均方距离为 `(sec²(π/8)^t − 1) / N`。因此每个振幅,以及经由各自求和的每个期望值,以至少 `C` 的概率落在精确值的 `sqrt((sec²(π/8)^t − 1) / (N (1 − C)))` 之内。结果的类别为 `estimate`,每个值旁给出该界及其置信度:由 T 门数、项数和置信度算出,从不依据结果。 + +两种模式都以稠密态矢量为准检验:最多 7 个量子比特、10 个 T 门的随机 Clifford+T 线路,每个振幅(含相位)误差在 `10⁻¹²` 之内,保真度与 1 相差在 `10⁻¹²` 之内,每个期望值同样如此;抽样界在至少其所述的比例中成立,在整个态上测量。 + ## 高斯玻色采样 ```sh runnable diff --git a/wai/wai-quantum/schemas/job-result.v1.json b/wai/wai-quantum/schemas/job-result.v1.json index cbea0e005..8dab89897 100644 --- a/wai/wai-quantum/schemas/job-result.v1.json +++ b/wai/wai-quantum/schemas/job-result.v1.json @@ -710,7 +710,8 @@ }, "bound": { "type": "number", - "description": "bounded (a pulse run): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together." + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 }, "truncation_bound": { "type": "number", @@ -725,6 +726,20 @@ }, "norm": { "type": "string" + }, + "t_count": { + "type": "integer", + "minimum": 0, + "description": "stabilizer_rank: the T and T† gates the program lowers to." + }, + "terms": { + "type": "integer", + "minimum": 1, + "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." + }, + "confidence": { + "type": "number", + "description": "The probability a stated bound holds." } } }, @@ -752,7 +767,7 @@ }, "bound": { "type": "number", - "description": "A rigorous bound on |exact − value|, for the bounded class." + "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, "peak_terms": { "type": "integer" @@ -791,6 +806,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } }, @@ -811,6 +830,15 @@ }, "im": { "type": "number" + }, + "bound": { + "type": "number", + "minimum": 0, + "description": "A bound on |exact − value| of the amplitude, holding with the probability confidence states (stabilizer_rank's sampled mode)." + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds." } } }, diff --git a/wai/wai-quantum/src/engine/catalog.rs b/wai/wai-quantum/src/engine/catalog.rs index 3edbe658e..d15ad7553 100644 --- a/wai/wai-quantum/src/engine/catalog.rs +++ b/wai/wai-quantum/src/engine/catalog.rs @@ -13,6 +13,7 @@ //! | `stabilizer` | Clifford, ≤ 32768 qubits, optionally with Pauli noise | counts, expectations | exact; an estimate with noise | //! | `pauli` | any, ≤ 1024 qubits | expectations | bounded | //! | `mps` | any, ≤ 4096 qubits, best on low-entanglement circuits | counts, expectations, amplitudes | exact, or heuristic with its fidelity estimate | +//! | `stabilizer_rank` | Clifford+T, ≤ 32768 qubits, as many T gates as its terms allow | amplitudes, expectations | exact, or an estimate with its bound | //! | `tensor_network` | any | amplitudes | exact | //! | `cutrank` | Clifford, then one layer of one-qubit gates at any angles, ≤ 4096 qubits, as wide as its cut-rank allows | counts, amplitudes | exact, or single | //! | `cutrank_single` | as `cutrank`, the table on a GPU (never picked by `auto`) | counts, amplitudes | single | @@ -22,9 +23,11 @@ //! `auto` picks, in order: with noise, `density_matrix`, `stabilizer`, then `trajectories`; //! for counts, `stabilizer`, `exact`, `statevector`, `statevector_single`, //! `cutrank`, `mps`; for expectations only, `stabilizer`, `exact`, `statevector`, -//! `statevector_single`, `pauli`, `mps`; for amplitudes only, `exact`, -//! `statevector`, `statevector_single`, `cutrank`, `tensor_network`, `mps`. A method that cannot take the circuit is -//! skipped, and the plan says why the one chosen was chosen. +//! `statevector_single`, `stabilizer_rank`, `pauli`, `mps`; for amplitudes only, `exact`, +//! `statevector`, `statevector_single`, `cutrank`, `stabilizer_rank`, `tensor_network`, `mps`. A method that cannot take the circuit is +//! skipped, and the plan says why the one chosen was chosen. `stabilizer_rank` +//! is chosen by its T count: `auto` takes its exact sum when its terms (`2^t` +//! for amplitudes, `4^t` for an expectation value) are within one job's work. //! //! A job with `"compile": {"epsilon", "level", "basis"}` runs its program //! compiled first ([`super::compile`]): with the basis `clifford_t` every @@ -70,6 +73,15 @@ pub const CUTRANK_MAX_QUBITS: u32 = 4096; pub const CUTRANK_MAX_CUT: usize = 34; /// The table entries a `cutrank` job's passes may touch: about ten minutes. pub const CUTRANK_MAX_WORK: u64 = 4_000_000_000_000; +/// The most qubits `stabilizer_rank` takes: a tableau's. +pub const STABILIZER_RANK_MAX_QUBITS: u32 = crate::quantum_tableau::MAX_QUBITS; +/// The tableau word operations a `stabilizer_rank` job may take, in the unit +/// [`stabilizer_rank_work`] counts: about a minute on a 16-core host, which +/// walks about 4·10¹⁰ a second. +pub const STABILIZER_RANK_MAX_WORK: u64 = 2_000_000_000_000; +/// The most branches the sampled mode draws. +pub const STABILIZER_RANK_MAX_TERMS: u64 = 100_000_000; + /// The word operations spent searching for an order of the qubits with /// narrower cuts: the planner's one search, about a second, and each of the /// run's searches. @@ -102,7 +114,8 @@ pub struct Plan { /// host that has timed none of its own jobs of the method: the planner's own /// budgets over the times they are stated to take (a stabilizer job's /// [`STABILIZER_MAX_WORK`] about a minute, an `mps` job's [`MPS_MAX_WORK`] -/// and a `cutrank` job's [`CUTRANK_MAX_WORK`] about ten minutes, a density +/// and a `cutrank` job's [`CUTRANK_MAX_WORK`] about ten minutes, a +/// `stabilizer_rank` job's [`STABILIZER_RANK_MAX_WORK`] about one, a density /// matrix's [`DENSITY_MAX_WORK`] about three), and for the state vectors /// 10⁹ amplitude updates a second in double precision, 2·10⁸ in fixed point /// and 10¹⁰ on a GPU. None where the work the planner counts does not @@ -117,6 +130,7 @@ pub fn nominal_rate(method: &str) -> Option { "stabilizer" => Some(STABILIZER_MAX_WORK as f64 / 60.0), "mps" => Some(MPS_MAX_WORK as f64 / 600.0), "cutrank" | "cutrank_single" => Some(CUTRANK_MAX_WORK as f64 / 600.0), + "stabilizer_rank" => Some(STABILIZER_RANK_MAX_WORK as f64 / 60.0), "density_matrix" => Some(DENSITY_MAX_WORK as f64 / 180.0), "pulse" => Some(1e9), _ => None, @@ -129,7 +143,7 @@ pub fn accuracy_classes() -> Value { "bit-exact": "the same bits on every machine: amplitudes in 30-bit fixed point, every output an exact function of them; counts are seeded samples", "exact": "no approximation beyond IEEE double-precision rounding; counts are seeded samples of the exact distribution", "bounded": "an approximation with a rigorous bound on |exact − value| reported beside each value", - "estimate": "a statistical estimate, reported with its standard error", + "estimate": "a statistical estimate, reported with its standard error, or with a bound on its error and the probability that the bound holds", "heuristic": "an approximation reported with the standard estimate of its error (a matrix product state's fidelity estimate), not a bound", }) } @@ -144,6 +158,7 @@ pub fn describe(job_bytes: u64) -> Value { { "method": "stabilizer", "accuracy": "exact; with Pauli noise, counts are noisy samples and expectations estimates", "circuits": "Clifford (rotations by whole quarter turns, controlled phases by whole half turns), optionally with depolarizing, dephasing and readout noise", "max_qubits": STABILIZER_MAX_QUBITS, "answers": ["counts", "expectations"], "options": { "trajectories": "with noise: the shots expectation values are estimated from (default: the shots, at least 10000)" } }, { "method": "pauli", "accuracy": "bounded", "circuits": "any", "max_qubits": PAULI_MAX_QUBITS, "answers": ["expectations"], "options": { "threshold": "coefficients below it are dropped (default 1e-5); the bound covers what was dropped", "max_weight": "Pauli strings heavier than this are dropped", "ladder": "also report the value at up to three thresholds a decade apart above it, to show it settling (default true)", "max_terms": "the most Pauli terms to hold (default: what the job's memory holds); past it the threshold rises, and the bound covers what drops" } }, { "method": "mps", "accuracy": "exact when nothing is truncated, otherwise heuristic", "circuits": "any; best on low-entanglement circuits", "max_qubits": MPS_MAX_QUBITS, "answers": ["counts", "expectations", "amplitudes"], "options": { "max_bond": "the largest bond dimension kept (default 64, at most 256)", "cutoff": "singular values whose squared share is below it are dropped (default 1e-12)" } }, + { "method": "stabilizer_rank", "accuracy": "exact; with terms or epsilon, an estimate with its bound", "circuits": "Clifford+T (t, tdg, and p, rz, rx, ry at odd multiples of π/4, cp at odd multiples of π/2, ccz and ccx), each T gate doubling the sum's terms: the state as a sum of stabilizer states", "max_qubits": STABILIZER_RANK_MAX_QUBITS, "answers": ["amplitudes", "expectations"], "options": { "terms": "the sampled mode: this many branches drawn, seeded, the result an estimate with the bound on its distance from the state that holds with the confidence stated", "epsilon": "the sampled mode with as many branches as that bound needs", "confidence": "the probability the sampled bound holds (default 0.95)" } }, { "method": "tensor_network", "accuracy": "exact", "circuits": "any", "max_qubits": qasm::MAX_QUBITS, "answers": ["amplitudes"], "options": { "path_restarts": "independent contraction-path searches, the cheapest kept (default 8; 1 in a browser tab)" } }, { "method": "cutrank", "accuracy": "exact; single when only a single-precision table fits", "circuits": "a Clifford circuit, then one layer of one-qubit gates at any angles: each qubit's gates from its first non-Clifford one on act on that qubit alone; the cost is set by the state's cut-rank along an order of the qubits, not by their number", "max_qubits": CUTRANK_MAX_QUBITS, "answers": ["counts", "amplitudes"] }, { "method": "cutrank_single", "accuracy": "single", "circuits": "as for cutrank; the table on a GPU, its arithmetic in single precision", "max_qubits": CUTRANK_MAX_QUBITS, "max_cut": gpu_cutrank_max_cut().unwrap_or(0), "available": gpu_cutrank_max_cut().is_ok(), "answers": ["counts", "amplitudes"] }, @@ -700,6 +715,74 @@ fn try_dynamic(method: &str, r: &Request, clifford: &Result, +} + +impl StabilizerRankMode { + fn terms_per_amplitude(&self, t: u32) -> u64 { + self.sampled.map_or(1u64.checked_shl(t).unwrap_or(u64::MAX), |(k, _)| k) + } + + fn terms_per_expectation(&self, t: u32) -> u64 { + self.sampled.map_or(1u64.checked_shl(2 * t).unwrap_or(u64::MAX), |(k, _)| k) + } + + fn terms_said(&self, t: u32, expectations: bool) -> String { + match self.sampled { + Some((k, _)) => format!("{k} branches drawn"), + None if expectations => format!("4^{t} branches for an expectation value"), + None => format!("2^{t} branches"), + } + } +} + +/// The mode a `stabilizer_rank` job asks for: `terms` or `epsilon` (with +/// `confidence`, default 0.95) for the sampled mode, otherwise the exact sum. +pub fn stabilizer_rank_mode(r: &Request, t: u32) -> Result { + let confidence = r.options.get("confidence").and_then(Value::as_f64).unwrap_or(0.95); + if !(confidence > 0.0 && confidence < 1.0) { + return Err(tag(refusal::BAD_FIELD, "options.confidence is a probability strictly between 0 and 1")); + } + let delta = 1.0 - confidence; + let terms = match (r.options.get("terms").and_then(Value::as_u64), r.options.get("epsilon").and_then(Value::as_f64)) { + (Some(_), Some(_)) => return Err(tag(refusal::BAD_FIELD, "give options.terms or options.epsilon, not both")), + (Some(k), None) => k, + (None, Some(e)) if e > 0.0 && e.is_finite() => { + let k = crate::quantum_stabrank::terms_for(t, e, delta); + if k > STABILIZER_RANK_MAX_TERMS as f64 { + return Err(format!("a bound of {e} at confidence {confidence} with {t} T gates needs {k} branches, more than {STABILIZER_RANK_MAX_TERMS}")); + } + k.max(1.0) as u64 + } + (None, Some(_)) => return Err(tag(refusal::BAD_FIELD, "options.epsilon is a positive number")), + (None, None) => return Ok(StabilizerRankMode { sampled: None }), + }; + if terms == 0 || terms > STABILIZER_RANK_MAX_TERMS { + return Err(tag(refusal::BAD_FIELD, format!("options.terms is 1 to {STABILIZER_RANK_MAX_TERMS}"))); + } + Ok(StabilizerRankMode { sampled: Some((terms, delta)) }) +} + +/// A `stabilizer_rank` job's work, in tableau word operations: for each +/// branch, its gates (a pass over a qubit's run of rows each, a reduction for +/// each Hadamard) and the reduction that reads its amplitudes; amplitudes' +/// branches once, each expectation value's of its own. +pub fn stabilizer_rank_work(c: &crate::quantum_stabrank::CliffordT, amplitude_terms: u64, expectation_terms: u64, amplitudes: u64, observables: u64) -> u64 { + use crate::quantum_tableau::Clifford; + let nn = c.n as u64; + let words = nn.div_ceil(64).max(1); + let reduction = (nn * nn * words).max(1); + let hs = c.gates.iter().filter(|g| matches!(g, crate::quantum_stabrank::CtGate::Clifford(Clifford::H(_) | Clifford::SX(_) | Clifford::SXdg(_)))).count() as u64; + let per = (hs + 1).saturating_mul(reduction) + c.gates.len() as u64 * 2 * words + amplitudes * nn * words; + let a = if amplitudes > 0 { amplitude_terms.saturating_mul(per) } else { 0 }; + let e = observables.saturating_mul(expectation_terms).saturating_mul(per.saturating_mul(2)); + a.saturating_add(e) +} + fn try_method(method: &str, r: &Request, dyadic: &Result, clifford: &Result, String>, cap: u64) -> Result { let n = r.program.n_qubits; let gates = r.program.ops.len() as u64; @@ -849,6 +932,30 @@ fn try_method(method: &str, r: &Request, dyadic: &Result { + if counts { + return Err("stabilizer_rank answers amplitudes and expectation values".into()); + } + let c = r.program.clifford_t().map_err(|e| format!("stabilizer_rank needs a Clifford+T circuit: {e}"))?; + if n > STABILIZER_RANK_MAX_QUBITS { + return Err(format!("stabilizer_rank holds at most {STABILIZER_RANK_MAX_QUBITS} qubits")); + } + let t = c.t_count(); + let mode = stabilizer_rank_mode(r, t)?; + let work = stabilizer_rank_work(&c, mode.terms_per_amplitude(t), mode.terms_per_expectation(t), r.amplitudes.len() as u64, r.observables.len() as u64); + if work > STABILIZER_RANK_MAX_WORK { + let hint = if mode.sampled.is_none() { "; give options.terms or options.epsilon for the sampled mode, an estimate with its bound" } else { "; ask for fewer terms" }; + return Err(format!("{t} T gates: {} is more work than one job may take ({work} tableau word operations, at most {STABILIZER_RANK_MAX_WORK}){hint}", mode.terms_said(t, wants_expectations))); + } + // A tableau for each branch walked at once, about n² bits each. + let nn = n as u64; + let memory = 64 * MIB + 32 * (nn * nn / 2 + 4096) + (r.amplitudes.len() as u64 + 1) * 64 * nn; + let said = match mode.sampled { + None => format!("Clifford+T circuit with {t} T gates on {n} qubits: the exact sum of its stabilizer branches"), + Some((terms, delta)) => format!("Clifford+T circuit with {t} T gates on {n} qubits: {terms} of its stabilizer branches drawn, the bound holding with probability {}", 1.0 - delta), + }; + Ok(plan(memory, work, said)) + } "tensor_network" => { if !wants_amplitudes || counts || wants_expectations { return Err("tensor_network answers amplitudes only".into()); @@ -987,9 +1094,9 @@ fn choose(r: &Request, job_bytes: u64) -> Result { } else if r.shots > 0 { &["stabilizer", "exact", "statevector", "statevector_single", "cutrank", "mps"] } else if !r.observables.is_empty() && r.amplitudes.is_empty() { - &["stabilizer", "exact", "statevector", "statevector_single", "pauli", "mps"] + &["stabilizer", "exact", "statevector", "statevector_single", "stabilizer_rank", "pauli", "mps"] } else { - &["exact", "statevector", "statevector_single", "cutrank", "tensor_network", "mps"] + &["exact", "statevector", "statevector_single", "cutrank", "stabilizer_rank", "tensor_network", "mps"] }; let mut refusals = Vec::new(); for m in order { diff --git a/wai/wai-quantum/src/engine/guide.rs b/wai/wai-quantum/src/engine/guide.rs index 8684361b3..0f9953738 100644 --- a/wai/wai-quantum/src/engine/guide.rs +++ b/wai/wai-quantum/src/engine/guide.rs @@ -94,7 +94,7 @@ pub const EXAMPLES: &str = "wai-quantum://examples"; pub const VERDICTS: &str = "wai-quantum://docs/verdicts"; /// The order `auto` tries the methods in. -pub const AUTO: &str = "auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen."; +pub const AUTO: &str = "auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, stabilizer_rank, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, stabilizer_rank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen; stabilizer_rank is chosen by its T count, its exact sum taken when its branches are within one job's work."; /// Where the statevector method's state runs, in a paragraph. pub const FABRIC: &str = "The statevector method's state runs where the job's `fabric` says: auto (the default) places a state of 20 qubits or more on the first accelerator member of the fabric found here and certified bit-exact against the CPU (`wai-quantum fabric`, or list_fabric, lists them), and keeps a smaller one on the CPU; cpu, accelerator (any certified accelerator member) or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere."; diff --git a/wai/wai-quantum/src/engine/run.rs b/wai/wai-quantum/src/engine/run.rs index 0227f0a0d..c352b0cef 100644 --- a/wai/wai-quantum/src/engine/run.rs +++ b/wai/wai-quantum/src/engine/run.rs @@ -597,6 +597,58 @@ fn run_job(request: &Value, plan: &Plan, passes: &mut Option) -> Result { + use crate::quantum_stabrank::{amplitudes as exact_sums, exact_scale, sampled, sampled_bound, sampled_scale}; + let c = r.program.clifford_t()?; + let t = c.t_count(); + let mode = catalog::stabilizer_rank_mode(&r, t)?; + let threads = if cfg!(target_arch = "wasm32") { 1 } else { std::thread::available_parallelism().map_or(1, |t| t.get()).min(16) }; + // Every branch, or `terms` drawn: the sums and the scale they are read at. + let sums = |c: &crate::quantum_stabrank::CliffordT, xs: &[Vec], seed: u64| -> Result<(Vec<(f64, f64)>, Option), String> { + let tc = c.t_count(); + match mode.sampled { + None => Ok((exact_sums(c, xs, threads).map_err(|e| e.to_string())?.iter().map(|s| s.value(exact_scale(tc))).collect(), None)), + Some((k, delta)) => Ok((sampled(c, xs, k, seed, threads).map_err(|e| e.to_string())?.iter().map(|s| s.value(sampled_scale(tc, k))).collect(), Some(sampled_bound(tc, k, delta)))), + } + }; + out["accuracy"] = match mode.sampled { + None => json!({ "class": "exact", "t_count": t, "terms": 1u64.checked_shl(t).unwrap_or(u64::MAX), "note": "the state as the exact sum of its stabilizer branches, each T gate a sum of two Clifford gates of equal weight; every term is a whole number of sixteenths of a turn at a power of 1/√2, counted exactly, and the sum is evaluated once in double precision; an expectation value is the amplitude ⟨0|U†PU|0⟩, a sum over twice the T gates" }), + Some((k, delta)) => json!({ "class": "estimate", "t_count": t, "terms": k, "bound": sampled_bound(t, k, delta), "confidence": 1.0 - delta, "note": "the state's stabilizer branches drawn uniformly, seeded, each with its coefficient's phase: an unbiased estimate whose mean squared distance from the state is (sec²(π/8)^t − 1)/terms, so each amplitude is within the bound of the exact one with the probability stated (Markov's inequality), the bound computed from the T count, the terms and the confidence; an expectation value is the amplitude ⟨0|U†PU|0⟩, drawn over twice the T gates, with its own bound" }), + }; + if !r.amplitudes.is_empty() { + let xs: Vec> = r.amplitudes.iter().map(|b| (0..n).map(|q| b.as_bytes()[(n - 1 - q) as usize] == b'1').collect()).collect(); + let (values, bound) = sums(&c, &xs, r.seed)?; + out["amplitudes"] = Value::Array( + r.amplitudes + .iter() + .zip(values) + .map(|(b, (re, im))| { + let mut e = json!({ "bits": b, "re": re, "im": im }); + if let (Some(eps), Some((_, delta))) = (bound, mode.sampled) { + e["bound"] = json!(eps); + e["confidence"] = json!(1.0 - delta); + } + e + }) + .collect(), + ); + } + if !r.observables.is_empty() { + let zero = vec![vec![false; n as usize]]; + let mut entries = Vec::new(); + for (i, (text, coeff, string)) in r.observables.iter().enumerate() { + let w = c.sandwich(string).map_err(|e| e.to_string())?; + let (values, bound) = sums(&w, &zero, r.seed.wrapping_add((i as u64 + 1).wrapping_mul(0x9E37_79B9_7F4A_7C15)))?; + let mut e = json!({ "observable": text, "coeff": coeff, "value": coeff * values[0].0 }); + if let (Some(eps), Some((_, delta))) = (bound, mode.sampled) { + e["bound"] = json!(coeff.abs() * eps); + e["confidence"] = json!(1.0 - delta); + } + entries.push(e); + } + out["expectations"] = Value::Array(entries); + } + } "tensor_network" => { use crate::quantum_tn::{Network, PathOptions, contract_plan, find_path_restarts_seeded, sweep_orders, sweep_path, tensor_places}; // Independent path searches, side by side: the search's cost varies with its @@ -1352,4 +1404,128 @@ mod tests { let p = run_with_provenance(&bell, &catalog::plan(&bell, 1 << 30).unwrap(), "h").unwrap()["provenance"].clone(); assert_eq!((p["compilation"]["asked"].as_bool(), p["compilation"]["status"].as_str()), (Some(false), Some("not-applicable")), "{p}"); } + + /// A random Clifford+T program in the language, with every gate the + /// lowering turns into T gates, its global phases included. + fn clifford_t_program(n: u32, len: usize, seed: u64) -> String { + let mut s = seed; + let mut next = || { + s = s.wrapping_add(0x9E37_79B9_7F4A_7C15); + let mut z = s; + z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9); + z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB); + z ^ (z >> 31) + }; + let mut q = format!("OPENQASM 3.0;\nqubit[{n}] q;\n"); + for _ in 0..len { + let a = (next() % u64::from(n)) as u32; + let b = (a + 1 + (next() % u64::from(n - 1)) as u32) % n; + let c = (0..n).find(|&x| x != a && x != b).unwrap(); + let odd = ["pi/4", "3*pi/4", "-pi/4", "5*pi/4"][(next() % 4) as usize]; + q.push_str(&match next() % 22 { + 0 | 1 => format!("h q[{a}];\n"), + 2 => format!("t q[{a}];\n"), + 3 => format!("tdg q[{a}];\n"), + 4 => format!("s q[{a}];\n"), + 5 => format!("cx q[{a}], q[{b}];\n"), + 6 => format!("cz q[{a}], q[{b}];\n"), + 7 => format!("rz({odd}) q[{a}];\n"), + 8 => format!("rx({odd}) q[{a}];\n"), + 9 => format!("ry({odd}) q[{a}];\n"), + 10 => format!("p({odd}) q[{a}];\n"), + 11 => format!("cp(pi/2) q[{a}], q[{b}];\n"), + 12 => format!("ccx q[{a}], q[{b}], q[{c}];\n"), + 13 => format!("ccz q[{a}], q[{b}], q[{c}];\n"), + 14 => format!("sx q[{a}];\n"), + 15 | 16 => format!("cx q[{b}], q[{a}];\n"), + 17 => format!("swap q[{a}], q[{b}];\n"), + 18 => format!("h q[{b}];\n"), + 19 => format!("y q[{a}];\n"), + _ => format!("rz(pi/2) q[{a}];\n"), + }); + } + q + } + + /// Ground truth first: the stabilizer-rank sum of a program, every + /// amplitude (phase and all) and every expectation value, is the dense + /// state vector's, on every size a test affords; checked amplitude by + /// amplitude and by fidelity. + #[test] + fn the_stabilizer_rank_method_is_the_dense_state_vector() { + let mut cases = 0; + for n in 3..=6u32 { + for seed in 0..10u64 { + let qasm = clifford_t_program(n, 2 * n as usize + 2, seed * 7 + u64::from(n)); + let t = crate::qasm::read(&qasm).unwrap().program.clifford_t().unwrap().t_count(); + // An expectation value sums 4^t branches. + if t > 9 { + continue; + } + let bits: Vec = (0..1u32 << n).map(|x| format!("{x:0w$b}", w = n as usize)).collect(); + let job = |method: &str| json!({ "qasm": qasm, "method": method, "amplitudes": bits, "observables": ["Z0", "X1 Z2", format!("Y{} X0", n - 1)] }); + let sv = run(&job("statevector"), &plan(&job("statevector"), CAP).unwrap()).unwrap(); + let sr_plan = plan(&job("stabilizer_rank"), CAP).unwrap(); + let sr = run(&job("stabilizer_rank"), &sr_plan).unwrap(); + assert_eq!((sr["accuracy"]["class"].as_str(), sr["accuracy"]["t_count"].as_u64()), (Some("exact"), Some(u64::from(t))), "{}", sr["accuracy"]); + let (mut ore, mut oim, mut norm) = (0.0, 0.0, 0.0); + for (a, b) in sv["amplitudes"].as_array().unwrap().iter().zip(sr["amplitudes"].as_array().unwrap()) { + let (ar, ai, br, bi) = (a["re"].as_f64().unwrap(), a["im"].as_f64().unwrap(), b["re"].as_f64().unwrap(), b["im"].as_f64().unwrap()); + assert!((ar - br).abs() < 1e-12 && (ai - bi).abs() < 1e-12, "n={n} seed={seed} {}: {ar} {ai} against {br} {bi}\n{qasm}", a["bits"]); + ore += ar * br + ai * bi; + oim += ar * bi - ai * br; + norm += br * br + bi * bi; + } + assert!(((ore * ore + oim * oim) / norm - 1.0).abs() < 1e-12 && (ore - 1.0).abs() < 1e-12, "n={n} seed={seed}: the fidelity, and the overlap with the phase"); + for (a, b) in sv["expectations"].as_array().unwrap().iter().zip(sr["expectations"].as_array().unwrap()) { + assert!((a["value"].as_f64().unwrap() - b["value"].as_f64().unwrap()).abs() < 1e-12, "n={n} seed={seed} {}", a["observable"]); + } + cases += 1; + } + } + assert!(cases >= 16, "{cases}"); + } + + /// Auto takes the stabilizer-rank sum by its T count, the sampled mode + /// states its bound and confidence, and the method refuses what it does not + /// take. + #[test] + fn auto_chooses_the_stabilizer_rank_sum_by_its_t_count() { + let wide = |ts: usize| { + let mut q = String::from("OPENQASM 3.0;\nqubit[40] q;\nh q;\n"); + for i in 0..ts { + q.push_str(&format!("t q[{}];\ncx q[{}], q[{}];\n", i % 40, i % 40, (i + 7) % 40)); + } + q.push_str("h q;\n"); + json!({ "qasm": q, "amplitudes": ["0".repeat(40)], "observables": [] }) + }; + let p = plan(&wide(6), CAP).unwrap(); + assert_eq!(p.method, "stabilizer_rank", "{}", p.why); + let many = plan(&wide(60), CAP).unwrap(); + assert_eq!(many.method, "tensor_network", "too many T gates for one job's sum: {}", many.why); + assert!(many.why.contains("stabilizer_rank: 60 T gates"), "{}", many.why); + // Expectation values alone, past the dense state vector. + let mut e = wide(4); + e["amplitudes"] = json!([]); + e["observables"] = json!(["Z0 Z7", "X3"]); + assert_eq!(plan(&e, CAP).unwrap().method, "stabilizer_rank"); + // The sampled mode states its bound and confidence, and its schema holds. + let mut s = wide(10); + s["method"] = json!("stabilizer_rank"); + s["options"] = json!({ "terms": 2000, "confidence": 0.9 }); + let out = run(&s, &plan(&s, CAP).unwrap()).unwrap(); + assert_eq!(out["accuracy"]["class"], "estimate"); + let b = out["accuracy"]["bound"].as_f64().unwrap(); + assert!((b - crate::quantum_stabrank::sampled_bound(10, 2000, 0.1)).abs() < 1e-15 && out["amplitudes"][0]["bound"].as_f64() == Some(b), "{out}"); + let errs = crate::engine::schema::Registry::engine().check("job-result.v1.json", &out); + assert!(errs.is_empty(), "{errs:?}"); + // Refusals: counts, a gate past Clifford+T, noise, and options that do not read. + let refuse = |v: Value| plan(&v, CAP).unwrap_err(); + assert!(refuse(json!({ "qasm": "OPENQASM 3.0;\nqubit[2] q;\nt q[0];\n", "method": "stabilizer_rank", "shots": 10 })).contains("amplitudes and expectation values")); + assert!(refuse(json!({ "qasm": "OPENQASM 3.0;\nqubit[2] q;\nrx(0.3) q[0];\n", "method": "stabilizer_rank", "amplitudes": ["00"] })).contains("needs a Clifford+T circuit")); + assert!(refuse(json!({ "qasm": "OPENQASM 3.0;\nqubit[2] q;\nt q[0];\n", "method": "stabilizer_rank", "amplitudes": ["00"], "noise": { "dephasing": 0.01 } })).contains("does not model noise")); + assert!(refuse(json!({ "qasm": "OPENQASM 3.0;\nqubit[2] q;\nt q[0];\n", "method": "stabilizer_rank", "amplitudes": ["00"], "options": { "terms": 10, "epsilon": 0.1 } })).ends_with("[J003]")); + let fine = json!({ "qasm": "OPENQASM 3.0;\nqubit[2] q;\nt q[0];\n", "method": "stabilizer_rank", "amplitudes": ["00"], "options": { "epsilon": 0.1 } }); + assert!(plan(&fine, CAP).unwrap().why.contains("drawn")); + } } diff --git a/wai/wai-quantum/src/lib.rs b/wai/wai-quantum/src/lib.rs index 16cca6176..007851d9e 100644 --- a/wai/wai-quantum/src/lib.rs +++ b/wai/wai-quantum/src/lib.rs @@ -281,6 +281,9 @@ pub mod quantum_receipt; pub mod quantum_stabilizer; #[cfg(feature = "quantum_tableau")] pub mod quantum_tableau; +// Clifford+T circuits as sums of stabilizer states, on the phased tableau. +#[cfg(feature = "quantum_tableau")] +pub mod quantum_stabrank; #[cfg(feature = "quantum_cutrank")] pub mod quantum_cutrank; #[cfg(feature = "quantum_cutrank_metal")] diff --git a/wai/wai-quantum/src/qasm.rs b/wai/wai-quantum/src/qasm.rs index 67765886a..a789a9eb0 100644 --- a/wai/wai-quantum/src/qasm.rs +++ b/wai/wai-quantum/src/qasm.rs @@ -1252,6 +1252,95 @@ impl Program { Ok((bulk, tail.into_iter().map(|t| t.unwrap_or([one, zero, zero, one])).collect(), complex(phase.re / m, phase.im / m))) } + /// The circuit as Clifford gates and T and T† gates, exactly, with its + /// global phase: the input of the `stabilizer_rank` method. A Clifford op + /// lowers as [`Program::clifford`] lowers it, its phase read off its + /// matrix; `t`, `tdg`, `p`, `rz`, `rx` and `ry` at odd multiples of π/4, + /// `cp` at odd multiples of π/2, `ccz` and `ccx` (seven T gates each) lower + /// to T gates. Refused for any other gate, and for a global phase that is + /// not a whole number of sixteenths of a turn. + #[cfg(feature = "quantum_qasm")] + pub fn clifford_t(&self) -> Result { + use crate::quantum_stabrank::{CliffordT, CtGate}; + use Kind::*; + let mut gates = Vec::new(); + let mut phase: i64 = 0; + // P(mπ/4) for odd m: S^((m−1)/2) then T. + let eighth_z = |gates: &mut Vec, q: u32, m: i64| { + let m = m.rem_euclid(8); + let mut quarter = Vec::new(); + quarter_z(&mut quarter, q, ((m - 1) / 2) as u32); + gates.extend(quarter.into_iter().map(CtGate::Clifford)); + gates.push(CtGate::T(q)); + }; + // An odd number of eighth turns (π/4) within 1e-12, or none. + let odd_eighth = |theta: f64| -> Option { + let x = theta / std::f64::consts::FRAC_PI_4; + let m = x.round(); + ((x - m).abs() <= 1e-12 && (m as i64).rem_euclid(2) == 1).then_some(m as i64) + }; + for op in &self.ops { + let q = &op.qubits; + if let Ok((cl, _)) = Self::lower_clifford(std::slice::from_ref(op)) { + let ph = lowering_phase(op, &cl); + let x = ph.im.atan2(ph.re) / (std::f64::consts::PI / 8.0); + let j = x.round(); + if (x - j).abs() > 1e-9 || (ph.re.hypot(ph.im) - 1.0).abs() > 1e-9 { + return Err(format!("{:?}: its phase is not a whole number of sixteenths of a turn", op.kind)); + } + phase += j as i64; + gates.extend(cl.into_iter().map(CtGate::Clifford)); + continue; + } + let not = || format!("{:?}{} is not a Clifford+T gate", op.kind, if op.params.is_empty() { String::new() } else { format!("({})", op.params.iter().map(|x| format!("{x}")).collect::>().join(", ")) }); + match op.kind { + T => gates.push(CtGate::T(q[0])), + Tdg => gates.push(CtGate::Tdg(q[0])), + P => eighth_z(&mut gates, q[0], odd_eighth(op.params[0]).ok_or_else(not)?), + // Rz(θ) = e^{−iθ/2} P(θ); Rx and Ry are Rz between Cliffords. + Rz | Rx | Ry => { + let m = odd_eighth(op.params[0]).ok_or_else(not)?; + let (pre, post): (Vec, Vec) = match op.kind { + Rx => (vec![Clifford::H(q[0])], vec![Clifford::H(q[0])]), + Ry => (vec![Clifford::Sdg(q[0]), Clifford::H(q[0])], vec![Clifford::H(q[0]), Clifford::S(q[0])]), + _ => (vec![], vec![]), + }; + gates.extend(pre.into_iter().map(CtGate::Clifford)); + eighth_z(&mut gates, q[0], m); + gates.extend(post.into_iter().map(CtGate::Clifford)); + phase -= m; + } + // CP(φ) = P(φ/2)_a P(φ/2)_b CX P(−φ/2)_b CX, φ/2 an odd eighth turn. + Cp => { + let x = op.params[0] / std::f64::consts::FRAC_PI_2; + let m = x.round(); + if (x - m).abs() > 1e-12 || (m as i64).rem_euclid(2) != 1 { + return Err(not()); + } + let (a, b, m) = (q[0], q[1], m as i64); + eighth_z(&mut gates, a, m); + eighth_z(&mut gates, b, m); + gates.push(CtGate::Clifford(Clifford::CX(a, b))); + eighth_z(&mut gates, b, -m); + gates.push(CtGate::Clifford(Clifford::CX(a, b))); + } + Ccz | Ccx => { + let (a, b, c) = (q[0], q[1], q[2]); + let cx = |x: u32, y: u32| CtGate::Clifford(Clifford::CX(x, y)); + if op.kind == Ccx { + gates.push(CtGate::Clifford(Clifford::H(c))); + } + gates.extend([cx(b, c), CtGate::Tdg(c), cx(a, c), CtGate::T(c), cx(b, c), CtGate::Tdg(c), cx(a, c), CtGate::T(b), CtGate::T(c), cx(a, b), CtGate::T(a), CtGate::Tdg(b), cx(a, b)]); + if op.kind == Ccx { + gates.push(CtGate::Clifford(Clifford::H(c))); + } + } + _ => return Err(not()), + } + } + Ok(CliffordT { n: self.n_qubits, gates, phase: phase.rem_euclid(16) as u8 }) + } + /// The Clifford lowering, and where each op's gates end in it. #[cfg(feature = "quantum_qasm")] fn clifford_bounds(&self) -> Result<(Vec, Vec), String> { diff --git a/wai/wai-quantum/src/quantum_stabrank.rs b/wai/wai-quantum/src/quantum_stabrank.rs new file mode 100644 index 000000000..6846d70c0 --- /dev/null +++ b/wai/wai-quantum/src/quantum_stabrank.rs @@ -0,0 +1,644 @@ +//! Clifford+T circuits as sums of stabilizer states — `wai.quantum.stabrank`. +//! +//! A T gate is a sum of two Clifford gates, +//! `T = (e^{iπ/8} I + e^{−iπ/8} S) / (2 cos π/8)`, and `T†` is its conjugate, +//! `(e^{−iπ/8} I + e^{iπ/8} S†) / (2 cos π/8)`. A circuit with `t` of them +//! is therefore a sum of `2^t` Clifford circuits, each a stabilizer state +//! whose every amplitude the phased tableau gives exactly +//! ([`PhasedTableau::amplitudes`]). Both coefficients of a T gate have the same +//! magnitude, `1 / (2 cos π/8)`, the least the stabilizer extent of a T gate +//! allows, so every branch weighs the same. +//! +//! - **Exact** ([`amplitudes`]). Every branch, walked depth first so branches +//! share the Clifford gates before their first difference. Each term is +//! `2^{−k/2} e^{iπj/8}`, held as a whole-number count per `(k, j)` +//! ([`ExactSum`]), so the sum is the same however the branches are split +//! between threads, and it is evaluated once, in a fixed order, in double +//! precision: no approximation beyond that rounding. The terms grow as `2^t`. +//! - **Expectation values** ([`CliffordT::sandwich`]). `⟨ψ|P|ψ⟩` is the +//! amplitude `⟨0|U†PU|0⟩` of one circuit with twice the T gates, so its terms +//! grow as `4^t`. +//! - **Sampled** ([`sampled`]). `K` branches drawn uniformly, each with its +//! coefficient's phase, scaled by `‖c‖₁ / K` with `‖c‖₁ = sec(π/8)^t`: an +//! unbiased estimate `ψ̃` of the state whose mean squared distance is exactly +//! `(‖c‖₁² − 1) / K` (the sparsification lemma). By Markov's inequality, +//! `‖ψ̃ − ψ‖ ≤ ε = sqrt((sec²(π/8)^t − 1) / (K δ))` with probability at least +//! `1 − δ` over the draw ([`sampled_bound`]); every amplitude, and every +//! amplitude of the sandwich (an expectation value), is within `ε` of the +//! exact one with that probability. The bound is computed from `t`, `K` and +//! `δ`, never from the result. The draw is seeded, each term from a stream of +//! its own, so the same seed gives the same bits at any thread count. +//! +//! # Checked +//! +//! Against the dense state vector of the same program, on random Clifford+T +//! circuits up to 7 qubits and 10 T gates: every amplitude, phase and all, +//! within `10⁻¹²`, the fidelity within `10⁻¹²` of 1, and every expectation +//! value within `10⁻¹²`. The sampled mode's bound holds in at least the +//! fraction `1 − δ` of seeds, measured on the whole state. + +use crate::quantum_tableau::{Clifford, PhasedTableau, TableauError}; + +/// `1 / (2 cos π/8)`: the magnitude of each coefficient of a T gate, correctly +/// rounded. +pub const T_COEFFICIENT: f64 = 0.541196100146197; + +/// `sec(π/8)`: `‖c‖₁` of one T gate's two coefficients, correctly rounded. +pub const SEC_PI_8: f64 = 1.082392200292394; + +/// `sec²(π/8) = 4 − 2√2`: the stabilizer extent of a T gate, correctly rounded. +pub const SEC2_PI_8: f64 = 1.17157287525381; + +/// `(cos πj/8, sin πj/8)` for `j` in `0..8`, correctly rounded. +const TURN16: [(f64, f64); 8] = [ + (1.0, 0.0), + (0.9238795325112867, 0.3826834323650898), + (std::f64::consts::FRAC_1_SQRT_2, std::f64::consts::FRAC_1_SQRT_2), + (0.3826834323650898, 0.9238795325112867), + (0.0, 1.0), + (-0.3826834323650898, 0.9238795325112867), + (-std::f64::consts::FRAC_1_SQRT_2, std::f64::consts::FRAC_1_SQRT_2), + (-0.9238795325112867, 0.3826834323650898), +]; + +/// One gate of a Clifford+T circuit. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum CtGate { + Clifford(Clifford), + T(u32), + Tdg(u32), +} + +/// A Clifford+T circuit on `n` qubits from `|0…0⟩`, its matrix the product of +/// its gates times `e^{iπ·phase/8}`. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct CliffordT { + pub n: u32, + pub gates: Vec, + /// The global phase, in sixteenths of a turn. + pub phase: u8, +} + +/// Why a Clifford+T sum could not be taken. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum StabrankError { + Tableau(TableauError), + /// A Pauli factor that is not `X`, `Y`, `Z` or `I`, or a qubit named + /// twice or out of range. + BadPauli(String), +} + +impl std::fmt::Display for StabrankError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + StabrankError::Tableau(e) => write!(f, "{e}"), + StabrankError::BadPauli(p) => write!(f, "{p}: not a Pauli string of this circuit"), + } + } +} + +impl std::error::Error for StabrankError {} + +impl From for StabrankError { + fn from(e: TableauError) -> StabrankError { + StabrankError::Tableau(e) + } +} + +fn inverse(c: Clifford) -> Clifford { + match c { + Clifford::S(q) => Clifford::Sdg(q), + Clifford::Sdg(q) => Clifford::S(q), + Clifford::SX(q) => Clifford::SXdg(q), + Clifford::SXdg(q) => Clifford::SX(q), + other => other, + } +} + +impl CliffordT { + /// The T and T† gates. + pub fn t_count(&self) -> u32 { + self.gates.iter().filter(|g| !matches!(g, CtGate::Clifford(_))).count() as u32 + } + + /// The inverse: each gate inverted, in reverse order, the phase negated. + pub fn inverse(&self) -> CliffordT { + let gates = self + .gates + .iter() + .rev() + .map(|&g| match g { + CtGate::Clifford(c) => CtGate::Clifford(inverse(c)), + CtGate::T(q) => CtGate::Tdg(q), + CtGate::Tdg(q) => CtGate::T(q), + }) + .collect(); + CliffordT { n: self.n, gates, phase: (16 - self.phase % 16) % 16 } + } + + /// `U† P U` as one circuit, for the Pauli string `P` (`(qubit, 'X'|'Y'|'Z'|'I')`): + /// its amplitude at `|0…0⟩` is `⟨ψ|P|ψ⟩`, with twice the T gates. + pub fn sandwich(&self, pauli: &[(u32, char)]) -> Result { + let mut gates = self.gates.clone(); + let mut seen = std::collections::BTreeSet::new(); + for &(q, p) in pauli { + if q >= self.n || !seen.insert(q) { + return Err(StabrankError::BadPauli(format!("{p}{q}"))); + } + match p.to_ascii_uppercase() { + 'X' => gates.push(CtGate::Clifford(Clifford::X(q))), + 'Y' => gates.push(CtGate::Clifford(Clifford::Y(q))), + 'Z' => gates.push(CtGate::Clifford(Clifford::Z(q))), + 'I' => {} + other => return Err(StabrankError::BadPauli(format!("{other}{q}"))), + } + } + gates.extend(self.inverse().gates); + Ok(CliffordT { n: self.n, gates, phase: 0 }) + } +} + +/// A sum of terms `2^{−k/2} e^{iπj/8}`, held as whole numbers: entry `[k][j]` +/// counts the terms of magnitude `2^{−k/2}` at `j` sixteenths of a turn, a +/// term at `j + 8` counted as minus one at `j`. Sums merge by addition, so a +/// sum is the same however its terms were split. +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct ExactSum { + counts: Vec<[i64; 8]>, +} + +impl ExactSum { + /// Adds `2^{−k/2} e^{iπ·sixteenth/8}`. + pub fn add(&mut self, k: u32, sixteenth: u8) { + let k = k as usize; + if self.counts.len() <= k { + self.counts.resize(k + 1, [0; 8]); + } + let j = sixteenth % 16; + if j < 8 { + self.counts[k][j as usize] += 1; + } else { + self.counts[k][(j - 8) as usize] -= 1; + } + } + + /// Adds every term of `other`. + pub fn merge(&mut self, other: &ExactSum) { + if self.counts.len() < other.counts.len() { + self.counts.resize(other.counts.len(), [0; 8]); + } + for (a, b) in self.counts.iter_mut().zip(&other.counts) { + for j in 0..8 { + a[j] += b[j]; + } + } + } + + /// The terms counted, net of cancellations. + pub fn is_zero(&self) -> bool { + self.counts.iter().all(|c| c.iter().all(|&x| x == 0)) + } + + /// The sum times `scale`, in double precision, its terms added in a fixed + /// order: the same bits on every machine. + pub fn value(&self, scale: f64) -> (f64, f64) { + let (mut re, mut im) = (0.0f64, 0.0f64); + for (k, c) in self.counts.iter().enumerate() { + let (mut kr, mut ki) = (0.0f64, 0.0f64); + for (j, &n) in c.iter().enumerate() { + kr += n as f64 * TURN16[j].0; + ki += n as f64 * TURN16[j].1; + } + let m = half_root_power(k as u32); + re += m * kr; + im += m * ki; + } + (re * scale, im * scale) + } +} + +/// `2^{−k/2}`, exactly as a power of two times `1/√2` for odd `k`. +fn half_root_power(k: u32) -> f64 { + let mut m = if k % 2 == 1 { std::f64::consts::FRAC_1_SQRT_2 } else { 1.0 }; + for _ in 0..k / 2 { + m *= 0.5; + } + m +} + +/// `x` multiplied by itself `t` times, one multiply at a time: the same bits +/// on every machine. +fn power(x: f64, t: u32) -> f64 { + let mut p = 1.0f64; + for _ in 0..t { + p *= x; + } + p +} + +/// The scale an exact sum of a circuit with `t` T gates is evaluated at. +pub fn exact_scale(t: u32) -> f64 { + power(T_COEFFICIENT, t) +} + +/// The scale a sampled sum of `terms` branches of a circuit with `t` T gates +/// is evaluated at: `sec(π/8)^t / terms`. +pub fn sampled_scale(t: u32, terms: u64) -> f64 { + power(SEC_PI_8, t) / terms as f64 +} + +/// The bound the sampled mode states: `‖ψ̃ − ψ‖ ≤ sqrt((sec²(π/8)^t − 1) / (terms · δ))` +/// with probability at least `1 − δ`, for a normalised `ψ`. +pub fn sampled_bound(t: u32, terms: u64, delta: f64) -> f64 { + ((power(SEC2_PI_8, t) - 1.0).max(0.0) / (terms.max(1) as f64 * delta)).sqrt() +} + +/// The terms the sampled mode needs for the bound `epsilon` at `1 − δ`. +pub fn terms_for(t: u32, epsilon: f64, delta: f64) -> f64 { + ((power(SEC2_PI_8, t) - 1.0).max(0.0) / (epsilon * epsilon * delta)).ceil() +} + +/// One branch point: the Clifford gate the S branch applies, and the +/// sixteenths each branch's coefficient turns by. +fn branch(g: CtGate) -> Option<(Clifford, u8, u8)> { + match g { + CtGate::Clifford(_) => None, + CtGate::T(q) => Some((Clifford::S(q), 1, 15)), + CtGate::Tdg(q) => Some((Clifford::Sdg(q), 15, 1)), + } +} + +/// A leaf: its amplitudes at `xs` added to `sums`. +fn leaf(st: &PhasedTableau, phase: u8, xs: &[Vec], sums: &mut [ExactSum]) -> Result<(), TableauError> { + for (s, a) in sums.iter_mut().zip(st.amplitudes(xs)?) { + if let Some((k, m)) = a { + s.add(k, (phase + 2 * m) % 16); + } + } + Ok(()) +} + +/// Every branch below `(st, pos, phase)`, depth first. +fn walk(c: &CliffordT, mut st: PhasedTableau, mut pos: usize, mut phase: u8, xs: &[Vec], sums: &mut [ExactSum]) -> Result<(), TableauError> { + while pos < c.gates.len() { + match branch(c.gates[pos]) { + None => { + if let CtGate::Clifford(g) = c.gates[pos] { + st.apply(g)?; + } + } + Some((s, keep, turn)) => { + walk(c, st.clone(), pos + 1, (phase + keep) % 16, xs, sums)?; + st.apply(s)?; + phase = (phase + turn) % 16; + } + } + pos += 1; + } + leaf(&st, phase, xs, sums) +} + +/// The branches down to the first `depth` branch points, as starting points +/// for [`walk`]: each a state, the gate it stops at, and its phase. +fn prefixes(c: &CliffordT, depth: u32) -> Result, TableauError> { + let mut out = vec![(PhasedTableau::new(c.n)?, 0usize, c.phase % 16)]; + for _ in 0..depth { + let mut next = Vec::with_capacity(2 * out.len()); + let mut grew = false; + for (mut st, mut pos, phase) in out { + while pos < c.gates.len() && branch(c.gates[pos]).is_none() { + if let CtGate::Clifford(g) = c.gates[pos] { + st.apply(g)?; + } + pos += 1; + } + match c.gates.get(pos).and_then(|&g| branch(g)) { + Some((s, keep, turn)) => { + let mut other = st.clone(); + next.push((st, pos + 1, (phase + keep) % 16)); + other.apply(s)?; + next.push((other, pos + 1, (phase + turn) % 16)); + grew = true; + } + None => next.push((st, pos, phase)), + } + } + out = next; + if !grew { + break; + } + } + Ok(out) +} + +/// Runs `work(i, sums)` for `i` in `0..tasks` on up to `threads` threads, each +/// with sums of its own for `width` amplitudes, and adds them: the same sums +/// at any thread count. +fn spread(tasks: usize, width: usize, threads: usize, work: &(dyn Fn(usize, &mut [ExactSum]) -> Result<(), TableauError> + Sync)) -> Result, TableauError> { + let threads = if cfg!(target_arch = "wasm32") { 1 } else { threads.clamp(1, tasks.max(1)) }; + let next = std::sync::atomic::AtomicUsize::new(0); + let run = || -> Result, TableauError> { + let mut sums = vec![ExactSum::default(); width]; + loop { + let i = next.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + if i >= tasks { + return Ok(sums); + } + work(i, &mut sums)?; + } + }; + let parts: Vec, TableauError>> = if threads == 1 { + vec![run()] + } else { + std::thread::scope(|s| { + let handles: Vec<_> = (0..threads).map(|_| s.spawn(&run)).collect(); + handles.into_iter().map(|h| h.join().expect("a branch walk does not panic")).collect() + }) + }; + let mut total = vec![ExactSum::default(); width]; + for p in parts { + for (t, s) in total.iter_mut().zip(p?) { + t.merge(&s); + } + } + Ok(total) +} + +/// Every amplitude `⟨x|ψ⟩` of `c` at the basis states `xs` (qubit `q` at +/// index `q`), exactly, as sums of every branch; evaluate each with +/// [`ExactSum::value`] at [`exact_scale`]`(c.t_count())`. `threads` walk the +/// branches side by side; the sums do not depend on it. +pub fn amplitudes(c: &CliffordT, xs: &[Vec], threads: usize) -> Result, StabrankError> { + let depth = if threads > 1 { (threads.next_power_of_two().trailing_zeros() + 3).min(c.t_count()) } else { 0 }; + let starts = prefixes(c, depth)?; + let work = |i: usize, sums: &mut [ExactSum]| -> Result<(), TableauError> { + let (st, pos, phase) = &starts[i]; + walk(c, st.clone(), *pos, *phase, xs, sums) + }; + Ok(spread(starts.len(), xs.len(), threads, &work)?) +} + +fn splitmix(s: &mut u64) -> u64 { + *s = s.wrapping_add(0x9E37_79B9_7F4A_7C15); + let mut z = *s; + z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9); + z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB); + z ^ (z >> 31) +} + +/// `terms` branches of `c` drawn uniformly with `seed`, each from a stream of +/// its own, their amplitudes at `xs` summed exactly; evaluate each with +/// [`ExactSum::value`] at [`sampled_scale`]`(c.t_count(), terms)` for the +/// sampled estimate, whose distance from the state [`sampled_bound`] bounds. +pub fn sampled(c: &CliffordT, xs: &[Vec], terms: u64, seed: u64, threads: usize) -> Result, StabrankError> { + const CHUNK: u64 = 64; + let chunks = terms.div_ceil(CHUNK) as usize; + let work = |i: usize, sums: &mut [ExactSum]| -> Result<(), TableauError> { + for term in (i as u64 * CHUNK)..((i as u64 + 1) * CHUNK).min(terms) { + let mut rng = seed ^ term.wrapping_mul(0xD1B5_4A32_D192_ED03); + let mut bits = 0u64; + let mut left = 0; + let mut st = PhasedTableau::new(c.n)?; + let mut phase = c.phase % 16; + for &g in &c.gates { + match branch(g) { + None => { + if let CtGate::Clifford(g) = g { + st.apply(g)?; + } + } + Some((s, keep, turn)) => { + if left == 0 { + bits = splitmix(&mut rng); + left = 64; + } + let take_s = bits & 1 == 1; + bits >>= 1; + left -= 1; + if take_s { + st.apply(s)?; + phase = (phase + turn) % 16; + } else { + phase = (phase + keep) % 16; + } + } + } + } + leaf(&st, phase, xs, sums)?; + } + Ok(()) + }; + Ok(spread(chunks, xs.len(), threads, &work)?) +} + +#[cfg(all(test, feature = "quantum_sv"))] +mod tests { + use super::*; + use crate::gates::{Gate, complex}; + use crate::quantum_sv::StateVector; + + fn gate(g: CtGate) -> Gate { + let (z, o, i) = (complex(0.0, 0.0), complex(1.0, 0.0), complex(0.0, 1.0)); + match g { + CtGate::T(q) => Gate::t(q), + CtGate::Tdg(q) => Gate { qubits: vec![q], matrix: vec![o, z, z, complex(std::f64::consts::FRAC_1_SQRT_2, -std::f64::consts::FRAC_1_SQRT_2)] }, + CtGate::Clifford(c) => match c { + Clifford::H(q) => Gate::h(q), + Clifford::S(q) => Gate::s(q), + Clifford::Sdg(q) => Gate::sdg(q), + Clifford::X(q) => Gate::x(q), + Clifford::Y(q) => Gate::y(q), + Clifford::Z(q) => Gate::z(q), + Clifford::SX(q) => Gate::sqrt_x(q), + Clifford::SXdg(q) => { + let (a, b) = (complex(0.5, -0.5), complex(0.5, 0.5)); + Gate { qubits: vec![q], matrix: vec![a, b, b, a] } + } + Clifford::CX(c, t) => Gate::cx(c, t), + Clifford::CY(c, t) => Gate { qubits: vec![c, t], matrix: vec![o, z, z, z, z, o, z, z, z, z, z, complex(0.0, -1.0), z, z, i, z] }, + Clifford::CZ(a, b) => Gate::cz(a, b), + Clifford::Swap(a, b) => Gate::swap(a, b), + }, + } + } + + /// A random Clifford+T circuit on `n` qubits with exactly `t` T or T† + /// gates among `len` gates, and a global phase. + fn circuit(n: u32, len: usize, t: u32, seed: u64) -> CliffordT { + let mut s = seed; + let mut gates = Vec::with_capacity(len + t as usize); + let mut placed = 0; + for i in 0..len + t as usize { + let a = (splitmix(&mut s) % u64::from(n)) as u32; + let b = (a + 1 + (splitmix(&mut s) % u64::from(n - 1)) as u32) % n; + let left = len + t as usize - i; + let want_t = (t - placed) as usize; + if want_t > 0 && (splitmix(&mut s) % left as u64) < want_t as u64 { + placed += 1; + gates.push(if splitmix(&mut s) % 2 == 0 { CtGate::T(a) } else { CtGate::Tdg(a) }); + continue; + } + gates.push(CtGate::Clifford(match splitmix(&mut s) % 12 { + 0..=2 => Clifford::H(a), + 3 => Clifford::S(a), + 4 => Clifford::Sdg(a), + 5 => Clifford::SX(a), + 6 => Clifford::X(a), + 7 => Clifford::Y(a), + 8 => Clifford::CX(a, b), + 9 => Clifford::CY(a, b), + 10 => Clifford::CZ(a, b), + _ => Clifford::Swap(a, b), + })); + } + CliffordT { n, gates, phase: (splitmix(&mut s) % 16) as u8 } + } + + fn dense(c: &CliffordT) -> StateVector { + let mut sv = StateVector::zero(c.n).unwrap(); + for &g in &c.gates { + sv.apply(&gate(g)).unwrap(); + } + let (pc, ps) = { + let j = c.phase as usize % 16; + let (a, b) = TURN16[j % 8]; + if j < 8 { (a, b) } else { (-a, -b) } + }; + for x in 0..sv.re.len() { + let (r, i) = (sv.re[x], sv.im[x]); + sv.re[x] = pc * r - ps * i; + sv.im[x] = pc * i + ps * r; + } + sv + } + + fn basis(n: u32) -> Vec> { + (0..1usize << n).map(|i| (0..n).map(|q| i >> (n - 1 - q) & 1 == 1).collect()).collect() + } + + /// Ground truth first: every amplitude of the exact sum, phase and all, is + /// the dense state vector's, on every circuit size a test affords; the + /// fidelity is 1 to `10⁻¹²`; and the sums do not depend on the threads. + #[test] + fn the_exact_sum_is_the_dense_state_amplitude_by_amplitude() { + let mut cases = 0; + for n in 2..=7u32 { + for t in 0..=10u32 { + if n >= 6 && t > 8 { + continue; + } + for seed in 0..3u64 { + let c = circuit(n, 6 * n as usize, t, seed * 1000 + u64::from(n * 31 + t)); + assert_eq!(c.t_count(), t); + let sv = dense(&c); + let xs = basis(n); + let sums = amplitudes(&c, &xs, 1).unwrap(); + let scale = exact_scale(t); + let (mut overlap_re, mut overlap_im, mut norm) = (0.0, 0.0, 0.0); + for (x, s) in sums.iter().enumerate() { + let (re, im) = s.value(scale); + let w = sv.amplitude(x); + assert!((w.re - re).abs() < 1e-12 && (w.im - im).abs() < 1e-12, "n={n} t={t} seed={seed} x={x}: sum {re} {im}, dense {} {}", w.re, w.im); + overlap_re += w.re * re + w.im * im; + overlap_im += w.re * im - w.im * re; + norm += re * re + im * im; + } + let fidelity = (overlap_re * overlap_re + overlap_im * overlap_im) / norm; + assert!((fidelity - 1.0).abs() < 1e-12 && (overlap_re - 1.0).abs() < 1e-12, "n={n} t={t}: fidelity {fidelity}, overlap {overlap_re}"); + if t >= 4 { + assert_eq!(amplitudes(&c, &xs, 8).unwrap(), sums, "the sums do not depend on the threads"); + } + cases += 1; + } + } + } + assert!(cases > 150, "{cases}"); + } + + /// Every expectation value through the sandwich is the dense state's. + #[test] + fn expectation_values_through_the_sandwich_are_the_dense_states() { + for seed in 0..24u64 { + let n = 2 + (seed % 5) as u32; + let t = (seed % 6) as u32; + let c = circuit(n, 5 * n as usize, t, seed ^ 0xabc); + let sv = dense(&c); + let mut s = seed; + for _ in 0..4 { + let p: Vec<(u32, char)> = (0..n).filter_map(|q| match splitmix(&mut s) % 4 { + 0 => None, + 1 => Some((q, 'X')), + 2 => Some((q, 'Y')), + _ => Some((q, 'Z')), + }).collect(); + let w = c.sandwich(&p).unwrap(); + assert_eq!(w.t_count(), 2 * t); + let sum = &litudes(&w, &[vec![false; n as usize]], 2).unwrap()[0]; + let (re, im) = sum.value(exact_scale(w.t_count())); + let want = sv.expectation(&[(1.0, p.clone())]); + assert!((re - want).abs() < 1e-12 && im.abs() < 1e-12, "seed {seed} {p:?}: {re} {im}, dense {want}"); + } + } + let c = circuit(2, 4, 1, 1); + assert!(c.sandwich(&[(2, 'Z')]).is_err() && c.sandwich(&[(0, 'Q')]).is_err() && c.sandwich(&[(0, 'Z'), (0, 'X')]).is_err()); + } + + /// The sampled mode: an unbiased estimate whose distance from the state is + /// within the stated bound in at least the fraction `1 − δ` of seeds, + /// measured on the whole state; and the same bits at any thread count. + #[test] + fn the_sampled_bound_holds_as_often_as_it_says() { + let (n, t, terms, delta) = (5u32, 8u32, 400u64, 0.2); + let c = circuit(n, 30, t, 77); + let sv = dense(&c); + let xs = basis(n); + let bound = sampled_bound(t, terms, delta); + assert!(bound > 0.0 && bound < 1.0, "{bound}"); + let mut within = 0; + let seeds = 40; + let mut mean = vec![(0.0, 0.0); xs.len()]; + for seed in 0..seeds { + let sums = sampled(&c, &xs, terms, seed, 1).unwrap(); + let scale = sampled_scale(t, terms); + let mut dist = 0.0; + for (x, s) in sums.iter().enumerate() { + let (re, im) = s.value(scale); + let w = sv.amplitude(x); + dist += (re - w.re).powi(2) + (im - w.im).powi(2); + mean[x].0 += re / seeds as f64; + mean[x].1 += im / seeds as f64; + } + within += u32::from(dist.sqrt() <= bound); + if seed < 2 { + assert_eq!(sampled(&c, &xs, terms, seed, 8).unwrap(), sums, "the same bits at any thread count"); + } + } + assert!(f64::from(within) >= (1.0 - delta) * seeds as f64, "{within} of {seeds} within {bound}"); + // Unbiased: the mean of the estimates is closer to the state than one estimate's bound. + let err: f64 = mean.iter().enumerate().map(|(x, m)| (m.0 - sv.amplitude(x).re).powi(2) + (m.1 - sv.amplitude(x).im).powi(2)).sum::().sqrt(); + assert!(err < bound / 2.0, "{err} {bound}"); + // The terms for a bound give that bound. + let k = terms_for(t, 0.05, 0.05) as u64; + assert!(sampled_bound(t, k, 0.05) <= 0.05 + 1e-12 && sampled_bound(t, k - 1, 0.05) > 0.05); + assert_eq!(sampled_bound(0, 10, 0.05), 0.0, "a Clifford circuit's one branch is the state"); + } + + #[test] + fn exact_sums_add_in_any_order_and_evaluate_one_way() { + let mut a = ExactSum::default(); + let mut b = ExactSum::default(); + for (k, j) in [(0u32, 0u8), (3, 5), (3, 13), (2, 9), (1, 15)] { + a.add(k, j); + } + for (k, j) in [(1u32, 15u8), (2, 9), (3, 13), (3, 5), (0, 0)] { + b.add(k, j); + } + assert_eq!(a, b); + let mut c = ExactSum::default(); + c.add(2, 3); + c.add(2, 11); + assert!(c.is_zero(), "a term and its negation cancel exactly"); + assert_eq!(half_root_power(4), 0.25); + assert_eq!(power(2.0, 10), 1024.0); + } +} diff --git a/wai/wai-quantum/src/quantum_tableau.rs b/wai/wai-quantum/src/quantum_tableau.rs index 13cfe8e7a..67b973cdc 100644 --- a/wai/wai-quantum/src/quantum_tableau.rs +++ b/wai/wai-quantum/src/quantum_tableau.rs @@ -758,6 +758,64 @@ impl PhasedTableau { &self.t } + /// `⟨x|ψ⟩` for each basis state `x` (qubit `q` at index `q`), exactly: + /// `None` outside the support, otherwise `(k, m)` for `2^{−k/2} e^{iπm/4}`. + /// The stabilizers are reduced on their X parts once; then for each `x`, + /// `d = x ⊕ r` lies in their span exactly when the product `P` of the + /// pivot rows whose pivots `d` sets has X part `d`, and then + /// `⟨x|ψ⟩ = ⟨x|P|ψ⟩ = (−1)^{s + z·r} i^{|d∧z|} ⟨r|ψ⟩` with `P` written as + /// `(−1)^s` times its letters. Refused when an `x` is not `n` bits long. + pub fn amplitudes(&self, xs: &[Vec]) -> Result>, TableauError> { + let n = self.t.n; + if let Some(x) = xs.iter().find(|x| x.len() != n) { + return Err(TableauError::QubitOutOfRange { qubit: x.len() as u32, n: n as u32 }); + } + let mut rows = self.t.rows(n, 2 * n); + let wn = rows.wn; + let mut pivots = Vec::new(); + for q in 0..n { + let k = pivots.len(); + let Some(p) = (k..n).find(|&i| get(rows.xr(i), q)) else { continue }; + rows.swap(k, p); + for i in 0..n { + if i != k && get(rows.xr(i), q) { + rows.mul_into(i, k); + } + } + pivots.push(q); + } + Ok(xs + .iter() + .map(|x| { + let mut d = vec![0u64; wn]; + for (q, &b) in x.iter().enumerate() { + if b != get(&self.r, q) { + set(&mut d, q); + } + } + // Row 0 the product so far (the identity, sign +), row 1 the + // pivot row multiplied in. + let mut acc = Rows::new(2, n); + for (i, &c) in pivots.iter().enumerate() { + if get(&d, c) { + acc.x[wn..].copy_from_slice(rows.xr(i)); + acc.z[wn..].copy_from_slice(rows.zr(i)); + acc.r[1] = rows.r[i]; + acc.mul_into(0, 1); + } + } + if acc.xr(0) != &d[..] { + return None; + } + let z = acc.zr(0); + let parity = z.iter().zip(&self.r).map(|(a, b)| (a & b).count_ones()).sum::() % 2 == 1; + let ys = z.iter().zip(&d).map(|(a, b)| (a & b).count_ones()).sum::() % 4; + let quarter = (2 * u32::from(acc.r[0] ^ parity) + ys) % 4; + Some((self.k, (self.m + 2 * quarter as u8) % 8)) + }) + .collect()) + } + /// The reference basis state (qubit `q` at index `q`) and `⟨r|ψ⟩`. pub fn reference(&self) -> (Vec, (f64, f64)) { let bits = (0..self.t.n).map(|q| get(&self.r, q)).collect(); @@ -1875,4 +1933,38 @@ mod phase_tests { } assert!(checked > 2000); } + + /// Every amplitude, phase and all, is the state vector's: exactly zero + /// outside the support and `2^{−k/2} e^{iπm/4}` within it, over random + /// Clifford circuits and every basis state. + #[test] + fn every_amplitude_is_the_state_vectors() { + let mut checked = 0; + for seed in 0..60u64 { + let n = 2 + (seed % 7) as u32; + let ops = circuit(n, 10 * n as usize + 3, seed ^ 0x5eed); + let t = PhasedTableau::run(n, &ops).unwrap(); + let mut sv = StateVector::zero(n).unwrap(); + for &op in &ops { + sv.apply(&gate(op)).unwrap(); + } + let xs: Vec> = (0..1usize << n).map(|i| (0..n).map(|q| i >> (n - 1 - q) & 1 == 1).collect()).collect(); + for (i, a) in t.amplitudes(&xs).unwrap().into_iter().enumerate() { + let want = sv.amplitude(i); + let (re, im) = match a { + None => (0.0, 0.0), + Some((k, m)) => { + let mag = (-(k as f64) / 2.0).exp2(); + let ang = std::f64::consts::FRAC_PI_4 * f64::from(m); + (mag * ang.cos(), mag * ang.sin()) + } + }; + assert!((want.re - re).abs() < 1e-12 && (want.im - im).abs() < 1e-12, "seed {seed}, basis state {i}: tableau {re} {im}, state vector {} {}", want.re, want.im); + assert_eq!(a.is_none(), want.re.hypot(want.im) < 1e-9, "seed {seed}, basis state {i}: the support"); + checked += 1; + } + } + assert!(checked > 4000, "{checked}"); + assert!(PhasedTableau::new(3).unwrap().amplitudes(&[vec![false; 2]]).is_err()); + } } -- 2.54.0 (Apple Git-157) From 21b9369471964063087ee282e19667804a4b2ea8 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Fri, 30 Oct 2026 12:33:20 -0400 Subject: [PATCH 3/7] wai-quantum: a build without the fabric honours only auto placement, and says so The engine without quantum_fabric (the desktop app, the browser engine, the contract's build) reads every `fabric` and refuses all but auto (J013), with a test of its own; the placement tests that need the fabric are gated on it, and the helpers only the fabric uses are compiled only with it, so those builds carry no dead code. Co-Authored-By: Claude Opus 5.5 --- wai/wai-quantum/src/engine/fabric.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/wai/wai-quantum/src/engine/fabric.rs b/wai/wai-quantum/src/engine/fabric.rs index 9b4cd17ea..787514299 100644 --- a/wai/wai-quantum/src/engine/fabric.rs +++ b/wai/wai-quantum/src/engine/fabric.rs @@ -54,8 +54,10 @@ pub const MAX_PARTITIONS: usize = 64; /// The words `fabric` takes besides a member's id or key. pub const WORDS: [&str; 3] = ["auto", "cpu", "accelerator"]; -/// What a job's `fabric` asks for. +/// What a job's `fabric` asks for. A build without the fabric reads every +/// ask and honours only `auto`. #[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(not(feature = "quantum_fabric"), allow(dead_code))] pub(crate) enum Ask { Auto, Cpu, @@ -64,6 +66,7 @@ pub(crate) enum Ask { Split(Vec), } +#[cfg(feature = "quantum_fabric")] impl Ask { /// The ask as the job gave it, for the receipt. fn json(&self) -> Value { @@ -159,10 +162,12 @@ fn cpu_detail(job_bytes: u64) -> Value { } /// The energy a member's run carries: none is metered here. +#[cfg(feature = "quantum_fabric")] fn unmetered() -> Value { json!({ "unmetered": "no meter brackets a member's run in the engine: the job's own energy is its host process's, not the device's" }) } +#[cfg(feature = "quantum_fabric")] fn hex(b: &[u8]) -> String { b.iter().map(|x| format!("{x:02x}")).collect() } @@ -676,6 +681,7 @@ mod tests { } /// The answers: the result without where it ran and how long it took. + #[cfg(feature = "quantum_fabric")] fn answers(out: &Value) -> Vec { let mut o = out.clone(); for k in ["fabric", "elapsed_ms"] { @@ -688,6 +694,7 @@ mod tests { /// no `fabric` in its result and none in its plan's reasons. A job that /// asks for the CPU, or for partitions on the CPU, has the same answers /// byte for byte, and its result names where its state ran. + #[cfg(feature = "quantum_fabric")] #[test] fn a_placement_changes_where_the_state_runs_and_not_a_byte_of_the_answers() { for n in [6u32, 9] { @@ -722,6 +729,7 @@ mod tests { assert_eq!(answers(&fine), answers(&run(&job(6, json!({ "options": { "fusion": 2 } }))).unwrap())); } + #[cfg(feature = "quantum_fabric")] #[test] fn a_placement_this_host_cannot_honour_is_refused_never_made_elsewhere() { let code = |v: Value| run(&v).map(|_| ()).unwrap_err(); @@ -757,6 +765,7 @@ mod tests { /// The result that names where its state ran follows the job result's /// schema, read strictly, and its provenance names the members. + #[cfg(feature = "quantum_fabric")] #[test] fn a_placed_result_and_its_provenance_follow_their_schemas() { let r = super::super::schema::Registry::engine(); @@ -777,6 +786,20 @@ mod tests { assert_eq!(listed["members"][0]["key"], "cpu"); } + /// A build without the fabric runs every job as it always did, and + /// refuses any placement it was asked for. + #[cfg(not(feature = "quantum_fabric"))] + #[test] + fn without_the_fabric_only_auto_is_honoured() { + assert!(run(&job(6, json!({}))).unwrap().get("fabric").is_none()); + assert!(run(&job(6, json!({ "fabric": "auto" }))).is_ok()); + for f in [json!("cpu"), json!("accelerator"), json!(["cpu", "cpu"])] { + assert!(run(&job(6, json!({ "fabric": f }))).unwrap_err().ends_with("[J013]")); + } + assert_eq!(list(CAP)["members"][0]["key"], "cpu"); + } + + #[cfg(feature = "quantum_fabric")] fn backends_reached() -> Vec { list(CAP)["backends"].as_array().into_iter().flatten().filter_map(|b| b.as_str().map(str::to_string)).collect() } -- 2.54.0 (Apple Git-157) From 780b0526ce5fa54ab6770f7a1d0604052aeb8843 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Fri, 30 Oct 2026 14:29:36 -0400 Subject: [PATCH 4/7] wai-quantum: auto keeps the state vector on the CPU until a member is measured faster With one launch per gate and the state copied to the device and back, a whole job measured about as fast, or slower on the GPU, between 18 and 22 qubits on the fleet's GPUs (22 qubits on the laptop GPU: 159 ms on the CPU, 202 ms placed). A planner must not route by default to a path that is not better, so `auto` now places on the CPU on every host and looks for no member: a job that does not ask runs as it always did, its result unnamed. A member runs a job only when the job asks: `accelerator` takes the first certified member that holds the state, and one that fails during the run hands the job to the next, the receipt listing each that failed (`fell_back_from`, now a list, each with how it failed); when every one fails the job is refused (J013). A member named by id or key is alone. Discovery, certification, the receipt's fabric block, the split and `wai-quantum fabric` are as they were; `fabric_members` states `auto` instead of a threshold. A test with stand-in devices holds the fall-back to the CPU's bits and to the schema. The hardware legs ask for `accelerator` and check that auto names nothing; both replayed on jetson-hub and framework-128gb. Docs, help, both MCP servers' descriptions, the guide and the changelog say so; agent docs re-blessed. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/wai-quantum-cuda.yml | 8 +- .github/workflows/wai-quantum-hip.yml | 8 +- wai/CHANGELOG.md | 12 +- wai/wai-quantum-cli/README.md | 2 +- wai/wai-quantum-cli/README.zh-CN.md | 2 +- wai/wai-quantum-cli/docs/llms-full.txt | 51 +- wai/wai-quantum-cli/docs/local-mcp.json | 853 +++++++------- wai/wai-quantum-cli/docs/service-mcp.json | 1130 ++++++++++--------- wai/wai-quantum-cli/src/main.rs | 4 +- wai/wai-quantum-cli/src/mcp.rs | 2 +- wai/wai-quantum-service/src/mcp.rs | 2 +- wai/wai-quantum/README.md | 16 +- wai/wai-quantum/README.zh-CN.md | 2 +- wai/wai-quantum/schemas/job-request.v1.json | 2 +- wai/wai-quantum/schemas/job-result.v1.json | 13 +- wai/wai-quantum/schemas/tools.v1.json | 7 +- wai/wai-quantum/src/engine/fabric.rs | 143 ++- wai/wai-quantum/src/engine/guide.rs | 2 +- wai/wai-quantum/tests/fabric_placement.rs | 34 +- 19 files changed, 1284 insertions(+), 1009 deletions(-) diff --git a/.github/workflows/wai-quantum-cuda.yml b/.github/workflows/wai-quantum-cuda.yml index 0218f7da7..76f291f16 100644 --- a/.github/workflows/wai-quantum-cuda.yml +++ b/.github/workflows/wai-quantum-cuda.yml @@ -14,8 +14,9 @@ name: wai-quantum CUDA member # CPU's bits on its pinned corpus and at 16 and 20 qubits, every state-vector # mutant caught; and jobs placed on the fabric's members found there (the GPU # by CUDA and by OpenCL, the CPU by OpenCL) must give the CPU's answers byte -# for byte, alone and with one state split four ways over them and the CPU -# reference, a state past a member refused. +# for byte, asked for by key and by `accelerator`, alone and with one state +# split four ways over them and the CPU reference, a state past a member +# refused, and auto keeping every state on the CPU. # - cuda-absent (a container with no GPU and no CUDA libraries): the same build # finds no member and says why, rather than failing; the device tests run over # no member with the declaration `none`; and placement with no device, the @@ -164,7 +165,8 @@ jobs: grep -q "^fabric refused: key=$key " "$report" || { echo "::error::$key: a state past what it holds was not refused"; exit 1; } done grep -qx "fabric split: ${split//,/+} over 14 and 19 qubits gives the CPU's answers byte for byte" "$report" || { echo "::error::the state split over the devices is not the CPU's"; exit 1; } - grep -q "^fabric auto: .* the CPU's answers byte for byte" "$report" || { echo "::error::auto placed no wide state"; exit 1; } + grep -qx "fabric auto: every state on the CPU, its result unnamed" "$report" || { echo "::error::auto placed a state on a member"; exit 1; } + grep -q "^fabric accelerator: .* the CPU's answers byte for byte" "$report" || { echo "::error::an accelerator request placed no state"; exit 1; } cuda-absent: name: member · CUDA absent (linux) diff --git a/.github/workflows/wai-quantum-hip.yml b/.github/workflows/wai-quantum-hip.yml index 0ce0c74e1..7bea24f53 100644 --- a/.github/workflows/wai-quantum-hip.yml +++ b/.github/workflows/wai-quantum-hip.yml @@ -14,8 +14,9 @@ name: wai-quantum HIP member # and the dense f64 state vector must come back with the CPU's bits on its # pinned corpus and at 16 and 20 qubits, every state-vector mutant caught; # and jobs placed on the fabric's members found there (the GPU by HIP and by -# OpenCL) must give the CPU's answers byte for byte, alone and with one state -# split over them, a state past a member refused. +# OpenCL) must give the CPU's answers byte for byte, asked for by key and by +# `accelerator`, alone and with one state split over them, a state past a +# member refused, and auto keeping every state on the CPU. # - hip-absent (a container with no GPU and no HIP libraries): the same build # finds no member and says why, rather than failing; the device tests run over # no member with the declaration `none`. @@ -158,7 +159,8 @@ jobs: grep -q "^fabric refused: key=$key " "$report" || { echo "::error::$key: a state past what it holds was not refused"; exit 1; } done grep -qx "fabric split: ${keys//,/+} over 14 and 19 qubits gives the CPU's answers byte for byte" "$report" || { echo "::error::the state split over the members is not the CPU's"; exit 1; } - grep -q "^fabric auto: .* the CPU's answers byte for byte" "$report" || { echo "::error::auto placed no wide state"; exit 1; } + grep -qx "fabric auto: every state on the CPU, its result unnamed" "$report" || { echo "::error::auto placed a state on a member"; exit 1; } + grep -q "^fabric accelerator: .* the CPU's answers byte for byte" "$report" || { echo "::error::an accelerator request placed no state"; exit 1; } hip-absent: name: member · HIP absent (linux-arm64) diff --git a/wai/CHANGELOG.md b/wai/CHANGELOG.md index d3adc200f..13deaa92a 100644 --- a/wai/CHANGELOG.md +++ b/wai/CHANGELOG.md @@ -274,11 +274,13 @@ wire format may change and such changes are recorded here. the state split by its top qubits into one partition on each. The CUDA, HIP and OpenCL members' dense f64 state vectors (`quantum_fabric::sv64`) are discovered once per process, compiled and certified against the CPU on the pinned corpus; only a member certified bit-exact is placed, so a placed job's answers are the CPU's byte for - byte. `auto` places a state of 20 qubits or more on the first such member that holds it, GPUs first, and keeps a - smaller one on the CPU; a member that fails during an auto run hands the job back to the CPU, and the receipt - says so. A placement the host cannot honour is refused with the new code `J013`, never made elsewhere. With no - member asked for and none placed, a job's plan and result are the ones they always were; the pinned digests are - unchanged. + byte. **`auto` places on the CPU** on every host until a member is measured faster than the CPU: with one launch + per gate and the state copied to the device and back, a whole job took about as long either way, or longer on the + GPU, between 18 and 22 qubits on the fleet's GPUs. A member runs a job only when the job asks for one: + `accelerator` takes the first certified member that holds the state, GPUs first, and one that fails during the run + hands the job to the next, the receipt listing each that failed (`fell_back_from`). A placement the host cannot + honour is refused with the new code `J013`, never made elsewhere. A job that does not ask has the plan and result + it always had, on every host; the pinned digests are unchanged. - **The fabric's receipt in the job's**: a placed result, or one whose job asked for a placement, carries `fabric` (the kernel, the placement asked, the member or each partition's, its certificate's parity tier, digest and corpus, and the energy, unmetered with the reason), sealed by the job's receipt; its provenance's `computer` diff --git a/wai/wai-quantum-cli/README.md b/wai/wai-quantum-cli/README.md index 1aac9d23f..36f5cbd00 100644 --- a/wai/wai-quantum-cli/README.md +++ b/wai/wai-quantum-cli/README.md @@ -101,7 +101,7 @@ wai-quantum instance ghz-family.qasm --input n=3 `wai-quantum methods` lists each method's reach in a job's memory here (`--memory-gb`, default 16). -`--fabric` says where the `statevector` method's state runs: `auto` (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits), `cpu`, `accelerator`, or a member's id or key; given more than once, the state is split by its top qubits into one partition on each member named (a power of two of them; `cpu` is a member, and one may be named twice). Every member placed gives the CPU's answers byte for byte, and the result names where its state ran, with the member's certificate, in its receipt. `wai-quantum fabric` lists the members this host can place on, each with the most qubits it holds, and the devices found and not placed, with why. A placement this host cannot honour is refused (`J013`), never made elsewhere. +`--fabric` says where the `statevector` method's state runs: `auto` (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), `cpu`, `accelerator` (the first accelerator member certified bit-exact here that holds the state, the next taking over if it fails during the run), or a member's id or key; given more than once, the state is split by its top qubits into one partition on each member named (a power of two of them; `cpu` is a member, and one may be named twice). Every member placed gives the CPU's answers byte for byte, and the result names where its state ran, with the member's certificate, in its receipt. `wai-quantum fabric` lists the members this host can place on, each with the most qubits it holds, and the devices found and not placed, with why. A placement this host cannot honour is refused (`J013`), never made elsewhere. ```sh runnable wai-quantum fabric diff --git a/wai/wai-quantum-cli/README.zh-CN.md b/wai/wai-quantum-cli/README.zh-CN.md index a77d4f6a1..cb165ba5f 100644 --- a/wai/wai-quantum-cli/README.zh-CN.md +++ b/wai/wai-quantum-cli/README.zh-CN.md @@ -104,7 +104,7 @@ wai-quantum instance ghz-family.qasm --input n=3 `wai-quantum methods` 列出每种方法在本机一个作业的内存(`--memory-gb`,默认 16)内能达到的规模。 -`--fabric` 指定 `statevector` 方法的态在哪里运行:`auto`(默认:从 20 个量子比特起,放到本机第一个经认证逐位一致且能容纳它的加速器成员上)、`cpu`、`accelerator`,或成员的 id 或键;多次给出时,态按最高位量子比特划分为若干分区,每个所列成员一个分区(数量为 2 的幂;`cpu` 也是成员,同一成员可列两次)。放置到的每个成员都给出与 CPU 逐字节相同的答案,结果在其收据中指明态在哪里运行以及该成员的证书。`wai-quantum fabric` 列出本机可放置的成员(各附其可容纳的最多量子比特数),以及找到但未放置的设备及原因。主机无法兑现的放置会被拒绝(`J013`),绝不改放别处。 +`--fabric` 指定 `statevector` 方法的态在哪里运行:`auto`(默认:在每台主机上都放在 CPU 上,直到测得某个计算结构成员比 CPU 更快)、`cpu`、`accelerator`(本机第一个经认证逐位一致且能容纳该态的加速器成员;若它在运行中失败,由下一个接替),或成员的 id 或键;多次给出时,态按最高位量子比特划分为若干分区,每个所列成员一个分区(数量为 2 的幂;`cpu` 也是成员,同一成员可列两次)。放置到的每个成员都给出与 CPU 逐字节相同的答案,结果在其收据中指明态在哪里运行以及该成员的证书。`wai-quantum fabric` 列出本机可放置的成员(各附其可容纳的最多量子比特数),以及找到但未放置的设备及原因。主机无法兑现的放置会被拒绝(`J013`),绝不改放别处。 ```sh runnable wai-quantum fabric diff --git a/wai/wai-quantum-cli/docs/llms-full.txt b/wai/wai-quantum-cli/docs/llms-full.txt index 1f23088b2..20a94e843 100644 --- a/wai/wai-quantum-cli/docs/llms-full.txt +++ b/wai/wai-quantum-cli/docs/llms-full.txt @@ -57,7 +57,7 @@ Parameters: - `options` (object): Method options: max_bond, fusion, trajectories, threshold, memory_gb. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's "compiled" states its distance from the program. - `target` (any): A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it. -- `fabric` (any): Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's "fabric" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013). +- `fabric` (any): Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (the first certified accelerator member that holds the state, the next taking over if it fails during the run), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's "fabric" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013). - `intent` (any): What the program must do, checked by the engine with the run: the result's "verdict" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's "repaired" holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. @@ -78,7 +78,7 @@ Parameters: - `options` (object): Method options: max_bond, fusion, trajectories, threshold, memory_gb. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's "compiled" states its distance from the program. - `target` (any): A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it. -- `fabric` (any): Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's "fabric" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013). +- `fabric` (any): Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (the first certified accelerator member that holds the state, the next taking over if it fails during the run), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's "fabric" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013). - `intent` (any): What the program must do, checked by the engine with the run: the result's "verdict" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's "repaired" holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. @@ -411,7 +411,7 @@ Parameters: - `options` (object): Method options: max_bond, fusion, trajectories, threshold, memory_gb. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's "compiled" states its distance from the program. - `target` (any, required): A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it. -- `fabric` (any): Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's "fabric" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013). +- `fabric` (any): Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (the first certified accelerator member that holds the state, the next taking over if it fails during the run), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's "fabric" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013). - `intent` (any): What the program must do, checked by the engine with the run: the result's "verdict" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's "repaired" holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. @@ -506,7 +506,7 @@ Parameters: - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. - `target` (any): A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing. -- `fabric` (any): Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. +- `fabric` (any): Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. @@ -526,7 +526,7 @@ Parameters: - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. - `target` (any): A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing. -- `fabric` (any): Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. +- `fabric` (any): Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. @@ -548,7 +548,7 @@ Parameters: - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. - `target` (any): A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing. -- `fabric` (any): Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. +- `fabric` (any): Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. @@ -675,7 +675,7 @@ Parameters: - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. - `target` (any, required): A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing. -- `fabric` (any): Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. +- `fabric` (any): Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. @@ -908,7 +908,7 @@ A program that measures a qubit and then acts on it, resets one after its first - On this machine: `wai-quantum run`, or the local MCP server (`wai-quantum mcp`). Results are signed with the user's key and nothing leaves the machine. - On the free job service, for a program too large for this machine: `wai-quantum submit`, `POST https://wai.transaction.science/quantum-jobs/v1/run`, or its MCP server at https://wai.transaction.science/quantum-jobs/mcp. No account and no key. - auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, stabilizer_rank, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, stabilizer_rank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen; stabilizer_rank is chosen by its T count, its exact sum taken when its branches are within one job's work. -- The statevector method's state runs where the job's `fabric` says: auto (the default) places a state of 20 qubits or more on the first accelerator member of the fabric found here and certified bit-exact against the CPU (`wai-quantum fabric`, or list_fabric, lists them), and keeps a smaller one on the CPU; cpu, accelerator (any certified accelerator member) or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere. +- The statevector method's state runs where the job's `fabric` says: auto (the default) places it on the CPU, on every host, until a member of the fabric is measured faster than the CPU; accelerator places it on the first accelerator member found here and certified bit-exact against the CPU that holds it (`wai-quantum fabric`, or list_fabric, lists them), the next taking over if one fails during the run; cpu or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere. ### `wai-quantum://docs/diagnostics`: the reader's diagnostics @@ -1053,7 +1053,7 @@ The accuracy classes: auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, stabilizer_rank, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, stabilizer_rank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen; stabilizer_rank is chosen by its T count, its exact sum taken when its branches are within one job's work. -The statevector method's state runs where the job's `fabric` says: auto (the default) places a state of 20 qubits or more on the first accelerator member of the fabric found here and certified bit-exact against the CPU (`wai-quantum fabric`, or list_fabric, lists them), and keeps a smaller one on the CPU; cpu, accelerator (any certified accelerator member) or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere. +The statevector method's state runs where the job's `fabric` says: auto (the default) places it on the CPU, on every host, until a member of the fabric is measured faster than the CPU; accelerator places it on the first accelerator member found here and certified bit-exact against the CPU that holds it (`wai-quantum fabric`, or list_fabric, lists them), the next taking over if one fails during the run; cpu or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere. ### `wai-quantum://examples`: worked examples, each with what it must do @@ -1504,11 +1504,12 @@ Options: 1.5, 2]}) --fabric - Where the state vector runs (the statevector method): auto (the default: a certified - accelerator member from 20 qubits), cpu, accelerator, or a member's id or key - (`wai-quantum fabric` lists them); repeated, the state is split by its top qubits into one - partition on each member named, a power of two of them. A member certified bit-exact gives - the CPU's answers; a placement this host cannot honour is refused (J013) + Where the state vector runs (the statevector method): auto (the default: the CPU, until a + member is measured faster), cpu, accelerator (the first certified accelerator member that + holds the state), or a member's id or key (`wai-quantum fabric` lists them); repeated, the + state is split by its top qubits into one partition on each member named, a power of two + of them. A member certified bit-exact gives the CPU's answers; a placement this host + cannot honour is refused (J013) --json Print the job as the service returns it: request, plan, result and receipt @@ -1637,11 +1638,12 @@ Options: 1.5, 2]}) --fabric - Where the state vector runs (the statevector method): auto (the default: a certified - accelerator member from 20 qubits), cpu, accelerator, or a member's id or key - (`wai-quantum fabric` lists them); repeated, the state is split by its top qubits into one - partition on each member named, a power of two of them. A member certified bit-exact gives - the CPU's answers; a placement this host cannot honour is refused (J013) + Where the state vector runs (the statevector method): auto (the default: the CPU, until a + member is measured faster), cpu, accelerator (the first certified accelerator member that + holds the state), or a member's id or key (`wai-quantum fabric` lists them); repeated, the + state is split by its top qubits into one partition on each member named, a power of two + of them. A member certified bit-exact gives the CPU's answers; a placement this host + cannot honour is refused (J013) --json Print the plan as JSON @@ -2269,11 +2271,12 @@ Options: 1.5, 2]}) --fabric - Where the state vector runs (the statevector method): auto (the default: a certified - accelerator member from 20 qubits), cpu, accelerator, or a member's id or key - (`wai-quantum fabric` lists them); repeated, the state is split by its top qubits into one - partition on each member named, a power of two of them. A member certified bit-exact gives - the CPU's answers; a placement this host cannot honour is refused (J013) + Where the state vector runs (the statevector method): auto (the default: the CPU, until a + member is measured faster), cpu, accelerator (the first certified accelerator member that + holds the state), or a member's id or key (`wai-quantum fabric` lists them); repeated, the + state is split by its top qubits into one partition on each member named, a power of two + of them. A member certified bit-exact gives the CPU's answers; a placement this host + cannot honour is refused (J013) --json Print the job as the service returns it: request, plan, result and receipt diff --git a/wai/wai-quantum-cli/docs/local-mcp.json b/wai/wai-quantum-cli/docs/local-mcp.json index fc5b423eb..88fc86a79 100644 --- a/wai/wai-quantum-cli/docs/local-mcp.json +++ b/wai/wai-quantum-cli/docs/local-mcp.json @@ -126,7 +126,7 @@ "description": "A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it." }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (the first certified accelerator member that holds the state, the next taking over if it fails during the run), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", "anyOf": [ { "type": "string", @@ -929,7 +929,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -2028,7 +2028,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -2177,6 +2177,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -2200,70 +2204,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -3812,7 +3824,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -4909,7 +4921,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -5058,6 +5070,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -5081,70 +5097,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -6931,7 +6955,7 @@ "description": "A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it." }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (the first certified accelerator member that holds the state, the next taking over if it fails during the run), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", "anyOf": [ { "type": "string", @@ -25272,10 +25296,9 @@ "kernel": { "type": "string" }, - "auto_min_qubits": { - "type": "integer", - "minimum": 1, - "description": "The fewest qubits auto places on an accelerator member." + "auto": { + "type": "string", + "description": "Where auto places a state: on the CPU, until a member is measured faster than the CPU." }, "members": { "type": "array", @@ -27003,7 +27026,7 @@ "description": "A device target: its name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to the target's gates, placed where it is most likely to succeed and simulated under the target's noise, the target's hash in the receipt; noise may not be given beside it." }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (the first certified accelerator member that holds the state, the next taking over if it fails during the run), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", "anyOf": [ { "type": "string", @@ -27806,7 +27829,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -28905,7 +28928,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -29054,6 +29077,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -29077,70 +29104,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -30689,7 +30724,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -31786,7 +31821,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -31935,6 +31970,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -31958,70 +31997,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -35900,7 +35947,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -36999,7 +37046,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -37148,6 +37195,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -37171,70 +37222,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -38783,7 +38842,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -39880,7 +39939,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -40029,6 +40088,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -40052,70 +40115,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, diff --git a/wai/wai-quantum-cli/docs/service-mcp.json b/wai/wai-quantum-cli/docs/service-mcp.json index 5bf5f1565..cb88e73fc 100644 --- a/wai/wai-quantum-cli/docs/service-mcp.json +++ b/wai/wai-quantum-cli/docs/service-mcp.json @@ -123,7 +123,7 @@ "description": "A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing." }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", "anyOf": [ { "type": "string", @@ -934,7 +934,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -2033,7 +2033,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -2182,6 +2182,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -2205,70 +2209,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -3817,7 +3829,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -4914,7 +4926,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -5063,6 +5075,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -5086,70 +5102,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -8286,7 +8310,7 @@ "description": "A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing." }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", "anyOf": [ { "type": "string", @@ -9127,7 +9151,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -10226,7 +10250,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -10375,6 +10399,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -10398,70 +10426,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -12010,7 +12046,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -13107,7 +13143,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -13256,6 +13292,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -13279,70 +13319,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -16479,7 +16527,7 @@ "description": "A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing." }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", "anyOf": [ { "type": "string", @@ -18324,7 +18372,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -19423,7 +19471,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -19572,6 +19620,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -19595,70 +19647,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -21207,7 +21267,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -22304,7 +22364,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -22453,6 +22513,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -22476,70 +22540,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -37318,7 +37390,7 @@ "description": "A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing." }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", "anyOf": [ { "type": "string", @@ -38049,7 +38121,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -39148,7 +39220,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -39297,6 +39369,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -39320,70 +39396,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -40932,7 +41016,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", @@ -42029,7 +42113,7 @@ }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -42178,6 +42262,10 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } } @@ -42201,70 +42289,78 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "type": "object", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job.", - "required": [ - "member", - "implementation", - "parity", - "certificate" - ], - "properties": { - "member": { - "type": "string" - }, - "key": { - "type": "string" - }, - "class": { - "type": "string" - }, - "implementation": { - "type": "string" - }, - "parity": { - "type": "object", - "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", - "required": [ - "tier" - ], - "properties": { - "tier": { - "enum": [ - "bit-exact", - "within", - "statistical", - "uncertified" - ] - }, - "max_ulp": { - "type": "integer", - "minimum": 0 - }, - "max_abs": { - "type": "number" - }, - "fidelity": { - "type": "number" - }, - "shots": { - "type": "integer", - "minimum": 0 + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "type": "object", + "description": "A member of the fabric and its certificate for the kernel: its id (which binds the device), its key, its class, the implementation, the parity tier, the certificate's digest (BLAKE3, hex), and the corpus it was earned on (its digest, generator and cases; the CPU reference's own standing has none).", + "required": [ + "member", + "implementation", + "parity", + "certificate" + ], + "properties": { + "member": { + "type": "string" + }, + "key": { + "type": "string" + }, + "class": { + "type": "string" + }, + "implementation": { + "type": "string" + }, + "parity": { + "type": "object", + "description": "A certificate's standing against the CPU reference: bit-exact, within a bound (max_ulp, max_abs), statistical (fidelity over shots) or uncertified. Only bit-exact members are placed.", + "required": [ + "tier" + ], + "properties": { + "tier": { + "enum": [ + "bit-exact", + "within", + "statistical", + "uncertified" + ] + }, + "max_ulp": { + "type": "integer", + "minimum": 0 + }, + "max_abs": { + "type": "number" + }, + "fidelity": { + "type": "number" + }, + "shots": { + "type": "integer", + "minimum": 0 + } } + }, + "certificate": { + "type": "string" + }, + "corpus": { + "type": "string" + }, + "generator": { + "type": "string" + }, + "cases": { + "type": "integer", + "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } - }, - "certificate": { - "type": "string" - }, - "corpus": { - "type": "string" - }, - "generator": { - "type": "string" - }, - "cases": { - "type": "integer", - "minimum": 0 } } }, @@ -43995,7 +44091,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", diff --git a/wai/wai-quantum-cli/src/main.rs b/wai/wai-quantum-cli/src/main.rs index 855231368..dd4d22415 100644 --- a/wai/wai-quantum-cli/src/main.rs +++ b/wai/wai-quantum-cli/src/main.rs @@ -541,7 +541,7 @@ struct Job { /// A parameter's value, as theta=0.3 (repeatable): each `input float` and `input angle` of the program, bound exactly (the job's "params"); in a sweep, the parameters it fixes #[arg(long = "param", value_name = "NAME=VALUE", value_parser = variational::param_arg)] params: Vec<(String, f64)>, - /// Where the state vector runs (the statevector method): auto (the default: a certified accelerator member from 20 qubits), cpu, accelerator, or a member's id or key (`wai-quantum fabric` lists them); repeated, the state is split by its top qubits into one partition on each member named, a power of two of them. A member certified bit-exact gives the CPU's answers; a placement this host cannot honour is refused (J013) + /// Where the state vector runs (the statevector method): auto (the default: the CPU, until a member is measured faster), cpu, accelerator (the first certified accelerator member that holds the state), or a member's id or key (`wai-quantum fabric` lists them); repeated, the state is split by its top qubits into one partition on each member named, a power of two of them. A member certified bit-exact gives the CPU's answers; a placement this host cannot honour is refused (J013) #[arg(long = "fabric", value_name = "PLACEMENT")] fabric: Vec, } @@ -610,7 +610,7 @@ fn option_arg(s: &str) -> Result<(String, Value), String> { /// The fabric's members as `wai-quantum fabric` prints them. fn fabric_text(f: &Value) -> String { let s = |v: &Value| v.as_str().unwrap_or("").to_string(); - let mut o = format!("kernel {} (auto places a state of {} qubits or more on the first accelerator listed that holds it)\n", s(&f["kernel"]), f["auto_min_qubits"]); + let mut o = format!("kernel {}\nauto {}\n", s(&f["kernel"]), s(&f["auto"])); for m in f["members"].as_array().into_iter().flatten() { let corpus = m["corpus"].as_str().map(|c| format!(", corpus {}… over {} cases", &c[..16.min(c.len())], m["cases"])).unwrap_or_default(); o.push_str(&format!("member {:<18} {:<4} up to {} qubits, {} {}{corpus}\n", s(&m["key"]), s(&m["class"]), m["detail"]["max_qubits"], s(&m["implementation"]), s(&m["parity"]["tier"]))); diff --git a/wai/wai-quantum-cli/src/mcp.rs b/wai/wai-quantum-cli/src/mcp.rs index 1f7f2f441..c8296a2ef 100644 --- a/wai/wai-quantum-cli/src/mcp.rs +++ b/wai/wai-quantum-cli/src/mcp.rs @@ -129,7 +129,7 @@ fn job_schema() -> Value { /// What a job's `fabric` takes: where the statevector method's state runs. pub(crate) fn fabric_schema() -> Value { json!({ - "description": "Where the statevector method's state runs: auto (the default: on a certified accelerator member from 20 qubits, otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (the first certified accelerator member that holds the state, the next taking over if it fails during the run), a member's id or key (list_fabric), or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's \"fabric\" names where the state ran, sealed by the receipt. A placement this host cannot honour is refused (J013).", "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "array", "minItems": 2, "maxItems": 64, "items": { "type": "string", "minLength": 1 } }] }) } diff --git a/wai/wai-quantum-service/src/mcp.rs b/wai/wai-quantum-service/src/mcp.rs index 22071858d..d578deee8 100644 --- a/wai/wai-quantum-service/src/mcp.rs +++ b/wai/wai-quantum-service/src/mcp.rs @@ -228,7 +228,7 @@ fn tool_list() -> Value { "options": { "type": "object", "description": "Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories." }, "compile": { "type": "object", "description": "Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program.", "properties": compile_props() }, "target": { "description": "A device target: a built-in target's name (list_targets) or a target document (wai.quantum.target/1). The program is then compiled to its gates, placed where it is most likely to succeed and simulated under its noise, its hash in the receipt; not with noise or amplitudes. The service reads the document given and fetches nothing." }, - "fabric": { "description": "Where the statevector method's state runs: auto (the default), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "array", "minItems": 2, "maxItems": 64, "items": { "type": "string", "minLength": 1 } }] }, + "fabric": { "description": "Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU.", "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "array", "minItems": 2, "maxItems": 64, "items": { "type": "string", "minLength": 1 } }] }, "intent": intent_schema(), "repair": { "description": "Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {\"max_iterations\": N, \"dyadic_bits\": K, \"sizes\": {\"q\": 3}}. The result's `repaired` holds the program that ran and each repair." }, "mitigate": wai_quantum::engine::mitigate::schema(), diff --git a/wai/wai-quantum/README.md b/wai/wai-quantum/README.md index e9fc2e319..69b4a1dd4 100644 --- a/wai/wai-quantum/README.md +++ b/wai/wai-quantum/README.md @@ -544,10 +544,12 @@ members (`engine::fabric`). With the CUDA, HIP or OpenCL member compiled in `quantum_engine`), each device this process finds runs the dense f64 state vector (`quantum_fabric::sv64`) and is certified against the CPU on the pinned corpus; only a member certified bit-exact is placed, so a job placed on one -gives the CPU's answers byte for byte. `auto`, the default, places a state of -20 qubits or more on the first such member that holds it, GPUs first, and -keeps a smaller one on the CPU; `cpu`, `accelerator` or a member's id or key -place it there; and a list of members, a power of two of them, splits the +gives the CPU's answers byte for byte. `auto`, the default, places the state on +the CPU, on every host, until a member is measured faster than the CPU for a +job; a member runs a job only when the job asks for one. `accelerator` places +it on the first certified member that holds it, GPUs first, the next taking +over if one fails during the run; `cpu` or a member's id or key place it +there; and a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Each partition runs the same launches the CPU plans on its own amplitudes, and a gate on a partition qubit first has that qubit exchanged with a local one through the host's copy @@ -558,8 +560,10 @@ receipt seals it; with no member asked for and none placed a result is the one it always was. Each member states the most qubits it holds, and a state or a partition past that is refused, as is any placement the host cannot honour (`J013`). Measured on the fleet's GPUs (a laptop GPU and an integrated one, -each beside a CPU), a whole job takes about as long either way below 22 -qubits: the copies to and from a device cost what its passes save. +each beside a CPU), with one launch per gate and the state copied to the +device and back, a whole job took about as long either way, or longer on the +GPU, between 18 and 22 qubits: the copies cost what the passes save. That is +why `auto` stays on the CPU. ## Tensor networks diff --git a/wai/wai-quantum/README.zh-CN.md b/wai/wai-quantum/README.zh-CN.md index 416408f1f..ec60075d1 100644 --- a/wai/wai-quantum/README.zh-CN.md +++ b/wai/wai-quantum/README.zh-CN.md @@ -350,7 +350,7 @@ wai-quantum fabric # 本机上态矢量可放 wai-quantum run circuit.qasm --method statevector --fabric cpu --fabric cpu --fabric cpu --fabric cpu --shots 100 --json > split.json ``` -作业的 `fabric` 把 `statevector` 方法的态放到计算结构的成员上(`engine::fabric`)。编译进 CUDA、HIP 或 OpenCL 成员(`quantum_fabric_cuda`、`quantum_fabric_hip`、`quantum_fabric_opencl`,配合 `quantum_engine`)后,本进程找到的每个设备都运行稠密 f64 态矢量(`quantum_fabric::sv64`),并在固定语料上对照 CPU 认证;只有认证为逐位一致的成员才会被放置,因此放到其上的作业给出与 CPU 逐字节相同的答案。默认的 `auto` 把 20 个量子比特及以上的态放到第一个能容纳它的此类成员上(GPU 优先),较小的态留在 CPU 上;`cpu`、`accelerator` 或成员的 id 或键把它放到那里;成员列表(数量为 2 的幂)按最高位量子比特把态划分为若干分区,每个成员一个分区。每个分区在自己的振幅上运行 CPU 规划的同一组启动;作用于分区量子比特的门,先经主机上的态副本把该量子比特与一个本地量子比特交换(`quantum_fabric::sv64::run_split`),因此拼合后的态与 CPU 的逐位相同。结果的 `fabric` 指明成员(或每个分区的成员)及其证书的一致性等级、摘要和语料,并由收据封存;未请求成员、也未放置时,结果与以往相同。每个成员说明它能容纳的最多量子比特数,超过此数的态或分区会被拒绝,主机无法兑现的任何放置也会被拒绝(`J013`)。在本集群的 GPU(一块笔记本 GPU 和一块集成 GPU,各与一颗 CPU 相邻)上测得:低于 22 个量子比特时,整个作业两种方式耗时相近,设备往返拷贝的开销与它节省的遍历相当。 +作业的 `fabric` 把 `statevector` 方法的态放到计算结构的成员上(`engine::fabric`)。编译进 CUDA、HIP 或 OpenCL 成员(`quantum_fabric_cuda`、`quantum_fabric_hip`、`quantum_fabric_opencl`,配合 `quantum_engine`)后,本进程找到的每个设备都运行稠密 f64 态矢量(`quantum_fabric::sv64`),并在固定语料上对照 CPU 认证;只有认证为逐位一致的成员才会被放置,因此放到其上的作业给出与 CPU 逐字节相同的答案。默认的 `auto` 在每台主机上都把态放在 CPU 上,直到测得某个成员对作业比 CPU 更快;只有作业请求成员时,成员才运行它。`accelerator` 把它放到第一个能容纳它的已认证成员上(GPU 优先),若该成员在运行中失败,由下一个接替;`cpu` 或成员的 id 或键把它放到那里;成员列表(数量为 2 的幂)按最高位量子比特把态划分为若干分区,每个成员一个分区。每个分区在自己的振幅上运行 CPU 规划的同一组启动;作用于分区量子比特的门,先经主机上的态副本把该量子比特与一个本地量子比特交换(`quantum_fabric::sv64::run_split`),因此拼合后的态与 CPU 的逐位相同。结果的 `fabric` 指明成员(或每个分区的成员)及其证书的一致性等级、摘要和语料,并由收据封存;未请求成员、也未放置时,结果与以往相同。每个成员说明它能容纳的最多量子比特数,超过此数的态或分区会被拒绝,主机无法兑现的任何放置也会被拒绝(`J013`)。在本集群的 GPU(一块笔记本 GPU 和一块集成 GPU,各与一颗 CPU 相邻)上测得:每个门一次启动、态在设备与主机之间往返拷贝时,在 18 到 22 个量子比特之间,整个作业两种方式耗时相近,或在 GPU 上更长,拷贝的开销与节省的遍历相当。这就是 `auto` 留在 CPU 上的原因。 ## 张量网络 diff --git a/wai/wai-quantum/schemas/job-request.v1.json b/wai/wai-quantum/schemas/job-request.v1.json index a7132c8bb..04ccfb74f 100644 --- a/wai/wai-quantum/schemas/job-request.v1.json +++ b/wai/wai-quantum/schemas/job-request.v1.json @@ -173,7 +173,7 @@ ] }, "fabric": { - "description": "Where the statevector method's state runs: auto (the default: on the first accelerator member of the fabric certified bit-exact here that holds it, from 20 qubits; otherwise the CPU), cpu, accelerator (any certified accelerator member), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", + "description": "Where the statevector method's state runs: auto (the default: on the CPU, on every host, until a member of the fabric is measured faster than the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.", "anyOf": [ { "type": "string", diff --git a/wai/wai-quantum/schemas/job-result.v1.json b/wai/wai-quantum/schemas/job-result.v1.json index 8dab89897..963d668e4 100644 --- a/wai/wai-quantum/schemas/job-result.v1.json +++ b/wai/wai-quantum/schemas/job-result.v1.json @@ -1120,12 +1120,16 @@ "cases": { "type": "integer", "minimum": 0 + }, + "why": { + "type": "string", + "description": "For a member the job fell back from: how it failed." } } }, "fabric": { "type": "object", - "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the state ran on an accelerator member, or the job asked for a placement; the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", + "description": "Where the state vector ran: the kernel, the placement the job asked for, the member that ran it (or each partition's), each with its certificate, and the energy. Present when the job asked for a placement (auto places on the CPU and names nothing); the receipt seals it with the rest of the result. Every member placed is certified bit-exact, so the answers are the CPU's, byte for byte.", "required": [ "kernel", "asked", @@ -1204,8 +1208,11 @@ "description": "Partition qubits exchanged with local ones through the host's copy of the state." }, "fell_back_from": { - "$ref": "#/$defs/fabric_member", - "description": "An auto placement whose member failed during the run: that member; the CPU ran the job." + "type": "array", + "description": "An accelerator request whose member failed during the run: each member that failed, in turn, with how; the member named above ran the job.", + "items": { + "$ref": "#/$defs/fabric_member" + } }, "energy": { "$ref": "#/$defs/energy" diff --git a/wai/wai-quantum/schemas/tools.v1.json b/wai/wai-quantum/schemas/tools.v1.json index 9a79d1445..7746a3812 100644 --- a/wai/wai-quantum/schemas/tools.v1.json +++ b/wai/wai-quantum/schemas/tools.v1.json @@ -2239,10 +2239,9 @@ "kernel": { "type": "string" }, - "auto_min_qubits": { - "type": "integer", - "minimum": 1, - "description": "The fewest qubits auto places on an accelerator member." + "auto": { + "type": "string", + "description": "Where auto places a state: on the CPU, until a member is measured faster than the CPU." }, "members": { "type": "array", diff --git a/wai/wai-quantum/src/engine/fabric.rs b/wai/wai-quantum/src/engine/fabric.rs index 787514299..937ef9a69 100644 --- a/wai/wai-quantum/src/engine/fabric.rs +++ b/wai/wai-quantum/src/engine/fabric.rs @@ -9,7 +9,7 @@ //! the CPU on the pinned corpus. Only a member certified bit-exact is //! placed: it gives the CPU's bits, so a job placed on it has the answers it //! would have had on the CPU, byte for byte. Discovery runs once per -//! process, the first time a job may be placed on a member. +//! process, the first time a job asks for a member. //! - **Asking.** A job's `fabric` is `auto` (the default), `cpu`, //! `accelerator` (any certified accelerator member), a member's id or key, //! or a list of them: the state split by its top qubits into that many @@ -17,12 +17,18 @@ //! named more than once, and `cpu` is a member). A placement this host //! cannot honour is refused ([`super::refusal::FABRIC`]), never made //! somewhere else. -//! - **Auto.** A state of at least [`AUTO_MIN_QUBITS`] qubits goes to the -//! first certified accelerator member that holds it, GPUs first; a smaller -//! one, or one no member holds, stays on the CPU. A member that fails during -//! an auto run hands the job back to the CPU, and the receipt says so. With -//! no member present a job runs as it always did, and its result has no -//! `fabric`. +//! - **Auto stays on the CPU** until a member is measured faster than the CPU +//! for a job. With one launch per gate and the state copied to the device +//! and back, a whole job measured about as fast, or slower, either way +//! between 18 and 22 qubits on the fleet's GPUs, so `auto` places nothing +//! and looks for no member: a job that does not ask runs as it always did, +//! on every host, and its result has no `fabric`. A member runs a job only +//! when the job asks for one. +//! - **Accelerator.** `accelerator` takes the first certified member that +//! holds the state, GPUs first. One that fails during the run hands the job +//! to the next that holds it, and the receipt lists each that failed +//! (`fell_back_from`); when every one fails the job is refused. A member +//! named by its id or key is that member alone. //! - **Partitions** ([`crate::quantum_fabric::sv64::run_split`]). Each //! partition runs the same launches the CPU plans, on its own amplitudes; a //! gate on a partition qubit first has that qubit exchanged with a local one @@ -43,10 +49,9 @@ use serde_json::{Value, json}; /// The kernel a placement runs: a gate list on a dense f64 state. pub const KERNEL: &str = "wai.quantum.sv/run"; -/// The fewest qubits `auto` places on an accelerator member. Below, the -/// copies to and from the device cost more than the passes over the state -/// they save. -pub const AUTO_MIN_QUBITS: u32 = 20; +/// Where `auto` places a state: on the CPU, on every host, until a member +/// is measured faster than the CPU for a job. +pub const AUTO: &str = "cpu: auto places on the CPU until a member is measured faster than the CPU; a member runs a job that asks for one"; /// The most partitions a state may be split into. pub const MAX_PARTITIONS: usize = 64; @@ -200,7 +205,7 @@ mod imp { pub(super) fn list(job_bytes: u64) -> Value { json!({ "kernel": KERNEL, - "auto_min_qubits": AUTO_MIN_QUBITS, + "auto": AUTO, "members": [{ "member": "cpu", "key": "cpu", "class": "cpu", "implementation": "reference", "parity": { "tier": "bit-exact" }, "detail": cpu_detail(job_bytes) }], "refused": [], "unavailable": [{ "backend": "fabric", "why": "this build has no fabric (the engine's quantum_fabric feature)" }], @@ -233,6 +238,14 @@ mod imp { device: Box, } + impl Accelerator { + /// A member for the tests, on a device of their own. + #[cfg(test)] + pub(super) fn for_tests(key: &str, certificate: Certificate, class: FabricClass, device: Box) -> Accelerator { + Accelerator { id: key.into(), key: key.into(), class, backend: "test", certificate, detail: String::new(), device } + } + } + struct Registry { members: Vec, refused: Vec, @@ -389,7 +402,9 @@ mod imp { pub(super) enum Placed<'a> { Cpu, - One(&'a Accelerator), + /// The member the state runs on, then those it falls back to in + /// turn (for `accelerator`; a member named is alone here). + Members(Vec<&'a Accelerator>), Split(Vec>), } @@ -431,21 +446,24 @@ mod imp { pub(super) fn resolve<'a>(ask: &Ask, n: u32, widest: u32) -> Result, String> { match ask { - Ask::Cpu => Ok(Placed::Cpu), - Ask::Auto if n < AUTO_MIN_QUBITS || backends().is_empty() => Ok(Placed::Cpu), - Ask::Auto => Ok(registry().members.iter().find(|m| m.device.max_qubits() >= n).map_or(Placed::Cpu, Placed::One)), + // Auto stays on the CPU and looks for no member (see the module). + Ask::Cpu | Ask::Auto => Ok(Placed::Cpu), Ask::Accelerator => { let reg = registry(); if reg.members.is_empty() { return Err(tag(refusal::FABRIC, format!("fabric accelerator: no certified accelerator member here; {}", here(reg)))); } - reg.members.iter().find(|m| m.device.max_qubits() >= n).map(Placed::One).ok_or_else(|| tag(refusal::FABRIC, format!("fabric accelerator: a state of {n} qubits; the largest member here holds {} (give a list of members to split it)", reg.members.iter().map(|m| m.device.max_qubits()).max().unwrap_or(0)))) + let holds: Vec<&Accelerator> = reg.members.iter().filter(|m| m.device.max_qubits() >= n).collect(); + if holds.is_empty() { + return Err(tag(refusal::FABRIC, format!("fabric accelerator: a state of {n} qubits; the largest member here holds {} (give a list of members to split it)", reg.members.iter().map(|m| m.device.max_qubits()).max().unwrap_or(0)))); + } + Ok(Placed::Members(holds)) } Ask::Member(name) => { let reg = registry(); match named(reg, name)? { Part::Cpu => Ok(Placed::Cpu), - Part::Member(m) if m.device.max_qubits() >= n => Ok(Placed::One(m)), + Part::Member(m) if m.device.max_qubits() >= n => Ok(Placed::Members(vec![m])), Part::Member(m) => Err(tag(refusal::FABRIC, format!("fabric {name}: a state of {n} qubits; {} holds at most {} (give a list of members to split it)", m.key, m.device.max_qubits()))), } } @@ -489,7 +507,7 @@ mod imp { match p { Placed::Cpu if *ask == Ask::Auto => None, Placed::Cpu => Some("on the CPU, as the job asked".into()), - Placed::One(m) => Some(format!("its state on {} ({}), certified bit-exact against the CPU", m.key, m.id)), + Placed::Members(ms) => ms.first().map(|m| format!("its state on {} ({}), certified bit-exact against the CPU", m.key, m.id)), Placed::Split(parts) => Some(format!("its state split by its top {} qubits into {} partitions, on {}, each certified bit-exact against the CPU", parts.len().trailing_zeros(), parts.len(), parts.iter().map(label).collect::>().join(", "))), } } @@ -538,23 +556,42 @@ mod imp { let r = (*ask != Ask::Auto).then(|| receipt(cpu_json(), said(ask, p))); Ok((sv, r)) } - Placed::One(m) => { + Placed::Members(ms) => { let launches = sv64::plan(n, gates, width).map_err(|e| format!("{e:?}"))?; let len = 1usize << n; let mut re = vec![0.0; len]; re[0] = 1.0; - match m.device.run(&re, &vec![0.0; len], &launches) { - Ok((re, im)) => Ok((state(n, re, im), Some(receipt(member_json(m), said(ask, p))))), - // A member that fails during an auto run hands the job - // back to the CPU, and the receipt says so. - Err(e) if *ask == Ask::Auto => { - let sv = cpu_run(n, gates, width)?; - let mut body = receipt(cpu_json(), Some(format!("{} failed during the run, and the CPU ran the job: {e}", m.key))); - body["fell_back_from"] = member_json(m); - Ok((sv, Some(body))) + let im = vec![0.0; len]; + // Each in turn until one runs it: a member that fails hands the + // job to the next, and the receipt lists each that failed. + let mut failed: Vec<(&Accelerator, String)> = Vec::new(); + for m in ms { + match m.device.run(&re, &im, &launches) { + Ok((re, im)) => { + let mut why = said(ask, &Placed::Members(vec![m])); + if !failed.is_empty() { + why = Some(format!("{}; {} failed during the run first", why.unwrap_or_default(), failed.iter().map(|(f, _)| f.key.as_str()).collect::>().join(", "))); + } + let mut body = receipt(member_json(m), why); + if !failed.is_empty() { + body["fell_back_from"] = Value::Array( + failed + .iter() + .map(|(f, e)| { + let mut j = member_json(f); + j["why"] = json!(e); + j + }) + .collect(), + ); + } + return Ok((state(n, re, im), Some(body))); + } + Err(e) => failed.push((m, e)), } - Err(e) => Err(tag(refusal::FABRIC, format!("fabric: {} failed during the run: {e}", m.key))), } + let all: Vec = failed.iter().map(|(f, e)| format!("{} failed during the run: {e}", f.key)).collect(); + Err(tag(refusal::FABRIC, format!("fabric: {}", all.join("; ")))) } Placed::Split(parts) => { let launches = sv64::plan(n, gates, width).map_err(|e| format!("{e:?}"))?; @@ -622,7 +659,7 @@ mod imp { } json!({ "kernel": KERNEL, - "auto_min_qubits": AUTO_MIN_QUBITS, + "auto": AUTO, "members": members, "refused": reg.refused, "unavailable": reg.unavailable, @@ -635,6 +672,50 @@ mod imp { mod tests { use super::*; + /// An `accelerator` request whose member fails during the run hands the + /// job to the next member that holds the state, with the CPU's bits and + /// the failure in the receipt; when every member fails it is refused. + #[cfg(feature = "quantum_fabric")] + #[test] + fn an_accelerator_that_fails_hands_the_job_to_the_next_and_the_receipt_says_so() { + use crate::quantum_fabric::sv64::{Launch, replay}; + use crate::quantum_fabric::{Certificate, FabricClass}; + use super::imp::{self, Accelerator, Device, Placed}; + struct Lost; + impl Device for Lost { + fn max_qubits(&self) -> u32 { + 25 + } + fn run(&self, _: &[f64], _: &[f64], _: &[Launch]) -> Result<(Vec, Vec), String> { + Err("device lost".into()) + } + } + struct Replay; + impl Device for Replay { + fn max_qubits(&self) -> u32 { + 25 + } + fn run(&self, re: &[f64], im: &[f64], l: &[Launch]) -> Result<(Vec, Vec), String> { + let (mut re, mut im) = (re.to_vec(), im.to_vec()); + replay(&mut re, &mut im, l); + Ok((re, im)) + } + } + let member = |key: &str, device: Box| Accelerator::for_tests(key, Certificate::reference(KERNEL, key), FabricClass::Gpu, device); + let (a, b) = (member("lost", Box::new(Lost)), member("kept", Box::new(Replay))); + let gates: Vec = (0..6u32).flat_map(|q| [crate::gates::Gate::rx(q, 0.3 + f64::from(q)), crate::gates::Gate::cz(q, (q + 1) % 6)]).collect(); + let mut cpu = crate::quantum_sv::StateVector::zero(6).unwrap(); + cpu.run(&gates, 3).unwrap(); + let (sv, receipt) = imp::run(&Ask::Accelerator, &Placed::Members(vec![&a, &b]), 6, &gates, 3).unwrap(); + assert!(sv.re.iter().zip(&cpu.re).chain(sv.im.iter().zip(&cpu.im)).all(|(x, y)| x.to_bits() == y.to_bits()), "the CPU's bits"); + let r = receipt.unwrap(); + assert_eq!((r["key"].as_str(), r["fell_back_from"][0]["key"].as_str(), r["fell_back_from"][0]["why"].as_str()), (Some("kept"), Some("lost"), Some("device lost")), "{r}"); + assert!(r["why"].as_str().unwrap().contains("lost failed during the run first"), "{r}"); + assert!(super::super::schema::Registry::engine().check("job-result.v1.json#/$defs/fabric", &r).is_empty(), "{r}"); + let e = imp::run(&Ask::Accelerator, &Placed::Members(vec![&a]), 6, &gates, 3).unwrap_err(); + assert!(e.ends_with("[J013]") && e.contains("lost failed during the run: device lost"), "{e}"); + } + #[test] fn a_job_s_fabric_reads_or_is_refused_with_its_code() { let ask = |f: Value| asked(&json!({ "qasm": "", "fabric": f })); diff --git a/wai/wai-quantum/src/engine/guide.rs b/wai/wai-quantum/src/engine/guide.rs index 0f9953738..eddda93aa 100644 --- a/wai/wai-quantum/src/engine/guide.rs +++ b/wai/wai-quantum/src/engine/guide.rs @@ -97,7 +97,7 @@ pub const VERDICTS: &str = "wai-quantum://docs/verdicts"; pub const AUTO: &str = "auto picks, in order: with noise, density_matrix, stabilizer, then trajectories; for counts, stabilizer, exact, statevector, statevector_single, cutrank, mps; for expectation values only, stabilizer, exact, statevector, statevector_single, stabilizer_rank, pauli, mps; for amplitudes only, exact, statevector, statevector_single, cutrank, stabilizer_rank, tensor_network, mps. A method that cannot take the program is skipped, and the plan says why the one chosen was chosen; stabilizer_rank is chosen by its T count, its exact sum taken when its branches are within one job's work."; /// Where the statevector method's state runs, in a paragraph. -pub const FABRIC: &str = "The statevector method's state runs where the job's `fabric` says: auto (the default) places a state of 20 qubits or more on the first accelerator member of the fabric found here and certified bit-exact against the CPU (`wai-quantum fabric`, or list_fabric, lists them), and keeps a smaller one on the CPU; cpu, accelerator (any certified accelerator member) or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere."; +pub const FABRIC: &str = "The statevector method's state runs where the job's `fabric` says: auto (the default) places it on the CPU, on every host, until a member of the fabric is measured faster than the CPU; accelerator places it on the first accelerator member found here and certified bit-exact against the CPU that holds it (`wai-quantum fabric`, or list_fabric, lists them), the next taking over if one fails during the run; cpu or a member's id or key places it there; a list of members, a power of two of them, splits the state by its top qubits into one partition on each. Every member placed gives the CPU's bits, so the answers are the same byte for byte; the result's `fabric` names where the state ran, with the member's certificate, and the receipt seals it. A placement this host cannot honour is refused (J013), never made elsewhere."; /// The language in a paragraph, for `AGENTS.md`. pub const SUMMARY: &str = "Programs are OpenQASM 3.1, or the OpenQASM 2 forms in common use, read by one reader on every surface: registers, the standard gates, `gate` and `def` definitions, the `ctrl @`, `negctrl @`, `inv @` and `pow @` modifiers, classical types and expressions, measurement and `reset` anywhere, `if`, `switch` and bounded `while` on measured bits, timing carried, and calibrations kept for export. Generators (integer `input`s, `const`s and `for` loops) describe a family of circuits. Every refusal and warning names its line and ends with a stable code (`[Q103]`), which the diagnostics resource explains."; diff --git a/wai/wai-quantum/tests/fabric_placement.rs b/wai/wai-quantum/tests/fabric_placement.rs index 1215b831b..fc6a38107 100644 --- a/wai/wai-quantum/tests/fabric_placement.rs +++ b/wai/wai-quantum/tests/fabric_placement.rs @@ -97,29 +97,37 @@ fn p0_each_member_gives_the_cpus_answers_byte_for_byte() { } #[test] -fn p1_auto_places_a_wide_state_and_keeps_a_small_one_on_the_cpu() { +fn p1_auto_stays_on_the_cpu_and_accelerator_takes_the_first_member() { let found = members(); - let small = ran(&job(8, json!({}))).unwrap(); - assert!(small.get("fabric").is_none(), "a state below the auto threshold stays on the CPU, unnamed: {}", small["fabric"]); + // Auto places nothing, however wide the state and whatever members there + // are: the result is the one it always was, with no `fabric`. + for n in [8u32, 21] { + let auto = ran(&job(n, json!({}))).unwrap(); + assert!(auto.get("fabric").is_none(), "auto at {n} qubits stays on the CPU, unnamed: {}", auto["fabric"]); + let plan = catalog::plan(&job(n, json!({})), CAP).unwrap(); + assert!(!plan.why.contains("its state on"), "{}", plan.why); + } + report("fabric auto: every state on the CPU, its result unnamed"); let Some((first, _)) = found.first() else { - let wide = ran(&job(fabric::AUTO_MIN_QUBITS, json!({}))).unwrap(); - assert!(wide.get("fabric").is_none(), "with no member, a job runs as it always did"); - report("fabric auto: no member; every state stays on the CPU, its result unnamed"); + let e = catalog::plan(&job(8, json!({ "fabric": "accelerator" })), CAP).unwrap_err(); + assert!(e.ends_with("[J013]") && e.contains("no certified accelerator member here"), "{e}"); + report("fabric accelerator: no member here; refused"); return; }; - let n = fabric::AUTO_MIN_QUBITS + 1; + let n = 21; let t = Instant::now(); let cpu = ran(&job(n, json!({ "fabric": "cpu" }))).unwrap(); let cpu_ms = t.elapsed().as_millis(); let t = Instant::now(); - let auto = ran(&job(n, json!({}))).unwrap(); - let auto_ms = t.elapsed().as_millis(); + let placed = ran(&job(n, json!({ "fabric": "accelerator" }))).unwrap(); + let placed_ms = t.elapsed().as_millis(); let listed = fabric::list(CAP); let want_first = listed["members"][1]["key"].as_str().unwrap(); - assert_eq!(auto["fabric"]["key"].as_str(), Some(want_first), "auto takes the first member listed: {}", auto["fabric"]); - assert_eq!(auto["fabric"]["asked"], "auto"); - assert_eq!(answers(&auto), answers(&cpu), "auto: the answers differ from the CPU's"); - report(&format!("fabric auto: {n} qubits on {want_first} (of {first} and the rest), the CPU's answers byte for byte; cpu {cpu_ms} ms, placed {auto_ms} ms")); + assert_eq!(placed["fabric"]["key"].as_str(), Some(want_first), "accelerator takes the first member listed: {}", placed["fabric"]); + assert_eq!(placed["fabric"]["asked"], "accelerator"); + assert!(placed["fabric"].get("fell_back_from").is_none(), "{}", placed["fabric"]); + assert_eq!(answers(&placed), answers(&cpu), "accelerator: the answers differ from the CPU's"); + report(&format!("fabric accelerator: {n} qubits on {want_first} (of {first} and the rest), the CPU's answers byte for byte; cpu {cpu_ms} ms, placed {placed_ms} ms")); } #[test] -- 2.54.0 (Apple Git-157) From a11492f9133d2b9d11b11a9cc414721700609e22 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Fri, 30 Oct 2026 14:43:00 -0400 Subject: [PATCH 5/7] quantum-studio: the stabilizer-rank sum by its plain name, and the views page rebuilt The Studio's method names gain stabilizer_rank, "Stabilizer-rank sum" in English and its Simplified Chinese, so a plan or result made by it shows a name rather than the method's key. The Studio's words feed the bundled views page, so the page is rebuilt in the CI image (act-22.04, Rust 1.98.0, wasm32-unknown-unknown), where build-views --check holds it to its 48 sources; it carries this branch's engine too. Co-Authored-By: Claude Opus 5.5 --- wai/CHANGELOG.md | 4 +-- wai/quantum-studio/locales/en/frame.json | 1 + wai/quantum-studio/locales/zh-CN/frame.json | 1 + wai/quantum-studio/src/result-parts.js | 2 +- wai/wai-quantum/views/manifest.json | 27 ++++++++++---------- wai/wai-quantum/views/wai-quantum-views.html | 8 +++--- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/wai/CHANGELOG.md b/wai/CHANGELOG.md index 13deaa92a..ed4b7b29c 100644 --- a/wai/CHANGELOG.md +++ b/wai/CHANGELOG.md @@ -313,8 +313,8 @@ wire format may change and such changes are recorded here. `t`, `tdg`, `p`, `rz`, `rx` and `ry` at odd multiples of π/4, `cp` at odd multiples of π/2, `ccz` and `ccx` with the global phase kept exactly. Held to the dense state vector by every amplitude and by fidelity, never by hash. `auto` takes it for amplitudes or expectation values past the dense state vector when its branches fit one job's - work, so it is chosen by the T count; it reaches the methods list, both MCP servers and the service by the same - name. The result's accuracy, amplitudes and expectation values gain optional `t_count`, `terms`, `bound` and + work, so it is chosen by the T count; it reaches the methods list, both MCP servers, the service and the Studio + (its plain name in English and Simplified Chinese, the views page rebuilt in the CI image) by the same name. The result's accuracy, amplitudes and expectation values gain optional `t_count`, `terms`, `bound` and `confidence` (`wai.quantum.job-result/1`), and the class `estimate` now also covers a bound with the probability it holds. diff --git a/wai/quantum-studio/locales/en/frame.json b/wai/quantum-studio/locales/en/frame.json index 4840d68d6..67c4cdeb1 100644 --- a/wai/quantum-studio/locales/en/frame.json +++ b/wai/quantum-studio/locales/en/frame.json @@ -13,6 +13,7 @@ "method.tensor_network": "Tensor network", "method.cutrank": "Cut-rank sum", "method.cutrank_single": "Cut-rank sum on the GPU, single precision", + "method.stabilizer_rank": "Stabilizer-rank sum", "method.density_matrix": "Density matrix", "method.trajectories": "Trajectories", "accuracy.bit-exact": "The same bits on every machine.", diff --git a/wai/quantum-studio/locales/zh-CN/frame.json b/wai/quantum-studio/locales/zh-CN/frame.json index 4608b940b..9023a0d4f 100644 --- a/wai/quantum-studio/locales/zh-CN/frame.json +++ b/wai/quantum-studio/locales/zh-CN/frame.json @@ -13,6 +13,7 @@ "method.tensor_network": "张量网络", "method.cutrank": "割秩求和", "method.cutrank_single": "GPU 上的割秩求和,单精度", + "method.stabilizer_rank": "稳定子秩求和", "method.density_matrix": "密度矩阵", "method.trajectories": "轨迹采样", "accuracy.bit-exact": "在每台机器上都得到相同的比特。", diff --git a/wai/quantum-studio/src/result-parts.js b/wai/quantum-studio/src/result-parts.js index 5f202badb..076271998 100644 --- a/wai/quantum-studio/src/result-parts.js +++ b/wai/quantum-studio/src/result-parts.js @@ -6,7 +6,7 @@ import { el } from './dom.js'; import { t as tr } from './i18n.js'; -export const METHOD_NAMES = Object.fromEntries(['exact', 'statevector', 'statevector_single', 'stabilizer', 'pauli', 'mps', 'tensor_network', 'cutrank', 'cutrank_single', 'density_matrix', 'trajectories'].map((m) => [m, tr(`method.${m}`)])); +export const METHOD_NAMES = Object.fromEntries(['exact', 'statevector', 'statevector_single', 'stabilizer', 'pauli', 'mps', 'tensor_network', 'cutrank', 'cutrank_single', 'stabilizer_rank', 'density_matrix', 'trajectories'].map((m) => [m, tr(`method.${m}`)])); export const ACCURACY = Object.fromEntries(['bit-exact', 'exact', 'single', 'bounded', 'estimate', 'heuristic'].map((a) => [a, tr(`accuracy.${a}`)])); // A bit string short enough to read. diff --git a/wai/wai-quantum/views/manifest.json b/wai/wai-quantum/views/manifest.json index d85286db0..f6d9a5efd 100644 --- a/wai/wai-quantum/views/manifest.json +++ b/wai/wai-quantum/views/manifest.json @@ -4,19 +4,19 @@ "placeholder": "__WAI_QUANTUM_VIEW__", "limit_bytes": 1048576, "bytes": { - "page": 804920, - "script": 94428, - "styles": 50804, - "engine_wasm": 193526, - "engine_wasm_base64": 258036, + "page": 802560, + "script": 93848, + "styles": 49020, + "engine_wasm": 193530, + "engine_wasm_base64": 258040, "engine_js": 401202 }, "sha256": { - "page": "a9601c1ba22d4bb5b38a9bb3c73b28b7f7aff413059e04724236fe531c70f9c8", - "script": "47c5c3d1921b34a8f5fbf3e6d65f9436f8e6ed5f216615f4c0544e40847b3c02", - "styles": "11ebcd4416c68e9eaf1156ca6f7c92b9a96744895ed13c377eba98fdd8dca9a6", - "engine_wasm": "3033a060d86fd9b76b5aa27c729ea4cf08a2de5d9af10fe62f0308f0450e92df", - "engine_js": "8c302982ec0f4bbc07cab8eb0f1228adf8a55b92b19449b74fe431fa916b3b96" + "page": "7fcd5c7db808a247e6ea03ce9d88ecbcab06ee70c502ad2f6a342e4a28339145", + "script": "4d7997c0c814dac55b0eb56575ccde40978c503b83a1bab106340c43fa749e09", + "styles": "118b40374f3adb9c67b6ee4d54a98c7dbeab9e49c259537393d61b2c26129a4b", + "engine_wasm": "7e8e04e51a5bf479ddaea762108e0916ee8f6a79d622ca57d38fd55fe00850ed", + "engine_js": "068e6d7cd99c7f8a83b5bd5ed07a351f4c8eaf319af1ddffa0b2a3b3ee0695a1" }, "sources": { "wai/quantum-studio/build-views.mjs": "da5b161829a990b3d1bb4c1b3ec7c8f254ff7b5078476156e504ae322bc4f010", @@ -32,7 +32,7 @@ "wai/quantum-studio/locales/en/estimate_view.json": "b20c94f96751eee548b011ea19f6ded9ecd8648cae32885b6b71b7d5e631b2b1", "wai/quantum-studio/locales/en/examples.json": "dd2f2f4aef033b00b3700c6eb7151c18dd1b43537ef0beeb17a8ffc069a564b2", "wai/quantum-studio/locales/en/flags.json": "d2beeef25cee8ec742d692e424ec54bdc821449733ae98b2882cc97711efffdd", - "wai/quantum-studio/locales/en/frame.json": "608565c19197c6210b37a917ed27bbb3dbf6338cbeff23eebae2219140a3650e", + "wai/quantum-studio/locales/en/frame.json": "e92b8b8e81304c83c243688ea7ae7f8cd4f582f3e7eebc909aef79299b123c53", "wai/quantum-studio/locales/en/gallery.json": "5d0c2992e39ea0f82541e0491b46f4fd724085d95a988f8c15a1e3657d2eb149", "wai/quantum-studio/locales/en/generators.json": "85eb826cc6353cf12bc3fa45bbb8721210a311f145b9b46493c3e2bb44e7a3c2", "wai/quantum-studio/locales/en/hardware.json": "745786e872062468680655326362f49ae85dabae6ae9021145072dd4dbd7fbf1", @@ -44,7 +44,6 @@ "wai/quantum-studio/locales/en/state_views.json": "a467fe4e7c8baffa9c08dee8c66e3b12a07e4b3a6598df0a43e84340808bd037", "wai/quantum-studio/locales/en/study.json": "851328d1f199db6d2bfe2984d430b89ec5a67b890b8615e2ce14341d04b364ae", "wai/quantum-studio/locales/en/taste.json": "f26d76d981eb32755c9b7b443b94368bf715c55b3234efd44850d20b0d979386", - "wai/quantum-studio/locales/en/update.json": "fb5bd53755a51a7eebb75a839c375af660433977965266fe022b5c79a0f503ac", "wai/quantum-studio/locales/en/verdict_view.json": "24f0afd12cd8dab87d9060f3b7ca7a124f09ed450555bc9bf97db8fbfe9d3f38", "wai/quantum-studio/locales/en/versions.json": "25e491e4a7b4989db08a89b771237fb50130183ee8debd30bbd10b523dedf49c", "wai/quantum-studio/locales/en/visual_edit.json": "a192c00167a149c34070bc244e2a1b56f322bb9debb00a5db21ebaaed83900cc", @@ -55,8 +54,8 @@ "wai/quantum-studio/src/dom.js": "08bfb43472f0f07ef46353593c8fd14ed025fc4d0f1256c35cf7a3861a2cf607", "wai/quantum-studio/src/estimate-view.js": "40cb4bd738afb628dd686cdad44813d9d09910fbc60905098852dcca6cfe1b27", "wai/quantum-studio/src/i18n.js": "f661474772b05ef6614f2f6096e85d94cd479c4fcd9448f34e8d312a2fd43498", - "wai/quantum-studio/src/result-parts.js": "c0c0bceae031a45e6e9862533706eda4cf119b6f65456237c2572ed534f9513e", - "wai/quantum-studio/src/studio.css": "8891f2a1b71e1ada344ee1dc41939ba9cd41232f25ab2703d05394c141855997", + "wai/quantum-studio/src/result-parts.js": "f919bd1a76498443ff7bf996023405a61e662ba52020addf1733caab459dfb9c", + "wai/quantum-studio/src/studio.css": "5156ab565d7127f3d6cc9ea43c0cb1f020551340a1e779b6f77feae2079248f9", "wai/quantum-studio/src/tokens.css": "492fbaf8a6cc5b1f7e89346336af3e0a1930a0b48a23731d80d86c128a9032c3", "wai/quantum-studio/src/verdict-view.js": "aec18c93c6f502657ffe2981ca4d9ae0956e1277638d1a9bb1b0846ac8e80160", "wai/quantum-studio/src/views/check.js": "2edae7b446e72a49293478ebcbfe21792b74762dcfb097fb9e75ec3a4feb8d9a", diff --git a/wai/wai-quantum/views/wai-quantum-views.html b/wai/wai-quantum/views/wai-quantum-views.html index ee2cd2a47..ea30cda16 100644 --- a/wai/wai-quantum/views/wai-quantum-views.html +++ b/wai/wai-quantum/views/wai-quantum-views.html @@ -6,15 +6,15 @@ WAI Quantum -
- - -- 2.54.0 (Apple Git-157) From 6c4f6d5154c484ff3fb5270e1d2706f362975dbe Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Fri, 30 Oct 2026 20:18:48 -0400 Subject: [PATCH 6/7] wai-quantum: the agent docs blessed and the views page rebuilt with the fabric, the stabilizer-rank method and everything before them The views page was rebuilt with wai/wai-quantum-views/build.sh in catthehacker/ubuntu:act-22.04 with Rust 1.98.0, as the views workflow rebuilds it. Co-Authored-By: Claude Opus 5.5 --- wai/wai-quantum-cli/docs/llms-full.txt | 1286 +- wai/wai-quantum-cli/docs/local-mcp.json | 13211 ++++++++++++++- wai/wai-quantum-cli/docs/service-mcp.json | 14470 ++++++++++++++++- wai/wai-quantum/views/manifest.json | 25 +- wai/wai-quantum/views/wai-quantum-views.html | 8 +- 5 files changed, 28726 insertions(+), 274 deletions(-) diff --git a/wai/wai-quantum-cli/docs/llms-full.txt b/wai/wai-quantum-cli/docs/llms-full.txt index 20a94e843..f60b34090 100644 --- a/wai/wai-quantum-cli/docs/llms-full.txt +++ b/wai/wai-quantum-cli/docs/llms-full.txt @@ -46,11 +46,12 @@ Runs on this machine, signed with the user's key; nothing leaves the machine. Run an OpenQASM program on this machine, planned as the quantum job service plans it: measurement counts, Pauli expectation values and/or amplitudes, the method chosen and why, its accuracy class, and a receipt signed with this user's key. Give `intent` (an exact distribution, or a reference program it must equal or whose state it must prepare) and the engine checks it with the run. Every answer carries `verdict`: the level the engine checked to (proof, evidence, executed, parsed, refused), whether the intent holds and a plain statement, sealed in the receipt. Quote the verdict and the numbers; do not estimate them or claim more. Parameters: -- `qasm` (string, required): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. +- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. +- `qasm` (string): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. - `inputs` (object): Values for a generator's integer inputs, as {"n": 5}: the program is read as its family's circuit at those values. - `shots` (integer): Shots to sample; 1024 when nothing else is asked. - `seed` (integer): The sampling seed (default 1). -- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names. +- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. - `observables` (array): Pauli observables, as "Z0 Z1" or "0.5 X2". - `amplitudes` (array): Basis states whose amplitudes to return, as bit strings with the highest qubit first. - `noise` (object): Channel probabilities @@ -61,17 +62,20 @@ Parameters: - `intent` (any): What the program must do, checked by the engine with the run: the result's "verdict" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's "repaired" holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. +- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. +- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050). ### `plan_quantum_circuit`: Plan a quantum program The method a program would run on and why, the memory and work it would take, without running it. Parameters: -- `qasm` (string, required): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. +- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. +- `qasm` (string): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. - `inputs` (object): Values for a generator's integer inputs, as {"n": 5}: the program is read as its family's circuit at those values. - `shots` (integer): Shots to sample; 1024 when nothing else is asked. - `seed` (integer): The sampling seed (default 1). -- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names. +- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. - `observables` (array): Pauli observables, as "Z0 Z1" or "0.5 X2". - `amplitudes` (array): Basis states whose amplitudes to return, as bit strings with the highest qubit first. - `noise` (object): Channel probabilities @@ -82,6 +86,8 @@ Parameters: - `intent` (any): What the program must do, checked by the engine with the run: the result's "verdict" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's "repaired" holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. +- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. +- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050). ### `lint_qasm`: Check an OpenQASM program @@ -122,6 +128,18 @@ Parameters: - `b` (string, required): The second program. - `inputs` (object): Values for a generator's integer inputs, as {"n": 5}: the program is read as its family's circuit at those values. +### `convert_program`: Convert a program between formats + +Carry a program between OpenQASM 3, QIR (LLVM text, read under its base and adaptive profiles, written as QIR 2.0) and jeff (its Cap'n Proto message, as base64). The answer is the program written, the program as OpenQASM 3 (what every other tool takes), each note with its code (a rotation at an arbitrary angle, a custom gate read by its name, what a format leaves out), what was read and written, and the check: the output read back and held to the program by the equivalence ladder. A construct a reader cannot hold exactly is refused with its code (Q700 to Q721) and its place: quote the code, and never guess around it. + +Parameters: +- `program` (string): The program's text: OpenQASM or QIR. +- `program_base64` (string): The program's bytes as base64: jeff. +- `from` (string, one of qasm, qir, jeff): Its format; found from its bytes when not given. +- `to` (string, required, one of qasm, qir, jeff): The format to write. +- `profile` (string, one of base, adaptive): QIR's profile to write: by default base when the program's measurements all come at the end, else adaptive. +- `check` (boolean): false: write it without the check. + ### `improve_qasm`: Improve an OpenQASM program The program with its smells fixed in its own text (all of them, and each alone), each with its measures and the equivalence check's verdict against the original. A candidate the check finds different is never returned. @@ -400,11 +418,12 @@ Parameters: Run an OpenQASM program here as it would run on a device target: compiled exactly to the target's native gates, placed on the qubits and routes most likely to succeed (the expected success given beside the fewest-swaps layout's), checked against the circuit, and simulated under the noise its calibration gives (each gate's error, T1, T2 and durations, idling, and each qubit's readout), on the density matrix or by trajectories. Counts and expectation values, their distance from the ideal distribution, the noise derived, and a receipt signed with this user's key that binds the target's hash. A model of the device, not a run on it: quote it as such. Every angle must be a dyadic multiple of 2π. Parameters: -- `qasm` (string, required): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. +- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. +- `qasm` (string): The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in "inputs"). while, inv and pow are refused with their line. - `inputs` (object): Values for a generator's integer inputs, as {"n": 5}: the program is read as its family's circuit at those values. - `shots` (integer): Shots to sample; 1024 when nothing else is asked. - `seed` (integer): The sampling seed (default 1). -- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names. +- `method` (string): auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. - `observables` (array): Pauli observables, as "Z0 Z1" or "0.5 X2". - `amplitudes` (array): Basis states whose amplitudes to return, as bit strings with the highest qubit first. - `noise` (object): Channel probabilities @@ -415,6 +434,8 @@ Parameters: - `intent` (any): What the program must do, checked by the engine with the run: the result's "verdict" states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's "repaired" holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. +- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. +- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050). ### `qec_code`: Show an error-correcting code and certify its distance @@ -457,6 +478,92 @@ Parameters: - `rounds` (integer): surface: rounds (default the distance). - `seed` (integer) +### `pulse_schedule`: Read a pulse program into its schedule + +Read a pulse program (OpenPulse calibrations: ports, frames, waveforms, play, delay, shift_phase, set_phase, shift_frequency, set_frequency, captures and barriers) into its schedule on frames: every instruction at its sample, each waveform's samples (gaussian, drag, gaussian_square, constant, sech, sine, or explicit), each gate call with the samples its calibration spans, and the digests a pulse run's receipt binds (the program, its calibrations, the schedule). Durations are whole samples of dt (pulse.dt_ns, default 0.5 ns) or refused. A construct the reader does not take is refused with a Q code and its line. Sealed with this user's key. To run it, give the program to run_quantum_circuit with method "pulse". + +Parameters: +- `qasm` (string, required): A pulse program: OpenQASM 3 with `defcalgrammar "openpulse";`, `cal` blocks declaring ports (d0 drives qubit 0, m0 is its measurement port, a0 its acquisition port), frames (newframe(port, frequency Hz, phase)) and waveforms, a `defcal` for every gate it calls on physical qubits ($0), and the calls. +- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. + +### `pulse_check`: Check a pulse run by running it again + +Check a pulse job as a host returned it ({"request", "result"}, the result with its receipt): the receipt's signature, the program's digest against the request's text, and the request run again here with the result held to the one given field by field (the density matrix's digest among them), each difference named. A pulse run is the same bits on every platform, so a result that does not reproduce was not made from that request by this engine. Sealed with this user's key. Quote `verified` and the statement. + +Parameters: +- `request` (object, required): The pulse job's request. +- `result` (object, required): Its result, with its receipt. + +### `gradient_qasm`: The exact gradient of a Hamiltonian's expectation by a program's parameters + +The expectation E = ⟨ψ|H|ψ⟩ of a Hamiltonian at a program's parameters, and its gradient by each parameter, exactly: by adjoint differentiation or the parameter-shift rule on the double-precision state vector (at most 20 qubits, no noise, measurements only at the end). The reader follows each parameter into the gates, so an argument may be any expression of the built-in functions. The answer states its method, that it is f64 and approximate, and a bound on the rounding of the value and of each component (precision.rounding_bound). Sealed with this user's key. Quote the gradient with its bound. + +Parameters: +- `qasm` (string, required): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). +- `params` (object, required): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). +- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. +- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. + +### `optimize_qasm`: Minimise a Hamiltonian's expectation over a program's parameters + +Minimise E = ⟨ψ|H|ψ⟩ over a program's parameters from the given params, deterministically: gradient descent with a fixed step, Adam, or SPSA from a seeded stream (at most 2000 steps). Every step's parameters and value (and gradient, or SPSA's perturbation and estimate) are listed, each step a link of a digest chain from the request, best and final given; the same request gives the same bytes on every platform. Sealed with this user's key: the receipt binds the program, every step, the method and the seed, and verify_quantum_result (or wai-quantum verify) re-runs it. A minimum found is a minimum along this path, not a proof of the global one. + +Parameters: +- `qasm` (string, required): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). +- `params` (object, required): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). +- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. +- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). +- `steps` (integer): Steps to take (default 100). +- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). +- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. +- `seed` (integer): SPSA's seed (default 1). + +### `vqe_ground_state`: Find a Hamiltonian's ground energy by the variational eigensolver + +The variational eigensolver: an ansatz (the program given as qasm with params, or ansatz {"layers": L}: layers of ry and rz on every qubit and a ring of cx, its parameters t0, t1, … from 0.1) optimised on the Hamiltonian as optimize_qasm does. At most 8 qubits the answer sets the energy found beside the exact ground energy by diagonalisation (reference.ground_energy and gap); the energy found is never below it. Sealed with this user's key. Report the gap: an ansatz that cannot reach the ground state stops above it. + +Parameters: +- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. +- `qasm` (string): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). +- `params` (object): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). +- `ansatz` (object): The built-in ansatz in place of qasm (layers default 2, qubits the Hamiltonian's). +- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). +- `steps` (integer): Steps to take (default 100). +- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). +- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. +- `seed` (integer): SPSA's seed (default 1). + +### `qaoa_maxcut`: Solve Max-Cut on a graph by QAOA + +Max-Cut by the quantum approximate optimisation algorithm: the program (|+⟩ⁿ, then for each layer rzz(gamma·w) on every edge and rx(2·beta) on every qubit) and its cost Hamiltonian built from the graph (at most 20 vertices, 16 layers), optimised as optimize_qasm does from the params or a linear ramp, and read against the maximum cut found by brute force: the expected cut and its ratio to the maximum, the likeliest assignment and whether it is optimal, and the probability of an optimal one. Sealed with this user's key. + +Parameters: +- `graph` (object, required) +- `layers` (integer): QAOA's p (default 1). +- `params` (object): gamma_0, beta_0, … to start from. +- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). +- `steps` (integer): Steps to take (default 100). +- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). +- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. +- `seed` (integer): SPSA's seed (default 1). + +### `build_algorithm`: Write the program for a standard algorithm, checked against its reference + +An OpenQASM 3 program for a standard algorithm, with how to read its result, what it gives, and the equivalence ladder's verdict on it against a reference matrix or truth table built from the definitions (check: exact on every basis state up to 8 qubits, the adder's up to 16; past that unchecked). qpe: the phase φ of p(2πφ) on counting qubits; amplitude_estimation: the amplitude a that A = ry(2·arcsin √a) gives the good state, by phase estimation of the Grover operator; adder: the ripple-carry adder of bits-bit integers in place (with a and b, prepared and measured); qsvt: quantum signal processing from phases, of a signal x or of a real symmetric 2 × 2 matrix through its block encoding (all phases zero give the Chebyshev polynomial). Sealed with this user's key. Run the program with run_quantum_circuit. + +Parameters: +- `algorithm` (any, required, one of qpe, amplitude_estimation, adder, qsvt) +- `counting` (integer): qpe, amplitude_estimation: counting qubits (default 4). +- `phase` (number): qpe: the phase φ, in turns. +- `amplitude` (number): amplitude_estimation: the good state's probability a. +- `bits` (integer): adder: the integers' width. +- `a` (integer): adder: the first addend, prepared. +- `b` (integer): adder: the second, which the sum replaces. +- `carry_in` (boolean): adder: a carry in. +- `phases` (array): qsvt: φ₀ … φ_d, radians. +- `x` (number): qsvt: the signal. +- `matrix` (array): qsvt: [[a, b], [b, c]], real and symmetric, its eigenvalues within [-1, 1]. + ### `providers_list`: List the person's quantum providers The person's own quantum providers, as their registry lists them: each one's name, kind, protocol, endpoint or command, and where its credential is kept (never the credential itself). With free: true, also what anyone can use at no cost: the engine's methods on this machine with their limits, the free job service, and each provider whose own description states free use (this asks each provider to describe itself). @@ -496,12 +603,12 @@ Streamable HTTP, no account and no key. Run an OpenQASM program and return measurement counts, Pauli expectation values and/or amplitudes. The service chooses the method (bit-exact or double-precision state vector up to 32 qubits, single precision on a GPU to 33, stabilizer tableau for Clifford circuits up to 32768 qubits, matrix product states up to 4096, sparse Pauli dynamics for expectation values up to 1024 with an error bound, an exact density matrix or trajectories for noise), reports why and how accurate, and signs the result. Give `intent` (an exact distribution, or a reference program it must equal or whose state it must prepare) and the engine checks it with the run. Every answer carries `verdict`: the level the engine checked to (proof, evidence, executed, parsed, refused), whether the intent holds and a plain statement, sealed in the receipt. Waits up to 50 s; a longer job answers with status running and an id for get_quantum_job. Parameters: -- `qasm` (string, required): The program, OpenQASM 3 (or 2), read as the whole language: registers, aliases and slices; the standard gates, `U` and `gphase`; user `gate` definitions and `def` subroutines, inlined; every modifier (`ctrl @`, `negctrl @`, `inv @`, `pow(k) @`) on any gate, lowered exactly; classical types (int, uint, float, angle, complex, bool, bit, arrays), their arithmetic and built-in functions, computed on reading; `for`, `while`, `switch`, `break`, `continue`; measurement and `reset` anywhere; classical control on measured bits (`if (c[0]) x q[1];`, `if (c >= 2) { … } else { … }`, `&&`, `||`); a `while` on measured bits takes `@wai.max_iterations N` before it. `output` declarations come back in the result; `delay`, `box` and `stretch` are carried and labelled as not applied; `defcal` and `cal` are kept, not run. A program that measures in the middle or acts on what it measured runs on statevector or stabilizer: counts split their shots at each measurement; expectation values are exact, of the state before the final measurements. What the reader refuses comes back with a code, as `[Q103]`; qasm_diagnostics says what each code means. +- `qasm` (string): The program, OpenQASM 3 (or 2), read as the whole language: registers, aliases and slices; the standard gates, `U` and `gphase`; user `gate` definitions and `def` subroutines, inlined; every modifier (`ctrl @`, `negctrl @`, `inv @`, `pow(k) @`) on any gate, lowered exactly; classical types (int, uint, float, angle, complex, bool, bit, arrays), their arithmetic and built-in functions, computed on reading; `for`, `while`, `switch`, `break`, `continue`; measurement and `reset` anywhere; classical control on measured bits (`if (c[0]) x q[1];`, `if (c >= 2) { … } else { … }`, `&&`, `||`); a `while` on measured bits takes `@wai.max_iterations N` before it. `output` declarations come back in the result; `delay`, `box` and `stretch` are carried and labelled as not applied; `defcal` and `cal` are kept, not run. A program that measures in the middle or acts on what it measured runs on statevector or stabilizer: counts split their shots at each measurement; expectation values are exact, of the state before the final measurements. What the reader refuses comes back with a code, as `[Q103]`; qasm_diagnostics says what each code means. - `shots` (integer): Measurement shots. Default 1024 when no observables or amplitudes are asked for. - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, stabilizer_rank, density_matrix, trajectories): Leave as auto unless you need a particular method. +- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, stabilizer_rank, density_matrix, trajectories, pulse): Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. @@ -510,6 +617,9 @@ Parameters: - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. +- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. +- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. +- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes. ### `run_quantum_set`: Run a set of quantum programs, or one over a grid @@ -521,7 +631,7 @@ Parameters: - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, stabilizer_rank, density_matrix, trajectories): Leave as auto unless you need a particular method. +- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, stabilizer_rank, density_matrix, trajectories, pulse): Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. @@ -530,6 +640,8 @@ Parameters: - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. +- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. +- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes. - `programs` (array): The set's programs: each a program's text, or a job ({"qasm", …}) whose own fields win over the set's. - `sweep` (object): Each input of qasm and its values: every combination runs, the names in sorted order, the first varying slowest; an integer input's values are whole numbers. @@ -543,7 +655,7 @@ Parameters: - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, stabilizer_rank, density_matrix, trajectories): Leave as auto unless you need a particular method. +- `method` (string, one of auto, exact, statevector, statevector_single, stabilizer, pauli, mps, tensor_network, cutrank, cutrank_single, stabilizer_rank, density_matrix, trajectories, pulse): Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. @@ -552,8 +664,11 @@ Parameters: - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. - `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. +- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. +- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes. - `programs` (array): The set's programs: each a program's text, or a job ({"qasm", …}) whose own fields win over the set's. - `sweep` (object): Each input of qasm and its values: every combination runs, the names in sorted order, the first varying slowest; an integer input's values are whole numbers. +- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. ### `get_quantum_job`: Read a quantum job @@ -585,6 +700,18 @@ Parameters: - `a` (string, required) - `b` (string, required) +### `convert_program`: Convert a program between formats + +Carry a program between OpenQASM 3, QIR (LLVM text, read under its base and adaptive profiles, written as QIR 2.0) and jeff (its Cap'n Proto message, as base64). The answer is the program written, the program as OpenQASM 3 (what every other tool takes), each note with its code (a rotation at an arbitrary angle, a custom gate read by its name, what a format leaves out), what was read and written, and the check: the output read back and held to the program by the equivalence ladder. A construct a reader cannot hold exactly is refused with its code (Q700 to Q721) and its place: quote the code, and never guess around it. A conversion larger than the service takes is refused with the command that runs it locally. + +Parameters: +- `program` (string): The program's text: OpenQASM or QIR. +- `program_base64` (string): The program's bytes as base64: jeff. +- `from` (string, one of qasm, qir, jeff): Its format; found from its bytes when not given. +- `to` (string, required, one of qasm, qir, jeff): The format to write. +- `profile` (string, one of base, adaptive): QIR's profile to write: by default base when the program's measurements all come at the end, else adaptive. +- `check` (boolean): false: write it without the check. + ### `improve_qasm`: Improve a quantum program The program with its smells fixed in its own text (all of them, and each alone), each candidate with its measures and the equivalence check's verdict against the program. A candidate the check finds different is never returned. @@ -665,12 +792,12 @@ Parameters: Run an OpenQASM program as it would run on a device target: compiled exactly to its gates, placed on its most reliable qubits and routes (the expected success given), checked against the circuit, and simulated under the noise its calibration gives, on the density matrix or by trajectories. Counts and expectation values with their distance from the ideal distribution, the noise derived, and a receipt that binds the target's hash. A model of the device, not a run on it. Every angle must be a dyadic multiple of 2π. Waits up to 50 s, as run_quantum_circuit does. Parameters: -- `qasm` (string, required): The program, OpenQASM 3 (or 2), read as the whole language: registers, aliases and slices; the standard gates, `U` and `gphase`; user `gate` definitions and `def` subroutines, inlined; every modifier (`ctrl @`, `negctrl @`, `inv @`, `pow(k) @`) on any gate, lowered exactly; classical types (int, uint, float, angle, complex, bool, bit, arrays), their arithmetic and built-in functions, computed on reading; `for`, `while`, `switch`, `break`, `continue`; measurement and `reset` anywhere; classical control on measured bits (`if (c[0]) x q[1];`, `if (c >= 2) { … } else { … }`, `&&`, `||`); a `while` on measured bits takes `@wai.max_iterations N` before it. `output` declarations come back in the result; `delay`, `box` and `stretch` are carried and labelled as not applied; `defcal` and `cal` are kept, not run. A program that measures in the middle or acts on what it measured runs on statevector or stabilizer: counts split their shots at each measurement; expectation values are exact, of the state before the final measurements. What the reader refuses comes back with a code, as `[Q103]`; qasm_diagnostics says what each code means. +- `qasm` (string): The program, OpenQASM 3 (or 2), read as the whole language: registers, aliases and slices; the standard gates, `U` and `gphase`; user `gate` definitions and `def` subroutines, inlined; every modifier (`ctrl @`, `negctrl @`, `inv @`, `pow(k) @`) on any gate, lowered exactly; classical types (int, uint, float, angle, complex, bool, bit, arrays), their arithmetic and built-in functions, computed on reading; `for`, `while`, `switch`, `break`, `continue`; measurement and `reset` anywhere; classical control on measured bits (`if (c[0]) x q[1];`, `if (c >= 2) { … } else { … }`, `&&`, `||`); a `while` on measured bits takes `@wai.max_iterations N` before it. `output` declarations come back in the result; `delay`, `box` and `stretch` are carried and labelled as not applied; `defcal` and `cal` are kept, not run. A program that measures in the middle or acts on what it measured runs on statevector or stabilizer: counts split their shots at each measurement; expectation values are exact, of the state before the final measurements. What the reader refuses comes back with a code, as `[Q103]`; qasm_diagnostics says what each code means. - `shots` (integer): Measurement shots. Default 1024 when no observables or amplitudes are asked for. - `observables` (array): Pauli strings to take expectation values of, e.g. ["Z0", "Z0 Z1", "X2 Y3"]. Qubits count from 0. - `amplitudes` (array): Basis states to give amplitudes of: one character per qubit, qubit n-1 first, e.g. "0011". - `noise` (object): Optional noise, each a probability: depolarizing_1q, depolarizing_2q, amplitude_damping, dephasing (after each gate on its qubits), readout (each measured bit). -- `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. +- `params` (object): A value for each of the program's parameters (input float theta;, input angle phi;), as {"theta": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes. - `seed` (integer): Sampling seed (default 1); the same job and seed give the same counts. - `options` (object): Advanced, per method: max_bond (mps), threshold and max_terms (pauli), fusion (statevector), trajectories. - `compile` (object): Compile the program first (as compile_qasm does) and run the compiled circuit: with basis clifford_t it runs bit-exact, and the result's `compiled` states its distance from the program. @@ -678,6 +805,9 @@ Parameters: - `fabric` (any): Where the statevector method's state runs: auto (the default: on the CPU, until a member is measured faster than the CPU), cpu, accelerator (any certified accelerator member), a member's id or key, or a list of members, a power of two of them, the state split by its top qubits into one partition on each. Every member placed is certified bit-exact against the CPU, so the answers are the CPU's; the result's `fabric` names where the state ran, sealed by the receipt. A placement the service cannot honour is refused (J013): it places only on its CPU. - `intent` (any): What the program must do, checked by the engine with the run: the result's `verdict` states how far it checked (proof, evidence, executed, parsed, refused) and whether the intent holds, sealed by the receipt. - `repair` (any): Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {"max_iterations": N, "dyadic_bits": K, "sizes": {"q": 3}}. The result's `repaired` holds the program that ran and each repair. +- `mitigate` (any): Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object. +- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. +- `source` (object): The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source. ### `quantum_circuit_examples`: Ready-to-run quantum examples @@ -724,6 +854,92 @@ Parameters: - `rounds` (integer): surface: rounds (default the distance). - `seed` (integer) +### `pulse_schedule`: Read a pulse program into its schedule + +Read a pulse program (OpenPulse calibrations: ports, frames, waveforms, play, delay, shift_phase, set_phase, shift_frequency, set_frequency, captures and barriers) into its schedule on frames: every instruction at its sample, each waveform's samples (gaussian, drag, gaussian_square, constant, sech, sine, or explicit), each gate call with the samples its calibration spans, and the digests a pulse run's receipt binds (the program, its calibrations, the schedule). Durations are whole samples of dt (pulse.dt_ns, default 0.5 ns) or refused. A construct the reader does not take is refused with a Q code and its line. Sealed with the service's key. To run it, give the program to run_quantum_circuit with method "pulse". + +Parameters: +- `qasm` (string, required): A pulse program: OpenQASM 3 with `defcalgrammar "openpulse";`, `cal` blocks declaring ports (d0 drives qubit 0, m0 is its measurement port, a0 its acquisition port), frames (newframe(port, frequency Hz, phase)) and waveforms, a `defcal` for every gate it calls on physical qubits ($0), and the calls. +- `pulse` (object): A pulse run's options (method "pulse"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0. + +### `pulse_check`: Check a pulse run by running it again + +Check a pulse job as a host returned it ({"request", "result"}, the result with its receipt): the receipt's signature, the program's digest against the request's text, and the request run again here with the result held to the one given field by field (the density matrix's digest among them), each difference named. A pulse run is the same bits on every platform, so a result that does not reproduce was not made from that request by this engine. Sealed with the service's key. Quote `verified` and the statement. + +Parameters: +- `request` (object, required): The pulse job's request. +- `result` (object, required): Its result, with its receipt. + +### `gradient_qasm`: The exact gradient of a Hamiltonian's expectation by a program's parameters + +The expectation E = ⟨ψ|H|ψ⟩ of a Hamiltonian at a program's parameters, and its gradient by each parameter, exactly: by adjoint differentiation or the parameter-shift rule on the double-precision state vector (at most 20 qubits, no noise, measurements only at the end). The reader follows each parameter into the gates, so an argument may be any expression of the built-in functions. The answer states its method, that it is f64 and approximate, and a bound on the rounding of the value and of each component (precision.rounding_bound). Sealed with the service's key. Quote the gradient with its bound. + +Parameters: +- `qasm` (string, required): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). +- `params` (object, required): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). +- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. +- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. + +### `optimize_qasm`: Minimise a Hamiltonian's expectation over a program's parameters + +Minimise E = ⟨ψ|H|ψ⟩ over a program's parameters from the given params, deterministically: gradient descent with a fixed step, Adam, or SPSA from a seeded stream (at most 2000 steps). Every step's parameters and value (and gradient, or SPSA's perturbation and estimate) are listed, each step a link of a digest chain from the request, best and final given; the same request gives the same bytes on every platform. Sealed with the service's key: the receipt binds the program, every step, the method and the seed, and verify_quantum_result (or wai-quantum verify) re-runs it. A minimum found is a minimum along this path, not a proof of the global one. + +Parameters: +- `qasm` (string, required): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). +- `params` (object, required): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). +- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. +- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). +- `steps` (integer): Steps to take (default 100). +- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). +- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. +- `seed` (integer): SPSA's seed (default 1). + +### `vqe_ground_state`: Find a Hamiltonian's ground energy by the variational eigensolver + +The variational eigensolver: an ansatz (the program given as qasm with params, or ansatz {"layers": L}: layers of ry and rz on every qubit and a ring of cx, its parameters t0, t1, … from 0.1) optimised on the Hamiltonian as optimize_qasm does. At most 8 qubits the answer sets the energy found beside the exact ground energy by diagonalisation (reference.ground_energy and gap); the energy found is never below it. Sealed with the service's key. Report the gap: an ansatz that cannot reach the ground state stops above it. + +Parameters: +- `hamiltonian` (array, required): A Hamiltonian as Pauli terms summed: "Z0 Z1", "0.5 X2", "-1.5" (a constant), or {"pauli": "Y0 Y1", "coeff": -0.7}; qubit 0 is q[0]. +- `qasm` (string): The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129). +- `params` (object): A value for each parameter, by name, as {"theta": 0.3}: bound exactly. Every parameter the program declares needs one (J050). +- `ansatz` (object): The built-in ansatz in place of qasm (layers default 2, qubits the Hamiltonian's). +- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). +- `steps` (integer): Steps to take (default 100). +- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). +- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. +- `seed` (integer): SPSA's seed (default 1). + +### `qaoa_maxcut`: Solve Max-Cut on a graph by QAOA + +Max-Cut by the quantum approximate optimisation algorithm: the program (|+⟩ⁿ, then for each layer rzz(gamma·w) on every edge and rx(2·beta) on every qubit) and its cost Hamiltonian built from the graph (at most 20 vertices, 16 layers), optimised as optimize_qasm does from the params or a linear ramp, and read against the maximum cut found by brute force: the expected cut and its ratio to the maximum, the likeliest assignment and whether it is optimal, and the probability of an optimal one. Sealed with the service's key. + +Parameters: +- `graph` (object, required) +- `layers` (integer): QAOA's p (default 1). +- `params` (object): gamma_0, beta_0, … to start from. +- `optimizer` (any): gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma). +- `steps` (integer): Steps to take (default 100). +- `step_size` (number): The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2). +- `gradient` (any, one of adjoint, parameter_shift): adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding. +- `seed` (integer): SPSA's seed (default 1). + +### `build_algorithm`: Write the program for a standard algorithm, checked against its reference + +An OpenQASM 3 program for a standard algorithm, with how to read its result, what it gives, and the equivalence ladder's verdict on it against a reference matrix or truth table built from the definitions (check: exact on every basis state up to 8 qubits, the adder's up to 16; past that unchecked). qpe: the phase φ of p(2πφ) on counting qubits; amplitude_estimation: the amplitude a that A = ry(2·arcsin √a) gives the good state, by phase estimation of the Grover operator; adder: the ripple-carry adder of bits-bit integers in place (with a and b, prepared and measured); qsvt: quantum signal processing from phases, of a signal x or of a real symmetric 2 × 2 matrix through its block encoding (all phases zero give the Chebyshev polynomial). Sealed with the service's key. Run the program with run_quantum_circuit. + +Parameters: +- `algorithm` (any, required, one of qpe, amplitude_estimation, adder, qsvt) +- `counting` (integer): qpe, amplitude_estimation: counting qubits (default 4). +- `phase` (number): qpe: the phase φ, in turns. +- `amplitude` (number): amplitude_estimation: the good state's probability a. +- `bits` (integer): adder: the integers' width. +- `a` (integer): adder: the first addend, prepared. +- `b` (integer): adder: the second, which the sum replaces. +- `carry_in` (boolean): adder: a carry in. +- `phases` (array): qsvt: φ₀ … φ_d, radians. +- `x` (number): qsvt: the signal. +- `matrix` (array): qsvt: [[a, b], [b, c]], real and symmetric, its eigenvalues within [-1, 1]. + ## Resources, on both servers ### `wai-quantum://docs/language`: the OpenQASM the engine reads @@ -775,7 +991,8 @@ Each construct below is supported (read as the language defines it), lowered (re | `array[T, d1, d2, …]`, nested values, `sizeof` | supported | Q107, Q110 | | `const` | supported: known on reading; not assignable | Q127 | | `input int n;`, `input uint n;` | supported: given when the program is read (a generator) | Q114 | -| `input` of another type | refused: only integers take values | Q115 | +| `input float theta;`, `input angle phi;` | a parameter: a job's `params` binds it as a `const` at exactly the double given before the program is read (left without a value, the job is refused with Q114 and J050); the reader alone gives it no value | Q115 | +| a parameter followed into a gradient | supported through arithmetic, the built-in functions, loops and gate definitions into gates' arguments; refused under a modifier, in a classical variable, a condition, an index, a size, a loop's range, a subroutine, or a type that rounds it | Q129 | | `output` | carried into the result: a bit register's places in each outcome, or a value | Q600, Q601 | | `let a = q[0:2] ++ r;` | supported; a `let` that reuses an enclosing scope's name is refused | Q101 | | `extern f(…) -> T;` | supported as a declaration; a call is refused | Q125 | @@ -875,9 +1092,15 @@ Each construct below is supported (read as the language defines it), lowered (re | Construct | Status | Codes | |---|---|---| -| `defcalgrammar "openpulse";` | preserved | Q452 | -| `cal { … }` | preserved, never run | Q451 | -| `defcal …` | preserved, never run; the gate's matrix comes from its definition or the library | Q450, Q126 | +| `defcalgrammar "openpulse";` | preserved; in a pulse run, read (another grammar is refused) | Q452, Q454 | +| `cal { … }` | preserved, never run by the circuit methods; in a pulse run, read as OpenPulse and run in order | Q451, Q453 | +| `defcal …` | preserved, never run by the circuit methods; the gate's matrix comes from its definition or the library. In a pulse run, read as OpenPulse and run at each call on its physical qubits | Q450, Q126, Q453, Q459 | +| Ports, frames, waveforms (`constant`, `gaussian`, `sech`, `gaussian_square`, `drag`, `sine`, explicit samples) | in a pulse run, lowered to the schedule | Q453, Q455 to Q458 | +| `play`, `delay`, `shift_phase`, `set_phase`, `shift_frequency`, `set_frequency`, `capture_v0` to `capture_v4`, `barrier` | in a pulse run, lowered to the schedule on frames | Q453, Q457, Q458, Q461 | +| Plays on a measurement port | in a pulse run, scheduled and timed; the readout is not simulated | Q462 | + +A pulse run is the job method `pulse`; [the pulse page](pulse.md) gives the +model, the bound and the options. #### The bit-exact method @@ -973,6 +1196,7 @@ Every code: | `Q126` | refused | A call of an `opaque` gate, or of a gate with only a calibration: its matrix is not known. | | `Q127` | refused | An assignment to a constant, an input or a loop variable. | | `Q128` | refused | A measurement where a value is needed that is not a bit (measurement gives bits, into a bit register). | +| `Q129` | refused | A parameter (`input float`, `input angle`) a gradient cannot follow to the gates: under a modifier, in a classical variable, a condition, an index, a size, a loop's range, a subroutine or `gphase`, or one whose type rounds it (`angle[n]`, `float[32]`); a gradient follows a parameter through arithmetic, the built-in functions and gate definitions into a gate's arguments. | | `Q200` | lowered | A `gate` the program defines, inlined at each call with its parameters bound. | | `Q201` | lowered | `ctrl @` and `negctrl @` on any gate, lowered exactly to standard gates (a negative control is a control between two `x`). | | `Q202` | lowered | `inv @` on any gate, user gates included: each gate's exact inverse, in reverse order. | @@ -1020,11 +1244,40 @@ Every code: | `Q450` | preserved | `defcal`: kept verbatim for export, never executed; the gate's matrix comes from its `gate` definition or the standard library. | | `Q451` | preserved | `cal { … }`: kept verbatim for export, never executed. | | `Q452` | preserved | `defcalgrammar`: kept verbatim for export. | +| `Q453` | lowered | In a pulse run, a `cal` or `defcal` body read as OpenPulse and lowered to the schedule on frames (plays, delays, phase and frequency changes, captures and barriers) that the pulse simulator integrates. | +| `Q454` | refused | In a pulse run, a `defcalgrammar` other than `"openpulse"`: the pulse reader reads OpenPulse alone. | +| `Q455` | refused | A statement in a calibration that the pulse reader does not take: classical control, a frame's attributes or `get_phase`, an `extern` function, a frame made inside a `defcal`, a nested calibration, or a `defcal` over qubit arguments (the message names it and what to write instead). | +| `Q456` | refused | A waveform that does not read: a template the reader does not know, arguments of the wrong number or kind, a length or a width that is not positive, a sample that is not a number, or more samples than it holds. | +| `Q457` | refused | A frame or a port that does not read: a play, a delay or a phase or frequency change on a name that is not a frame, `newframe` on a name that is not a port, a frequency that is not a number, or a port that reaches no qubit. | +| `Q458` | refused | A duration in a calibration that is not a whole, non-negative number of samples at the sample period (`dt`), or a schedule longer than the reader holds. | +| `Q459` | refused | In a pulse run, a gate or a measurement on physical qubits that no `defcal` calibrates for those qubits and those parameters. | +| `Q460` | refused | In a pulse run, a statement outside the calibrations that the pulse reader does not take: declared qubits (a pulse program names physical qubits, `$0`), a modifier, `reset`, classical control, a subroutine, or a measurement into something other than a bit. | +| `Q461` | refused | A capture that does not read: not on a frame of an acquisition port, without a duration or a waveform, or its result put somewhere other than a bit. | +| `Q462` | warned | A play on a measurement port: scheduled and timed, its effect on the readout not simulated (a capture reads the qubit's state). | | `Q500` | refused | An angle that is not a dyadic multiple of 2π (2πm/2^k, k ≤ 32): the bit-exact method refuses it, never rounds it; the methods in double precision take it. | | `Q501` | refused | More than 255 qubits for the bit-exact circuit. | | `Q502` | refused | A program that measures a qubit and then acts on it, resets one after its first gate, or acts on measured bits: the bit-exact circuit takes programs whose measurements all come at the end. | | `Q600` | carried | An `output` declaration, carried into the result: its bits (their places in each outcome) or its value. | | `Q601` | refused | An `output` that is not a bit and whose value depends on a measurement at the end. | +| `Q700` | refused | A file that does not read in the format named: QIR that is not LLVM text with one entry point, or jeff that is not a Cap'n Proto message of the jeff schema (a pointer outside the message, a struct or list of the wrong shape, more than the reader takes); the message says what and where. | +| `Q701` | refused | A format version the reader does not take: QIR whose `qir_major_version` is not 1 or 2, or jeff other than 0.2 and 0.3. | +| `Q702` | warned | A QIR module that leaves out what its profile requires (the `qir_profiles` attribute, the version flags, `required_num_qubits`, `required_num_results`, the `entry_point` attribute of its only function): read from what it holds, and said so. | +| `Q703` | refused | A QIR profile the reader does not take: `qir_profiles` names neither `base_profile` nor `adaptive_profile`. | +| `Q704` | refused | What the module's own QIR profile forbids: under the base profile a branch, a classical instruction, reading a result, or a gate or reset on a qubit after its measurement; under the adaptive profile an optional capability its module flags do not declare (computation on integers or floats of a type, IR-defined functions, loops, `switch`, several returns, dynamic qubits or results, arrays). | +| `Q705` | refused | A QIR capability the module may use that this reader does not take: loops, `switch`, `phi`, IR-defined functions, dynamic allocation of qubits or results, arrays, controlled forms that take their controls in an array, or a classical value computed from a measurement anywhere but a branch's condition. | +| `Q706` | refused | An instruction or function the reader does not know: a quantum intrinsic outside the gates it reads (`docs/formats.md` lists them), a runtime function it does not take, an LLVM instruction no profile lists, or a function a module declares and does not define. | +| `Q707` | refused | A QIR operand that does not read: a qubit or result that is not a constant index, an index past `required_num_qubits` or `required_num_results`, or an angle that is not a finite number known on reading. | +| `Q708` | refused | A value whose meaning the program's text cannot keep: in QIR a result read, measured again and only then branched on; in jeff a qubit the two sides of a branch on a measurement leave in different places. | +| `Q709` | warned | Rotations at angles that are not dyadic multiples of 2π, read at their exact doubles: the double-precision methods take them; the bit-exact method refuses them (Q500). | +| `Q710` | refused | A jeff custom gate the reader does not know: its name is not a gate of the standard library (in any case), or its qubits or parameters are not that gate's. | +| `Q711` | warned | A jeff custom gate named as a gate of the standard library (`H`, `CX`, `Rx`, in any case) with that gate's qubits and parameters: read as that gate, by its name alone. | +| `Q712` | lowered | A jeff Pauli-product rotation, `exp(iθP)` as its schema defines it, lowered exactly to basis changes, a parity ladder and one `rz`. | +| `Q713` | refused | A jeff value used where it cannot be: a qubit or register used twice, a value used before it is defined or never defined, a cycle, or a value of the wrong type or count for its operation. | +| `Q714` | refused | A jeff value the reader needs on reading and cannot know: a gate angle, a loop's bounds or a `while` condition from a measurement, a register's size or index, a `switch` on a value that is neither known nor a measured bit, or integer arithmetic on a measured bit beyond not, and, or, xor, eq and select. | +| `Q715` | lowered | jeff's structured control flow: a `for` or `while` decided on reading unrolled, a `switch` on a known value decided, a `switch` on a measured bit written as `if … else`, and a call of a function the module defines inlined. | +| `Q716` | warned | A jeff entry point that takes qubits: they are the program's first qubits, starting in \|0⟩, and the qubits it returns are not measured. | +| `Q720` | refused | A program the format written cannot hold as it is: under QIR's base profile a measurement in the middle, a reset after a gate or a condition (write the adaptive profile), a loop in QIR, or in jeff a branch on a measured bit. | +| `Q721` | warned | What the format read or written has no place for, left out and said so: delays, boxes, barriers and gate durations, calibrations, `output` declarations, and classical values recorded as output. | ### `wai-quantum://docs/methods`: the methods and their accuracy classes @@ -1042,6 +1295,7 @@ Every code: | `cutrank_single` | single | as for cutrank; the table on a GPU, its arithmetic in single precision | counts, amplitudes | | `density_matrix` | exact | any, with noise | counts, expectations | | `trajectories` | estimate | any, with noise | counts, expectations | +| `pulse` | bounded | pulse programs: OpenPulse calibrations (cal, defcal) on physical qubits, every gate called with its calibration | counts, populations, captures | The accuracy classes: @@ -1294,6 +1548,10 @@ Commands: run Run a program here, planned as the job service plans it, and sign the result plan Show the method a program would run on and why, without running it instance Write a generator out at its `--input` values, as plain OpenQASM + convert Carry a program between formats (OpenQASM 3, QIR as LLVM text, jeff), every + conversion checked: what is written is read back and held to the program by the + equivalence ladder; notes and the check go to standard error (exit 1 refused, 2 the + check found it different) lint Check a program and print each problem with its line draw Draw a program's circuit: as text, or as an SVG image, LaTeX (plain TikZ) or words debug Step through a program on the engine's exact methods and look into the state at a @@ -1317,6 +1575,18 @@ Commands: Toffolis, rotations at their synthesised T counts, depth, qubits with ancillas), physical qubits, runtime and factories, and the frontier between qubits and time, each estimate signed (`wai-quantum estimate --help`) + gradient The expectation of a Hamiltonian at a program's parameters and its exact gradient by + each (adjoint differentiation or the parameter-shift rule, in f64 with a stated + rounding bound), signed + optimize Minimise a Hamiltonian's expectation over a program's parameters: gradient descent, + Adam or SPSA from a seed, every step in a digest chain the receipt seals + vqe The variational eigensolver: an ansatz optimised on a Hamiltonian, the energy found + set beside the exact ground energy by diagonalisation + qaoa Max-Cut on a graph by QAOA: the program and its cost built from the graph, optimised, + and the cut set beside the maximum cut by brute force + build A standard algorithm's program (qpe, amplitude_estimation, adder, qsvt) on standard + output, checked by the equivalence ladder against a reference built from its + definition repair Repair a program from its diagnostics, on the lines they flag alone: the mechanical fixes, a proposed fix checked against those lines, and what needs a person (exit 0 it reads, 1 something needs a person, 2 a proposal rejected) @@ -1370,6 +1640,9 @@ Commands: qec Error correction: a code and its certified distance, a syndrome or a circuit's detectors decoded, a threshold measured, each answer signed (`wai-quantum qec --help`) + pulse Pulse programs: a program's schedule on frames drawn as a timeline, and a pulse job + checked by running it again; a pulse program runs with `run --method pulse` + (`wai-quantum pulse --help`) eval Score a model on a task set with the engine: whether its program reads, the verdict's level and whether the intent holds, and the joules per solved task where its server's energy is metered; or write each task's answer three ways for a token count @@ -1404,6 +1677,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -1437,6 +1714,10 @@ Options: --seed The seed shots are sampled with (1 if not given) + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --method A method by name, or auto (the default) for the strongest the program admits; `wai-quantum methods` lists them @@ -1503,6 +1784,14 @@ Options: pea, pec, cdr, vd or readout, or its options as JSON ({"method": "pea", "factors": [1, 1.5, 2]}) + --pulse + A pulse run's options (with --method pulse), as JSON or a file of it: dt_ns, levels, + tolerance, substeps, qubits, couplings and ports (`wai-quantum pulse --help`) + + --param + A parameter's value, as theta=0.3 (repeatable): each `input float` and `input angle` of + the program, bound exactly (the job's "params"); in a sweep, the parameters it fixes + --fabric Where the state vector runs (the statevector method): auto (the default: the CPU, until a member is measured faster), cpu, accelerator (the first certified accelerator member that @@ -1571,6 +1860,10 @@ Options: --seed The seed shots are sampled with (1 if not given) + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --method A method by name, or auto (the default) for the strongest the program admits; `wai-quantum methods` lists them @@ -1637,6 +1930,14 @@ Options: pea, pec, cdr, vd or readout, or its options as JSON ({"method": "pea", "factors": [1, 1.5, 2]}) + --pulse + A pulse run's options (with --method pulse), as JSON or a file of it: dt_ns, levels, + tolerance, substeps, qubits, couplings and ports (`wai-quantum pulse --help`) + + --param + A parameter's value, as theta=0.3 (repeatable): each `input float` and `input angle` of + the program, bound exactly (the job's "params"); in a sweep, the parameters it fixes + --fabric Where the state vector runs (the statevector method): auto (the default: the CPU, until a member is measured faster), cpu, accelerator (the first certified accelerator member that @@ -1675,6 +1976,61 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + + -h, --help + Print help + + -V, --version + Print version +``` + +### `wai-quantum convert` + +```text +Carry a program between formats (OpenQASM 3, QIR as LLVM text, jeff), every conversion checked: what +is written is read back and held to the program by the equivalence ladder; notes and the check go to +standard error (exit 1 refused, 2 the check found it different) + +Usage: wai-quantum convert [OPTIONS] --to [FILE] + +Arguments: + [FILE] + The program; `-` or nothing reads standard input; its format is --from, else its + extension, else what its bytes look like + +Options: + --input + A value for a generator's integer `input`, as n=5 (repeat for each input): the program is + read as its family's circuit at those values + + --to + The format to write: qasm, qir or jeff + + --lang + The language of the words the command line writes itself, en or zh-CN (by default the one + LANG names); results, codes and the engine's own messages stay in English + + --profile + QIR's profile, base or adaptive: by default the base profile when the program's + measurements all come at the end, else the adaptive one + + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + + -o, --output + Write the program to this file (jeff is binary: give a file, or --json for its base64) + + --json + Print the conversion as JSON: the program (base64 for jeff), the program as OpenQASM, the + notes, what was read and written, and the check + + --no-check + Write it without the check + -h, --help Print help @@ -1705,6 +2061,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -1740,6 +2100,10 @@ Options: --svg The drawing as a standalone SVG image, the Studio's picture + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --latex The drawing as LaTeX: one picture in plain TikZ, which needs only \usepackage{tikz} @@ -1781,6 +2145,10 @@ Options: --line Stop before the first step on this line + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --outcomes The outcome of each measurement (and reset) the path meets, in order, as 0,1,1; the likelier when not given @@ -1835,6 +2203,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -1866,6 +2238,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -1900,6 +2276,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -1932,6 +2312,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -1967,6 +2351,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -2014,6 +2402,10 @@ Options: [default: clifford_t] + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --twirl Twirl each two-qubit Clifford gate with Paulis drawn from this seed (one instance; checked to be the same gate) @@ -2081,6 +2473,10 @@ Options: [default: 0.001] + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --qubit A reference qubit (us-e3, us-e4, ns-e3, ns-e4, meas-e4, meas-e6), `all` of them, or a JSON file describing one @@ -2123,6 +2519,345 @@ Options: Print version ``` +### `wai-quantum gradient` + +```text +The expectation of a Hamiltonian at a program's parameters and its exact gradient by each (adjoint +differentiation or the parameter-shift rule, in f64 with a stated rounding bound), signed + +Usage: wai-quantum gradient [OPTIONS] [FILE] + +Arguments: + [FILE] + The program; `-` or nothing reads standard input + +Options: + --input + A value for a generator's integer `input`, as n=5 (repeat for each input): the program is + read as its family's circuit at those values + + --param + A parameter's value, as theta=0.3 (repeatable): every `input float` and `input angle` the + program declares needs one + + --lang + The language of the words the command line writes itself, en or zh-CN (by default the one + LANG names); results, codes and the engine's own messages stay in English + + --term + A term of the Hamiltonian, as "Z0 Z1", "0.5 X2" or "-1.5" (a constant) (repeatable; the + terms are summed) + + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + + --hamiltonian + The Hamiltonian as a JSON list of terms, in place of --term + + --gradient + adjoint (the default: one pass forward, one back) or parameter_shift (each gate a + parameter moves run at shifted angles) + + --json + Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) + + --key + Sign with the key in this file (64 hex digits) + + --demo-key + Sign with the published demo key: the receipt then shows a result is unaltered, not who + signed it + + -h, --help + Print help + + -V, --version + Print version +``` + +### `wai-quantum optimize` + +```text +Minimise a Hamiltonian's expectation over a program's parameters: gradient descent, Adam or SPSA +from a seed, every step in a digest chain the receipt seals + +Usage: wai-quantum optimize [OPTIONS] [FILE] + +Arguments: + [FILE] + The program; `-` or nothing reads standard input + +Options: + --input + A value for a generator's integer `input`, as n=5 (repeat for each input): the program is + read as its family's circuit at those values + + --param + A parameter's value, as theta=0.3 (repeatable): every `input float` and `input angle` the + program declares needs one + + --lang + The language of the words the command line writes itself, en or zh-CN (by default the one + LANG names); results, codes and the engine's own messages stay in English + + --term + A term of the Hamiltonian, as "Z0 Z1", "0.5 X2" or "-1.5" (a constant) (repeatable; the + terms are summed) + + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + + --hamiltonian + The Hamiltonian as a JSON list of terms, in place of --term + + --gradient + adjoint (the default: one pass forward, one back) or parameter_shift (each gate a + parameter moves run at shifted angles) + + --optimizer + gradient_descent, adam (the default) or spsa, or its settings as JSON ({"name": "adam", + "beta1": 0.9}) + + --steps + Steps to take (default 100) + + --step-size + The step (gradient descent 0.1, Adam 0.05), or SPSA's gain a (0.2) + + --seed + SPSA's seed (default 1) + + --json + Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) + + --key + Sign with the key in this file (64 hex digits) + + --demo-key + Sign with the published demo key: the receipt then shows a result is unaltered, not who + signed it + + -h, --help + Print help + + -V, --version + Print version +``` + +### `wai-quantum vqe` + +```text +The variational eigensolver: an ansatz optimised on a Hamiltonian, the energy found set beside the +exact ground energy by diagonalisation + +Usage: wai-quantum vqe [OPTIONS] [FILE] + +Arguments: + [FILE] + The program; `-` or nothing reads standard input + +Options: + --input + A value for a generator's integer `input`, as n=5 (repeat for each input): the program is + read as its family's circuit at those values + + --param + A parameter's value, as theta=0.3 (repeatable): every `input float` and `input angle` the + program declares needs one + + --lang + The language of the words the command line writes itself, en or zh-CN (by default the one + LANG names); results, codes and the engine's own messages stay in English + + --term + A term of the Hamiltonian, as "Z0 Z1", "0.5 X2" or "-1.5" (a constant) (repeatable; the + terms are summed) + + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + + --hamiltonian + The Hamiltonian as a JSON list of terms, in place of --term + + --gradient + adjoint (the default: one pass forward, one back) or parameter_shift (each gate a + parameter moves run at shifted angles) + + --layers + The built-in ansatz in place of a program: this many layers of ry and rz on every qubit + and a ring of cx, its parameters t0, t1, … from 0.1 + + --qubits + With --layers: the ansatz's qubits (default the Hamiltonian's) + + --optimizer + gradient_descent, adam (the default) or spsa, or its settings as JSON ({"name": "adam", + "beta1": 0.9}) + + --steps + Steps to take (default 100) + + --step-size + The step (gradient descent 0.1, Adam 0.05), or SPSA's gain a (0.2) + + --seed + SPSA's seed (default 1) + + --json + Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) + + --key + Sign with the key in this file (64 hex digits) + + --demo-key + Sign with the published demo key: the receipt then shows a result is unaltered, not who + signed it + + -h, --help + Print help + + -V, --version + Print version +``` + +### `wai-quantum qaoa` + +```text +Max-Cut on a graph by QAOA: the program and its cost built from the graph, optimised, and the cut +set beside the maximum cut by brute force + +Usage: wai-quantum qaoa [OPTIONS] --graph + +Options: + --graph + The graph as JSON: {"nodes": n, "edges": [[0, 1], [1, 2, 0.5]]} + + --input + A value for a generator's integer `input`, as n=5 (repeat for each input): the program is + read as its family's circuit at those values + + --lang + The language of the words the command line writes itself, en or zh-CN (by default the one + LANG names); results, codes and the engine's own messages stay in English + + --layers + QAOA's layers, p (default 1) + + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + + --param + A starting value, as gamma_0=0.4 (repeatable; default a linear ramp) + + --gradient + adjoint (the default) or parameter_shift + + --optimizer + gradient_descent, adam (the default) or spsa, or its settings as JSON ({"name": "adam", + "beta1": 0.9}) + + --steps + Steps to take (default 100) + + --step-size + The step (gradient descent 0.1, Adam 0.05), or SPSA's gain a (0.2) + + --seed + SPSA's seed (default 1) + + --json + Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) + + --key + Sign with the key in this file (64 hex digits) + + --demo-key + Sign with the published demo key: the receipt then shows a result is unaltered, not who + signed it + + -h, --help + Print help + + -V, --version + Print version +``` + +### `wai-quantum build` + +```text +A standard algorithm's program (qpe, amplitude_estimation, adder, qsvt) on standard output, checked +by the equivalence ladder against a reference built from its definition + +Usage: wai-quantum build [OPTIONS] + +Arguments: + + qpe, amplitude_estimation, adder or qsvt + +Options: + --counting + qpe, amplitude_estimation: counting qubits (default 4) + + --input + A value for a generator's integer `input`, as n=5 (repeat for each input): the program is + read as its family's circuit at those values + + --lang + The language of the words the command line writes itself, en or zh-CN (by default the one + LANG names); results, codes and the engine's own messages stay in English + + --phase + qpe: the phase φ of p(2πφ), in turns + + --amplitude + amplitude_estimation: the good state's probability a + + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + + --bits + adder: the integers' width + + --a
+ adder: the first addend, prepared + + --b + adder: the second, which the sum replaces + + --carry-in + adder: a carry in + + --phases + qsvt: the phases φ0 … φd, in radians, as 0.1,-0.2,0.3 + + --x + qsvt: the signal, within [-1, 1] + + --matrix + qsvt: a real symmetric matrix [[a, b], [b, c]], as a,b,c + + --json + Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) + + --key + Sign with the key in this file (64 hex digits) + + --demo-key + Sign with the published demo key: the receipt then shows a result is unaltered, not who + signed it + + -h, --help + Print help + + -V, --version + Print version +``` + ### `wai-quantum repair` ```text @@ -2157,6 +2892,10 @@ Options: Round each angle the bit-exact method refuses (Q500) to the nearest multiple of 2π/2^K, its rounding stated on its line + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --size A register's size, for one used before it is declared (Q102), as q=3 (repeatable) @@ -2204,6 +2943,10 @@ Options: --seed The seed shots are sampled with (1 if not given) + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --method A method by name, or auto (the default) for the strongest the program admits; `wai-quantum methods` lists them @@ -2270,6 +3013,14 @@ Options: pea, pec, cdr, vd or readout, or its options as JSON ({"method": "pea", "factors": [1, 1.5, 2]}) + --pulse + A pulse run's options (with --method pulse), as JSON or a file of it: dt_ns, levels, + tolerance, substeps, qubits, couplings and ports (`wai-quantum pulse --help`) + + --param + A parameter's value, as theta=0.3 (repeatable): each `input float` and `input angle` of + the program, bound exactly (the job's "params"); in a sweep, the parameters it fixes + --fabric Where the state vector runs (the statevector method): auto (the default: the CPU, until a member is measured faster), cpu, accelerator (the first certified accelerator member that @@ -2345,6 +3096,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --service The service's address @@ -2385,6 +3140,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --service The service's address @@ -2425,6 +3184,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --service The service's address @@ -2469,6 +3232,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --service The service's address @@ -2514,6 +3281,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --service The service's address @@ -2558,6 +3329,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --service The service's address @@ -2603,6 +3378,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --service The service's address @@ -2647,6 +3426,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --service The service's address @@ -2687,6 +3470,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --service The service's address @@ -2734,6 +3521,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -2764,6 +3555,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -2791,6 +3586,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -2822,6 +3621,10 @@ Options: [default: 16] + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -2855,6 +3658,10 @@ Options: [default: 16] + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -2882,6 +3689,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -2914,6 +3725,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --memory-gb The memory a job may take, GiB @@ -2961,6 +3776,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --memory-gb The memory a job may take, GiB, when not the server's default @@ -2996,6 +3815,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --name The name the entry goes under @@ -3048,6 +3871,10 @@ Options: --write Write each file back formatted + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -3085,6 +3912,10 @@ Options: Sign with the published demo key: the receipt then shows a result is unaltered, not who signed it + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --stdio Accepted for the editors that pass it: standard input and output is the server's only transport @@ -3124,6 +3955,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -3161,6 +3996,10 @@ Options: Sign with the published demo key: the receipt then shows a result is unaltered, not who signed it + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -3196,6 +4035,10 @@ Options: [default: 1] + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --max-edits Edits made to a parent before it is evaluated, at most @@ -3254,6 +4097,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -3290,6 +4137,10 @@ Options: --parent The id of the archive entry it came from + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --proposer Who wrote it @@ -3341,6 +4192,10 @@ Options: --source Print one entry's generator, by id + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --json Print the summary as JSON @@ -3374,6 +4229,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -3411,6 +4270,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -3449,6 +4312,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -3487,6 +4354,10 @@ Options: [default: person] + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --name Which one: a model's or an agent's name, the rewrite, where the program came from @@ -3533,6 +4404,10 @@ Options: --locks The rules a proposal must keep (default: beside the program, as NAME.locks.json, if there) + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --parent The version it was changed from (default: the head) @@ -3590,6 +4465,10 @@ Options: --locks The rules a proposal must keep (default: beside the program, as NAME.locks.json, if there) + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --parent @@ -3635,6 +4514,10 @@ Options: --accept The changes accepted: their numbers from `changes` (as 0,2), all, or none + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --parent @@ -3700,6 +4583,10 @@ Options: [default: person] + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --name Which one: a model's or an agent's name, the rewrite, where the program came from @@ -3746,6 +4633,10 @@ Options: --locks The rules a proposal must keep (default: beside the program, as NAME.locks.json, if there) + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --json @@ -3785,6 +4676,10 @@ Options: --locks The rules a proposal must keep (default: beside the program, as NAME.locks.json, if there) + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --json @@ -3822,6 +4717,10 @@ Options: --locks The rules a proposal must keep (default: beside the program, as NAME.locks.json, if there) + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --job A job from `run --json --history` or the service @@ -3860,6 +4759,10 @@ Options: The program it is meant to improve on: the measures it beats it on that --weigh does not name + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --weigh The measures the cost weighs, comma-separated (as depth,two_qubit) @@ -3895,6 +4798,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -3931,6 +4838,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -3961,6 +4872,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -3994,6 +4909,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4028,6 +4947,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4065,6 +4988,10 @@ Options: Sign with the published demo key: the receipt then shows a result is unaltered, not who signed it + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4088,6 +5015,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4118,6 +5049,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4159,6 +5094,10 @@ Options: Sign with the published demo key: the receipt then shows a result is unaltered, not who signed it + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --json @@ -4193,6 +5132,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4227,6 +5170,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4263,6 +5210,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4295,6 +5246,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4325,6 +5280,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4358,6 +5317,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4388,6 +5351,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4421,6 +5388,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4454,6 +5425,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4492,6 +5467,10 @@ Options: [default: equivalent] + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --profile The profile's name: one person can keep several (for teaching, for one device) @@ -4531,6 +5510,10 @@ Options: --taste The file the profiles are kept in + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --json @@ -4567,6 +5550,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --novelty The novelty dial: −1 toward the typical, 1 toward the novel @@ -4617,6 +5604,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --task `prepares` or `equivalent` (a specification's own task by default) @@ -4662,6 +5653,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4698,6 +5693,10 @@ Options: --check Check this certificate (a sealed answer or the certificate alone) against the code + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --json Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) @@ -4740,6 +5739,10 @@ Options: --error The flipped qubits, as 3,12 (its syndrome is decoded and its residual judged) + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --memory The rotated surface-code memory experiment, as DISTANCE,ROUNDS,P @@ -4806,6 +5809,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --p Physical rates, as 0.002,0.004 @@ -4838,6 +5845,133 @@ Options: Print version ``` +### `wai-quantum pulse` + +```text +Pulse programs: a program's schedule on frames drawn as a timeline, and a pulse job checked by +running it again; a pulse program runs with `run --method pulse` (`wai-quantum pulse --help`) + +Usage: wai-quantum pulse [OPTIONS] + +Commands: + schedule A pulse program's schedule: each frame's timeline, every instruction at its sample, the + waveforms and the gate calls + check A pulse job (`run --method pulse --json`) checked: its receipt, its program's digest, + and the request run again here, its result held to the one given + help Print this message or the help of the given subcommand(s) + +Options: + --input + A value for a generator's integer `input`, as n=5 (repeat for each input): the program is + read as its family's circuit at those values + + --lang + The language of the words the command line writes itself, en or zh-CN (by default the one + LANG names); results, codes and the engine's own messages stay in English + + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + + -h, --help + Print help + + -V, --version + Print version +``` + +### `wai-quantum pulse schedule` + +```text +A pulse program's schedule: each frame's timeline, every instruction at its sample, the waveforms +and the gate calls + +Usage: wai-quantum pulse schedule [OPTIONS] [FILE] + +Arguments: + [FILE] + The program; `-` or nothing reads standard input + +Options: + --input + A value for a generator's integer `input`, as n=5 (repeat for each input): the program is + read as its family's circuit at those values + + --pulse + The pulse options, as JSON or a file of it (only dt_ns and ports matter here) + + --lang + The language of the words the command line writes itself, en or zh-CN (by default the one + LANG names); results, codes and the engine's own messages stay in English + + --width + The timeline's width, in columns + + [default: 60] + + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + + --json + Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) + + --key + Sign with the key in this file (64 hex digits) + + --demo-key + Sign with the published demo key: the receipt then shows a result is unaltered, not who + signed it + + -h, --help + Print help + + -V, --version + Print version +``` + +### `wai-quantum pulse check` + +```text +A pulse job (`run --method pulse --json`) checked: its receipt, its program's digest, and the +request run again here, its result held to the one given + +Usage: wai-quantum pulse check [OPTIONS] [FILE] + +Arguments: + [FILE] + The job, as `run --json` or the service returns it; `-` reads standard input + +Options: + --input + A value for a generator's integer `input`, as n=5 (repeat for each input): the program is + read as its family's circuit at those values + + --json + Print the answer sealed with this user's key, as JSON (`wai-quantum verify` checks it) + + --key + Sign with the key in this file (64 hex digits) + + --lang + The language of the words the command line writes itself, en or zh-CN (by default the one + LANG names); results, codes and the engine's own messages stay in English + + --demo-key + Sign with the published demo key: the receipt then shows a result is unaltered, not who + signed it + + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + + -h, --help + Print help + + -V, --version + Print version +``` + ### `wai-quantum eval` ```text @@ -4864,6 +5998,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4896,6 +6034,10 @@ Options: The model server: a chat-completions endpoint on this machine or a private network, as http://127.0.0.1:8080/v1 + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --name The model's name as its server knows it (default: the server's own) @@ -4967,6 +6109,10 @@ Options: -o, --out Write the corpus here (default: standard output) + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -4995,6 +6141,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5031,6 +6181,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5067,6 +6221,10 @@ Options: [default: 16] + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --junit Also write the verdict as a JUnit report to this file, one test case for each intent @@ -5111,6 +6269,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5157,6 +6319,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help (see a summary with '-h') @@ -5194,6 +6360,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --json Print the course and your progress as JSON @@ -5227,6 +6397,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5260,6 +6434,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5294,6 +6472,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5330,6 +6512,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5364,6 +6550,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5393,6 +6583,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5427,6 +6621,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5464,6 +6662,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --provider Read one of your providers' describe answers instead of a file (`wai-quantum providers list`) @@ -5500,6 +6702,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5533,6 +6739,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --view Print what the Studio draws: each qubit's place and errors, each pair's error @@ -5563,6 +6773,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5586,6 +6800,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5625,6 +6843,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5663,6 +6885,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + --set A setting that is not a secret, as backend=NAME (repeatable) @@ -5703,6 +6929,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5730,6 +6960,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5761,6 +6995,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5795,6 +7033,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5827,6 +7069,10 @@ Options: [default: 16] + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5855,6 +7101,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help @@ -5882,6 +7132,10 @@ Options: The language of the words the command line writes itself, en or zh-CN (by default the one LANG names); results, codes and the engine's own messages stay in English + --from + The format of every program the command reads: qasm, qir (LLVM text) or jeff; by default + the file's extension says (.ll or .qir is QIR, .jeff is jeff), and OpenQASM otherwise + -h, --help Print help diff --git a/wai/wai-quantum-cli/docs/local-mcp.json b/wai/wai-quantum-cli/docs/local-mcp.json index 88fc86a79..953f5a046 100644 --- a/wai/wai-quantum-cli/docs/local-mcp.json +++ b/wai/wai-quantum-cli/docs/local-mcp.json @@ -7,10 +7,45 @@ "description": "Run an OpenQASM program on this machine, planned as the quantum job service plans it: measurement counts, Pauli expectation values and/or amplitudes, the method chosen and why, its accuracy class, and a receipt signed with this user's key. Give `intent` (an exact distribution, or a reference program it must equal or whose state it must prepare) and the engine checks it with the run. Every answer carries `verdict`: the level the engine checked to (proof, evidence, executed, parsed, refused), whether the intent holds and a plain statement, sealed in the receipt. Quote the verdict and the numbers; do not estimate them or claim more.", "inputSchema": { "type": "object", - "required": [ - "qasm" + "anyOf": [ + { + "required": [ + "qasm" + ] + }, + { + "required": [ + "source" + ] + } ], "properties": { + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", + "properties": { + "format": { + "type": "string", + "enum": [ + "qasm", + "qir", + "jeff" + ], + "description": "Its format." + }, + "program": { + "type": "string", + "description": "The program's text: QIR (LLVM text) or OpenQASM." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64: jeff." + } + } + }, "qasm": { "type": "string", "description": "The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in \"inputs\"). while, inv and pow are refused with their line." @@ -34,7 +69,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or one of list_methods' names." + "description": "auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." }, "observables": { "type": "array", @@ -374,6 +409,128 @@ } } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050)." } } }, @@ -445,6 +602,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -452,6 +614,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -466,7 +652,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -1014,6 +1200,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -1038,6 +1231,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -1160,6 +1468,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -1170,11 +1497,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -1239,10 +1561,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -1280,6 +1598,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -3087,6 +3409,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -3340,6 +3893,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -3347,6 +3905,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -3361,7 +3943,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -3909,6 +4491,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -3933,6 +4522,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -4053,6 +4757,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -4063,11 +4786,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -4132,10 +4850,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -4173,6 +4887,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -5980,6 +6698,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -6836,10 +7785,45 @@ "description": "The method a program would run on and why, the memory and work it would take, without running it.", "inputSchema": { "type": "object", - "required": [ - "qasm" + "anyOf": [ + { + "required": [ + "qasm" + ] + }, + { + "required": [ + "source" + ] + } ], "properties": { + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", + "properties": { + "format": { + "type": "string", + "enum": [ + "qasm", + "qir", + "jeff" + ], + "description": "Its format." + }, + "program": { + "type": "string", + "description": "The program's text: QIR (LLVM text) or OpenQASM." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64: jeff." + } + } + }, "qasm": { "type": "string", "description": "The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in \"inputs\"). while, inv and pow are refused with their line." @@ -6863,7 +7847,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or one of list_methods' names." + "description": "auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." }, "observables": { "type": "array", @@ -7203,6 +8187,128 @@ } } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050)." } } }, @@ -12514,6 +13620,274 @@ ] } }, + { + "name": "convert_program", + "title": "Convert a program between formats", + "description": "Carry a program between OpenQASM 3, QIR (LLVM text, read under its base and adaptive profiles, written as QIR 2.0) and jeff (its Cap'n Proto message, as base64). The answer is the program written, the program as OpenQASM 3 (what every other tool takes), each note with its code (a rotation at an arbitrary angle, a custom gate read by its name, what a format leaves out), what was read and written, and the check: the output read back and held to the program by the equivalence ladder. A construct a reader cannot hold exactly is refused with its code (Q700 to Q721) and its place: quote the code, and never guess around it.", + "inputSchema": { + "type": "object", + "required": [ + "to" + ], + "properties": { + "program": { + "type": "string", + "description": "The program's text: OpenQASM or QIR." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64: jeff." + }, + "from": { + "type": "string", + "enum": [ + "qasm", + "qir", + "jeff" + ], + "description": "Its format; found from its bytes when not given." + }, + "to": { + "type": "string", + "enum": [ + "qasm", + "qir", + "jeff" + ], + "description": "The format to write." + }, + "profile": { + "type": "string", + "enum": [ + "base", + "adaptive" + ], + "description": "QIR's profile to write: by default base when the program's measurements all come at the end, else adaptive." + }, + "check": { + "type": "boolean", + "description": "false: write it without the check." + } + } + }, + "outputSchema": { + "$id": "wai-quantum://schemas/convert_program/1", + "type": "object", + "description": "A program carried from one format to another (OpenQASM 3, QIR as LLVM text, jeff as its Cap'n Proto message) and checked (engine::formats::convert_json): the program written, the program as read in OpenQASM 3, the readers' and writer's notes with their codes, what was read and written, and the check that holds the output to the input.", + "anyOf": [ + { + "type": "object", + "description": "A program carried from one format to another (OpenQASM 3, QIR as LLVM text, jeff as its Cap'n Proto message) and checked (engine::formats::convert_json): the program written, the program as read in OpenQASM 3, the readers' and writer's notes with their codes, what was read and written, and the check that holds the output to the input.", + "required": [ + "ok", + "format", + "from", + "to", + "qasm", + "notes", + "read", + "written", + "check" + ], + "properties": { + "ok": { + "const": true + }, + "format": { + "const": "wai.quantum.convert/1" + }, + "from": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "to": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program written, for a text format (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program written, for a binary format (jeff), as standard base64." + }, + "qasm": { + "type": "string", + "description": "The program as read, as OpenQASM 3: what every other tool takes." + }, + "notes": { + "type": "array", + "items": { + "type": "object", + "description": "One of the reader's diagnostics: its code, what happens to the construct it is about, its message (without the line or the code), and where it stands.", + "required": [ + "code", + "outcome", + "message" + ], + "properties": { + "code": { + "type": "string" + }, + "outcome": { + "enum": [ + "refused", + "lowered", + "carried", + "preserved", + "warned" + ] + }, + "message": { + "type": "string" + }, + "line": { + "type": "integer", + "minimum": 1 + }, + "column": { + "type": "integer", + "minimum": 1 + }, + "length": { + "type": "integer", + "minimum": 0 + } + } + }, + "description": "Each warning and note, with its code (Q7xx for the formats) and, for QIR, its line." + }, + "read": { + "type": "object", + "required": [ + "format" + ], + "description": "What was read: the format, its version, a QIR module's profile, entry point, qubits, results and declared capabilities, a jeff module's tool, entry point, qubits and bits." + }, + "written": { + "type": "object", + "required": [ + "format" + ], + "description": "What was written: the format, its version, and QIR's profile." + }, + "check": { + "anyOf": [ + { + "type": "null" + }, + { + "type": "object", + "required": [ + "what", + "verdict" + ], + "properties": { + "what": { + "type": "string", + "description": "What was held to what." + }, + "verdict": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "tableau", + "exact", + "rewrites", + "random", + "state", + "shape", + "steps", + "distribution", + "identity", + "none" + ], + "description": "The equivalence ladder's check (tableau, exact and rewrites are proofs; random is evidence); steps: the same steps one for one; distribution: every outcome's probability the same (evidence); identity: OpenQASM passed through; none: unchecked." + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": [ + "number", + "null" + ] + } + } + } + } + } + ], + "description": "The output read back and held to the program read (or, for a program read into OpenQASM, written back to its format and read again), or null when no check was asked." + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, { "name": "improve_qasm", "title": "Improve an OpenQASM program", @@ -18910,10 +20284,10 @@ "outputSchema": { "$id": "wai-quantum://schemas/verify_quantum_result/1", "type": "object", - "description": "Whether a job's receipt seals its request and its result, and the key that signed it; for an estimate, also every estimate's receipt and the request re-run here.", + "description": "Whether a job's receipt seals its request and its result, and the key that signed it; for an estimate, also every estimate's receipt and the request re-run here; for an answer of the variational and algorithm library, also its digest chain and the answer re-run here.", "anyOf": [ { - "description": "Whether a job's receipt seals its request and its result, and the key that signed it; for an estimate, also every estimate's receipt and the request re-run here.", + "description": "Whether a job's receipt seals its request and its result, and the key that signed it; for an estimate, also every estimate's receipt and the request re-run here; for an answer of the variational and algorithm library, also its digest chain and the answer re-run here.", "anyOf": [ { "type": "object", @@ -18973,6 +20347,48 @@ "type": "integer" } } + }, + { + "type": "object", + "description": "Whether a sealed answer of the library holds: its receipt over the request and the result, an optimisation's digest chain, and the answer run again to the same bytes (every call is deterministic and carries no clock).", + "required": [ + "valid", + "signed", + "chain", + "rerun", + "key" + ], + "properties": { + "valid": { + "type": "boolean" + }, + "signed": { + "type": "boolean" + }, + "chain": { + "type": [ + "boolean", + "null" + ], + "description": "An optimisation's chain: every step's digest the link over that step, from the request; null for an answer with no steps." + }, + "rerun": { + "type": "boolean" + }, + "rerun_error": { + "type": [ + "string", + "null" + ] + }, + "key": { + "type": [ + "string", + "null" + ], + "description": "The signing key, 32 bytes in hex." + } + } } ] }, @@ -26906,11 +28322,45 @@ "description": "Run an OpenQASM program here as it would run on a device target: compiled exactly to the target's native gates, placed on the qubits and routes most likely to succeed (the expected success given beside the fewest-swaps layout's), checked against the circuit, and simulated under the noise its calibration gives (each gate's error, T1, T2 and durations, idling, and each qubit's readout), on the density matrix or by trajectories. Counts and expectation values, their distance from the ideal distribution, the noise derived, and a receipt signed with this user's key that binds the target's hash. A model of the device, not a run on it: quote it as such. Every angle must be a dyadic multiple of 2π.", "inputSchema": { "type": "object", - "required": [ - "qasm", - "target" + "anyOf": [ + { + "required": [ + "qasm" + ] + }, + { + "required": [ + "source" + ] + } ], "properties": { + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", + "properties": { + "format": { + "type": "string", + "enum": [ + "qasm", + "qir", + "jeff" + ], + "description": "Its format." + }, + "program": { + "type": "string", + "description": "The program's text: QIR (LLVM text) or OpenQASM." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64: jeff." + } + } + }, "qasm": { "type": "string", "description": "The program, OpenQASM 3 or 2: registers and broadcast over them, the standard gates, ctrl/negctrl modifiers, gate definitions, measurement and reset anywhere, if on measured bits, and generators (integer input, const and for loops, one program for a family of circuits; give the inputs' values in \"inputs\"). while, inv and pow are refused with their line." @@ -26934,7 +28384,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or one of list_methods' names." + "description": "auto (the default: the strongest method the program admits), or one of list_methods' names; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." }, "observables": { "type": "array", @@ -27274,8 +28724,133 @@ } } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read. A parameter left without one is refused (J050)." } - } + }, + "required": [ + "target" + ] }, "outputSchema": { "$id": "wai-quantum://schemas/run_on_target/1", @@ -27345,6 +28920,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -27352,6 +28932,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -27366,7 +28970,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -27914,6 +29518,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -27938,6 +29549,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -28060,6 +29786,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -28070,11 +29815,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -28139,10 +29879,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -28180,6 +29916,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -29987,6 +31727,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -30240,6 +32211,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -30247,6 +32223,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -30261,7 +32261,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -30809,6 +32809,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -30833,6 +32840,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -30953,6 +33075,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -30963,11 +33104,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -31032,10 +33168,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -31073,6 +33205,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -32880,6 +35016,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -35135,6 +37502,9912 @@ ] } }, + { + "name": "pulse_schedule", + "title": "Read a pulse program into its schedule", + "description": "Read a pulse program (OpenPulse calibrations: ports, frames, waveforms, play, delay, shift_phase, set_phase, shift_frequency, set_frequency, captures and barriers) into its schedule on frames: every instruction at its sample, each waveform's samples (gaussian, drag, gaussian_square, constant, sech, sine, or explicit), each gate call with the samples its calibration spans, and the digests a pulse run's receipt binds (the program, its calibrations, the schedule). Durations are whole samples of dt (pulse.dt_ns, default 0.5 ns) or refused. A construct the reader does not take is refused with a Q code and its line. Sealed with this user's key. To run it, give the program to run_quantum_circuit with method \"pulse\".", + "inputSchema": { + "type": "object", + "required": [ + "qasm" + ], + "properties": { + "qasm": { + "type": "string", + "description": "A pulse program: OpenQASM 3 with `defcalgrammar \"openpulse\";`, `cal` blocks declaring ports (d0 drives qubit 0, m0 is its measurement port, a0 its acquisition port), frames (newframe(port, frequency Hz, phase)) and waveforms, a `defcal` for every gate it calls on physical qubits ($0), and the calls." + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/pulse_schedule/1", + "type": "object", + "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.pulse/1", + "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A schedule or a check, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A pulse program's schedule (pulse_schedule, wai-quantum pulse schedule, POST /v1/pulse/schedule): its frames and ports, every instruction at its sample, each waveform's samples, the gate calls, the reader's notes, and the digests a run binds.", + "required": [ + "answer", + "dt_ns", + "duration", + "frames", + "waveforms", + "instructions", + "calls", + "calibration" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.pulse/1" + }, + "answer": { + "const": "schedule" + }, + "dt_ns": { + "type": "number", + "description": "The sample period, ns." + }, + "duration": { + "type": "integer", + "description": "The latest time of any frame, samples." + }, + "duration_ns": { + "type": "number" + }, + "grammar": { + "type": [ + "string", + "null" + ] + }, + "ports": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer" + } + } + } + }, + "frames": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "frequency_hz": { + "type": "number" + }, + "phase": { + "type": "number" + } + } + } + }, + "waveforms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "length": { + "type": "integer" + }, + "samples": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + } + }, + "samples_every": { + "type": "integer", + "description": "Each k-th sample is drawn, when the schedule holds more than the view writes out." + } + } + } + }, + "instructions": { + "type": "array", + "items": { + "type": "object", + "required": [ + "frame", + "op", + "start", + "length" + ], + "properties": { + "frame": { + "type": "integer" + }, + "op": { + "enum": [ + "play", + "delay", + "shift_phase", + "set_phase", + "shift_frequency", + "set_frequency", + "capture", + "barrier" + ] + }, + "start": { + "type": "integer" + }, + "length": { + "type": "integer" + }, + "line": { + "type": "integer" + }, + "waveform": { + "type": "integer" + }, + "phase": { + "type": "number" + }, + "frequency_hz": { + "type": "number" + }, + "carrier": { + "type": "number", + "description": "The carrier's phase at the play's first sample, cycles in [0, 1)." + }, + "value": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "calls": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "params": { + "type": "array", + "items": { + "type": "number" + } + }, + "start": { + "type": "integer" + }, + "end": { + "type": "integer" + }, + "line": { + "type": "integer" + } + } + } + }, + "bits": { + "type": "array", + "items": { + "type": "string" + } + }, + "qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "decimated": { + "type": "string" + }, + "diagnostics": { + "type": "array", + "items": { + "type": "object", + "description": "A reader's note or warning (qasm::diag).", + "properties": { + "code": { + "type": "string" + }, + "outcome": { + "type": "string" + }, + "message": { + "type": "string" + }, + "line": { + "type": "integer" + }, + "column": { + "type": "integer" + }, + "length": { + "type": "integer" + } + } + } + }, + "calibration": { + "type": "object", + "description": "What a pulse run's receipt binds of the program: the BLAKE3 of the control program's text, of its calibrations as written (every cal, defcal and defcalgrammar, joined by newlines), and of the schedule's JSON; a run adds the device's and the target snapshot's.", + "required": [ + "program", + "calibrations", + "schedule" + ], + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + } + } + }, + { + "type": "object", + "description": "A pulse job checked (pulse_check, wai-quantum pulse check, POST /v1/pulse/check): its receipt's signature, its program's digest, and the request run again with the result held to the one given.", + "required": [ + "answer", + "verified", + "signature", + "program", + "reproduced", + "differences", + "statement" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.pulse/1" + }, + "answer": { + "const": "check" + }, + "verified": { + "type": "boolean" + }, + "signature": { + "type": "boolean" + }, + "key": {}, + "program": { + "type": "boolean" + }, + "reproduced": { + "type": "boolean" + }, + "differences": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Each field (or field.member) whose value differs from the run here." + }, + "density_hash": { + "type": "object", + "properties": { + "given": {}, + "recomputed": {} + } + }, + "calibration": {}, + "statement": { + "type": "string" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "pulse_check", + "title": "Check a pulse run by running it again", + "description": "Check a pulse job as a host returned it ({\"request\", \"result\"}, the result with its receipt): the receipt's signature, the program's digest against the request's text, and the request run again here with the result held to the one given field by field (the density matrix's digest among them), each difference named. A pulse run is the same bits on every platform, so a result that does not reproduce was not made from that request by this engine. Sealed with this user's key. Quote `verified` and the statement.", + "inputSchema": { + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The pulse job's request." + }, + "result": { + "type": "object", + "description": "Its result, with its receipt." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/pulse_check/1", + "type": "object", + "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.pulse/1", + "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A schedule or a check, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A pulse program's schedule (pulse_schedule, wai-quantum pulse schedule, POST /v1/pulse/schedule): its frames and ports, every instruction at its sample, each waveform's samples, the gate calls, the reader's notes, and the digests a run binds.", + "required": [ + "answer", + "dt_ns", + "duration", + "frames", + "waveforms", + "instructions", + "calls", + "calibration" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.pulse/1" + }, + "answer": { + "const": "schedule" + }, + "dt_ns": { + "type": "number", + "description": "The sample period, ns." + }, + "duration": { + "type": "integer", + "description": "The latest time of any frame, samples." + }, + "duration_ns": { + "type": "number" + }, + "grammar": { + "type": [ + "string", + "null" + ] + }, + "ports": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer" + } + } + } + }, + "frames": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "frequency_hz": { + "type": "number" + }, + "phase": { + "type": "number" + } + } + } + }, + "waveforms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "length": { + "type": "integer" + }, + "samples": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + } + }, + "samples_every": { + "type": "integer", + "description": "Each k-th sample is drawn, when the schedule holds more than the view writes out." + } + } + } + }, + "instructions": { + "type": "array", + "items": { + "type": "object", + "required": [ + "frame", + "op", + "start", + "length" + ], + "properties": { + "frame": { + "type": "integer" + }, + "op": { + "enum": [ + "play", + "delay", + "shift_phase", + "set_phase", + "shift_frequency", + "set_frequency", + "capture", + "barrier" + ] + }, + "start": { + "type": "integer" + }, + "length": { + "type": "integer" + }, + "line": { + "type": "integer" + }, + "waveform": { + "type": "integer" + }, + "phase": { + "type": "number" + }, + "frequency_hz": { + "type": "number" + }, + "carrier": { + "type": "number", + "description": "The carrier's phase at the play's first sample, cycles in [0, 1)." + }, + "value": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "calls": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "params": { + "type": "array", + "items": { + "type": "number" + } + }, + "start": { + "type": "integer" + }, + "end": { + "type": "integer" + }, + "line": { + "type": "integer" + } + } + } + }, + "bits": { + "type": "array", + "items": { + "type": "string" + } + }, + "qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "decimated": { + "type": "string" + }, + "diagnostics": { + "type": "array", + "items": { + "type": "object", + "description": "A reader's note or warning (qasm::diag).", + "properties": { + "code": { + "type": "string" + }, + "outcome": { + "type": "string" + }, + "message": { + "type": "string" + }, + "line": { + "type": "integer" + }, + "column": { + "type": "integer" + }, + "length": { + "type": "integer" + } + } + } + }, + "calibration": { + "type": "object", + "description": "What a pulse run's receipt binds of the program: the BLAKE3 of the control program's text, of its calibrations as written (every cal, defcal and defcalgrammar, joined by newlines), and of the schedule's JSON; a run adds the device's and the target snapshot's.", + "required": [ + "program", + "calibrations", + "schedule" + ], + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + } + } + }, + { + "type": "object", + "description": "A pulse job checked (pulse_check, wai-quantum pulse check, POST /v1/pulse/check): its receipt's signature, its program's digest, and the request run again with the result held to the one given.", + "required": [ + "answer", + "verified", + "signature", + "program", + "reproduced", + "differences", + "statement" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.pulse/1" + }, + "answer": { + "const": "check" + }, + "verified": { + "type": "boolean" + }, + "signature": { + "type": "boolean" + }, + "key": {}, + "program": { + "type": "boolean" + }, + "reproduced": { + "type": "boolean" + }, + "differences": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Each field (or field.member) whose value differs from the run here." + }, + "density_hash": { + "type": "object", + "properties": { + "given": {}, + "recomputed": {} + } + }, + "calibration": {}, + "statement": { + "type": "string" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "gradient_qasm", + "title": "The exact gradient of a Hamiltonian's expectation by a program's parameters", + "description": "The expectation E = ⟨ψ|H|ψ⟩ of a Hamiltonian at a program's parameters, and its gradient by each parameter, exactly: by adjoint differentiation or the parameter-shift rule on the double-precision state vector (at most 20 qubits, no noise, measurements only at the end). The reader follows each parameter into the gates, so an argument may be any expression of the built-in functions. The answer states its method, that it is f64 and approximate, and a bound on the rounding of the value and of each component (precision.rounding_bound). Sealed with this user's key. Quote the gradient with its bound.", + "inputSchema": { + "type": "object", + "required": [ + "qasm", + "params", + "hamiltonian" + ], + "properties": { + "qasm": { + "type": "string", + "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." + }, + "hamiltonian": { + "type": "array", + "minItems": 1, + "maxItems": 4096, + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "pauli" + ], + "properties": { + "pauli": { + "type": "string" + }, + "coeff": { + "type": "number" + } + } + } + ] + }, + "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ], + "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/gradient_qasm/1", + "type": "object", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.algorithms/1", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", + "required": [ + "call", + "value", + "gradient", + "params", + "method", + "how", + "evaluations", + "qubits", + "gates", + "moved_gates", + "parameters", + "terms", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "gradient" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "value": { + "type": "number", + "description": "⟨ψ|H|ψ⟩ at the params." + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "∂E/∂p for each parameter p, by name." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The point, by name." + }, + "method": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "how": { + "type": "string" + }, + "evaluations": { + "type": "integer", + "minimum": 0, + "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "moved_gates": { + "type": "integer", + "minimum": 0, + "description": "Gates a parameter moves." + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0, + "description": "The Hamiltonian's Pauli terms." + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "optimize" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + } + } + }, + { + "type": "object", + "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "reference" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "vqe" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "reference": { + "anyOf": [ + { + "type": "object", + "required": [ + "ground_energy", + "how", + "gap" + ], + "properties": { + "ground_energy": { + "type": "number" + }, + "first_excited": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "how": { + "type": "string" + }, + "gap": { + "type": "number", + "description": "The best energy found above the ground energy." + } + } + }, + { + "type": "object", + "required": [ + "unchecked" + ], + "properties": { + "unchecked": { + "type": "string" + } + } + } + ] + }, + "ansatz": { + "type": "object", + "required": [ + "qasm", + "params", + "kind" + ], + "properties": { + "qasm": { + "type": "string" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "kind": { + "const": "hardware_efficient" + } + } + } + } + }, + { + "type": "object", + "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "graph", + "layers", + "program", + "hamiltonian", + "maxcut" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "qaoa" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 0 + }, + "edges": { + "type": "array", + "items": { + "type": "array", + "minItems": 3, + "maxItems": 3 + } + } + } + }, + "layers": { + "type": "integer", + "minimum": 0 + }, + "program": { + "type": "string" + }, + "hamiltonian": { + "type": "array" + }, + "maxcut": { + "type": "object", + "required": [ + "max_cut", + "optimal", + "optimal_count", + "how", + "expected_cut", + "ratio", + "most_likely", + "p_optimal", + "bits" + ], + "properties": { + "max_cut": { + "type": "number" + }, + "optimal": { + "type": "array", + "items": { + "type": "string" + } + }, + "optimal_count": { + "type": "integer", + "minimum": 0 + }, + "how": { + "type": "string" + }, + "expected_cut": { + "type": "number" + }, + "ratio": { + "type": "number" + }, + "most_likely": { + "type": "object", + "required": [ + "bits", + "probability", + "cut", + "optimal" + ], + "properties": { + "bits": { + "type": "string" + }, + "probability": { + "type": "number" + }, + "cut": { + "type": "number" + }, + "optimal": { + "type": "boolean" + } + } + }, + "p_optimal": { + "type": "number" + }, + "bits": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", + "required": [ + "call", + "algorithm", + "qasm", + "qubits", + "gates", + "reads", + "expected", + "check" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "build" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "qasm": { + "type": "string" + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "reads": { + "type": "object", + "description": "How to read the program's result." + }, + "expected": { + "type": "object", + "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." + }, + "check": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "exact", + "random", + "none" + ] + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": "number" + }, + "reference": { + "type": "string" + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "optimize_qasm", + "title": "Minimise a Hamiltonian's expectation over a program's parameters", + "description": "Minimise E = ⟨ψ|H|ψ⟩ over a program's parameters from the given params, deterministically: gradient descent with a fixed step, Adam, or SPSA from a seeded stream (at most 2000 steps). Every step's parameters and value (and gradient, or SPSA's perturbation and estimate) are listed, each step a link of a digest chain from the request, best and final given; the same request gives the same bytes on every platform. Sealed with this user's key: the receipt binds the program, every step, the method and the seed, and verify_quantum_result (or wai-quantum verify) re-runs it. A minimum found is a minimum along this path, not a proof of the global one.", + "inputSchema": { + "type": "object", + "required": [ + "qasm", + "params", + "hamiltonian" + ], + "properties": { + "qasm": { + "type": "string", + "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." + }, + "hamiltonian": { + "type": "array", + "minItems": 1, + "maxItems": 4096, + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "pauli" + ], + "properties": { + "pauli": { + "type": "string" + }, + "coeff": { + "type": "number" + } + } + } + ] + }, + "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." + }, + "optimizer": { + "anyOf": [ + { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + } + } + } + ], + "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." + }, + "steps": { + "type": "integer", + "minimum": 1, + "maximum": 2000, + "description": "Steps to take (default 100)." + }, + "step_size": { + "type": "number", + "exclusiveMinimum": 0, + "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ], + "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." + }, + "seed": { + "type": "integer", + "minimum": 0, + "description": "SPSA's seed (default 1)." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/optimize_qasm/1", + "type": "object", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.algorithms/1", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", + "required": [ + "call", + "value", + "gradient", + "params", + "method", + "how", + "evaluations", + "qubits", + "gates", + "moved_gates", + "parameters", + "terms", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "gradient" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "value": { + "type": "number", + "description": "⟨ψ|H|ψ⟩ at the params." + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "∂E/∂p for each parameter p, by name." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The point, by name." + }, + "method": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "how": { + "type": "string" + }, + "evaluations": { + "type": "integer", + "minimum": 0, + "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "moved_gates": { + "type": "integer", + "minimum": 0, + "description": "Gates a parameter moves." + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0, + "description": "The Hamiltonian's Pauli terms." + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "optimize" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + } + } + }, + { + "type": "object", + "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "reference" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "vqe" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "reference": { + "anyOf": [ + { + "type": "object", + "required": [ + "ground_energy", + "how", + "gap" + ], + "properties": { + "ground_energy": { + "type": "number" + }, + "first_excited": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "how": { + "type": "string" + }, + "gap": { + "type": "number", + "description": "The best energy found above the ground energy." + } + } + }, + { + "type": "object", + "required": [ + "unchecked" + ], + "properties": { + "unchecked": { + "type": "string" + } + } + } + ] + }, + "ansatz": { + "type": "object", + "required": [ + "qasm", + "params", + "kind" + ], + "properties": { + "qasm": { + "type": "string" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "kind": { + "const": "hardware_efficient" + } + } + } + } + }, + { + "type": "object", + "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "graph", + "layers", + "program", + "hamiltonian", + "maxcut" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "qaoa" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 0 + }, + "edges": { + "type": "array", + "items": { + "type": "array", + "minItems": 3, + "maxItems": 3 + } + } + } + }, + "layers": { + "type": "integer", + "minimum": 0 + }, + "program": { + "type": "string" + }, + "hamiltonian": { + "type": "array" + }, + "maxcut": { + "type": "object", + "required": [ + "max_cut", + "optimal", + "optimal_count", + "how", + "expected_cut", + "ratio", + "most_likely", + "p_optimal", + "bits" + ], + "properties": { + "max_cut": { + "type": "number" + }, + "optimal": { + "type": "array", + "items": { + "type": "string" + } + }, + "optimal_count": { + "type": "integer", + "minimum": 0 + }, + "how": { + "type": "string" + }, + "expected_cut": { + "type": "number" + }, + "ratio": { + "type": "number" + }, + "most_likely": { + "type": "object", + "required": [ + "bits", + "probability", + "cut", + "optimal" + ], + "properties": { + "bits": { + "type": "string" + }, + "probability": { + "type": "number" + }, + "cut": { + "type": "number" + }, + "optimal": { + "type": "boolean" + } + } + }, + "p_optimal": { + "type": "number" + }, + "bits": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", + "required": [ + "call", + "algorithm", + "qasm", + "qubits", + "gates", + "reads", + "expected", + "check" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "build" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "qasm": { + "type": "string" + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "reads": { + "type": "object", + "description": "How to read the program's result." + }, + "expected": { + "type": "object", + "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." + }, + "check": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "exact", + "random", + "none" + ] + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": "number" + }, + "reference": { + "type": "string" + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "vqe_ground_state", + "title": "Find a Hamiltonian's ground energy by the variational eigensolver", + "description": "The variational eigensolver: an ansatz (the program given as qasm with params, or ansatz {\"layers\": L}: layers of ry and rz on every qubit and a ring of cx, its parameters t0, t1, … from 0.1) optimised on the Hamiltonian as optimize_qasm does. At most 8 qubits the answer sets the energy found beside the exact ground energy by diagonalisation (reference.ground_energy and gap); the energy found is never below it. Sealed with this user's key. Report the gap: an ansatz that cannot reach the ground state stops above it.", + "inputSchema": { + "type": "object", + "required": [ + "hamiltonian" + ], + "properties": { + "hamiltonian": { + "type": "array", + "minItems": 1, + "maxItems": 4096, + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "pauli" + ], + "properties": { + "pauli": { + "type": "string" + }, + "coeff": { + "type": "number" + } + } + } + ] + }, + "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." + }, + "qasm": { + "type": "string", + "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." + }, + "ansatz": { + "type": "object", + "properties": { + "layers": { + "type": "integer", + "minimum": 1, + "maximum": 16 + }, + "qubits": { + "type": "integer", + "minimum": 1, + "maximum": 20 + } + }, + "description": "The built-in ansatz in place of qasm (layers default 2, qubits the Hamiltonian's)." + }, + "optimizer": { + "anyOf": [ + { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + } + } + } + ], + "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." + }, + "steps": { + "type": "integer", + "minimum": 1, + "maximum": 2000, + "description": "Steps to take (default 100)." + }, + "step_size": { + "type": "number", + "exclusiveMinimum": 0, + "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ], + "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." + }, + "seed": { + "type": "integer", + "minimum": 0, + "description": "SPSA's seed (default 1)." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/vqe_ground_state/1", + "type": "object", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.algorithms/1", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", + "required": [ + "call", + "value", + "gradient", + "params", + "method", + "how", + "evaluations", + "qubits", + "gates", + "moved_gates", + "parameters", + "terms", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "gradient" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "value": { + "type": "number", + "description": "⟨ψ|H|ψ⟩ at the params." + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "∂E/∂p for each parameter p, by name." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The point, by name." + }, + "method": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "how": { + "type": "string" + }, + "evaluations": { + "type": "integer", + "minimum": 0, + "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "moved_gates": { + "type": "integer", + "minimum": 0, + "description": "Gates a parameter moves." + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0, + "description": "The Hamiltonian's Pauli terms." + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "optimize" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + } + } + }, + { + "type": "object", + "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "reference" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "vqe" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "reference": { + "anyOf": [ + { + "type": "object", + "required": [ + "ground_energy", + "how", + "gap" + ], + "properties": { + "ground_energy": { + "type": "number" + }, + "first_excited": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "how": { + "type": "string" + }, + "gap": { + "type": "number", + "description": "The best energy found above the ground energy." + } + } + }, + { + "type": "object", + "required": [ + "unchecked" + ], + "properties": { + "unchecked": { + "type": "string" + } + } + } + ] + }, + "ansatz": { + "type": "object", + "required": [ + "qasm", + "params", + "kind" + ], + "properties": { + "qasm": { + "type": "string" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "kind": { + "const": "hardware_efficient" + } + } + } + } + }, + { + "type": "object", + "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "graph", + "layers", + "program", + "hamiltonian", + "maxcut" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "qaoa" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 0 + }, + "edges": { + "type": "array", + "items": { + "type": "array", + "minItems": 3, + "maxItems": 3 + } + } + } + }, + "layers": { + "type": "integer", + "minimum": 0 + }, + "program": { + "type": "string" + }, + "hamiltonian": { + "type": "array" + }, + "maxcut": { + "type": "object", + "required": [ + "max_cut", + "optimal", + "optimal_count", + "how", + "expected_cut", + "ratio", + "most_likely", + "p_optimal", + "bits" + ], + "properties": { + "max_cut": { + "type": "number" + }, + "optimal": { + "type": "array", + "items": { + "type": "string" + } + }, + "optimal_count": { + "type": "integer", + "minimum": 0 + }, + "how": { + "type": "string" + }, + "expected_cut": { + "type": "number" + }, + "ratio": { + "type": "number" + }, + "most_likely": { + "type": "object", + "required": [ + "bits", + "probability", + "cut", + "optimal" + ], + "properties": { + "bits": { + "type": "string" + }, + "probability": { + "type": "number" + }, + "cut": { + "type": "number" + }, + "optimal": { + "type": "boolean" + } + } + }, + "p_optimal": { + "type": "number" + }, + "bits": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", + "required": [ + "call", + "algorithm", + "qasm", + "qubits", + "gates", + "reads", + "expected", + "check" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "build" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "qasm": { + "type": "string" + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "reads": { + "type": "object", + "description": "How to read the program's result." + }, + "expected": { + "type": "object", + "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." + }, + "check": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "exact", + "random", + "none" + ] + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": "number" + }, + "reference": { + "type": "string" + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "qaoa_maxcut", + "title": "Solve Max-Cut on a graph by QAOA", + "description": "Max-Cut by the quantum approximate optimisation algorithm: the program (|+⟩ⁿ, then for each layer rzz(gamma·w) on every edge and rx(2·beta) on every qubit) and its cost Hamiltonian built from the graph (at most 20 vertices, 16 layers), optimised as optimize_qasm does from the params or a linear ramp, and read against the maximum cut found by brute force: the expected cut and its ratio to the maximum, the likeliest assignment and whether it is optimal, and the probability of an optimal one. Sealed with this user's key.", + "inputSchema": { + "type": "object", + "required": [ + "graph" + ], + "properties": { + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 2, + "maximum": 20 + }, + "edges": { + "type": "array", + "minItems": 1, + "maxItems": 400, + "items": { + "type": "array", + "minItems": 2, + "maxItems": 3, + "items": { + "type": "number" + } + }, + "description": "Each edge [i, j] or [i, j, weight]." + } + } + }, + "layers": { + "type": "integer", + "minimum": 1, + "maximum": 16, + "description": "QAOA's p (default 1)." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "gamma_0, beta_0, … to start from." + }, + "optimizer": { + "anyOf": [ + { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + } + } + } + ], + "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." + }, + "steps": { + "type": "integer", + "minimum": 1, + "maximum": 2000, + "description": "Steps to take (default 100)." + }, + "step_size": { + "type": "number", + "exclusiveMinimum": 0, + "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ], + "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." + }, + "seed": { + "type": "integer", + "minimum": 0, + "description": "SPSA's seed (default 1)." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/qaoa_maxcut/1", + "type": "object", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.algorithms/1", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", + "required": [ + "call", + "value", + "gradient", + "params", + "method", + "how", + "evaluations", + "qubits", + "gates", + "moved_gates", + "parameters", + "terms", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "gradient" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "value": { + "type": "number", + "description": "⟨ψ|H|ψ⟩ at the params." + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "∂E/∂p for each parameter p, by name." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The point, by name." + }, + "method": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "how": { + "type": "string" + }, + "evaluations": { + "type": "integer", + "minimum": 0, + "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "moved_gates": { + "type": "integer", + "minimum": 0, + "description": "Gates a parameter moves." + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0, + "description": "The Hamiltonian's Pauli terms." + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "optimize" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + } + } + }, + { + "type": "object", + "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "reference" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "vqe" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "reference": { + "anyOf": [ + { + "type": "object", + "required": [ + "ground_energy", + "how", + "gap" + ], + "properties": { + "ground_energy": { + "type": "number" + }, + "first_excited": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "how": { + "type": "string" + }, + "gap": { + "type": "number", + "description": "The best energy found above the ground energy." + } + } + }, + { + "type": "object", + "required": [ + "unchecked" + ], + "properties": { + "unchecked": { + "type": "string" + } + } + } + ] + }, + "ansatz": { + "type": "object", + "required": [ + "qasm", + "params", + "kind" + ], + "properties": { + "qasm": { + "type": "string" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "kind": { + "const": "hardware_efficient" + } + } + } + } + }, + { + "type": "object", + "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "graph", + "layers", + "program", + "hamiltonian", + "maxcut" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "qaoa" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 0 + }, + "edges": { + "type": "array", + "items": { + "type": "array", + "minItems": 3, + "maxItems": 3 + } + } + } + }, + "layers": { + "type": "integer", + "minimum": 0 + }, + "program": { + "type": "string" + }, + "hamiltonian": { + "type": "array" + }, + "maxcut": { + "type": "object", + "required": [ + "max_cut", + "optimal", + "optimal_count", + "how", + "expected_cut", + "ratio", + "most_likely", + "p_optimal", + "bits" + ], + "properties": { + "max_cut": { + "type": "number" + }, + "optimal": { + "type": "array", + "items": { + "type": "string" + } + }, + "optimal_count": { + "type": "integer", + "minimum": 0 + }, + "how": { + "type": "string" + }, + "expected_cut": { + "type": "number" + }, + "ratio": { + "type": "number" + }, + "most_likely": { + "type": "object", + "required": [ + "bits", + "probability", + "cut", + "optimal" + ], + "properties": { + "bits": { + "type": "string" + }, + "probability": { + "type": "number" + }, + "cut": { + "type": "number" + }, + "optimal": { + "type": "boolean" + } + } + }, + "p_optimal": { + "type": "number" + }, + "bits": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", + "required": [ + "call", + "algorithm", + "qasm", + "qubits", + "gates", + "reads", + "expected", + "check" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "build" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "qasm": { + "type": "string" + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "reads": { + "type": "object", + "description": "How to read the program's result." + }, + "expected": { + "type": "object", + "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." + }, + "check": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "exact", + "random", + "none" + ] + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": "number" + }, + "reference": { + "type": "string" + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "build_algorithm", + "title": "Write the program for a standard algorithm, checked against its reference", + "description": "An OpenQASM 3 program for a standard algorithm, with how to read its result, what it gives, and the equivalence ladder's verdict on it against a reference matrix or truth table built from the definitions (check: exact on every basis state up to 8 qubits, the adder's up to 16; past that unchecked). qpe: the phase φ of p(2πφ) on counting qubits; amplitude_estimation: the amplitude a that A = ry(2·arcsin √a) gives the good state, by phase estimation of the Grover operator; adder: the ripple-carry adder of bits-bit integers in place (with a and b, prepared and measured); qsvt: quantum signal processing from phases, of a signal x or of a real symmetric 2 × 2 matrix through its block encoding (all phases zero give the Chebyshev polynomial). Sealed with this user's key. Run the program with run_quantum_circuit.", + "inputSchema": { + "type": "object", + "required": [ + "algorithm" + ], + "properties": { + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "counting": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "qpe, amplitude_estimation: counting qubits (default 4)." + }, + "phase": { + "type": "number", + "description": "qpe: the phase φ, in turns." + }, + "amplitude": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "amplitude_estimation: the good state's probability a." + }, + "bits": { + "type": "integer", + "minimum": 1, + "maximum": 32, + "description": "adder: the integers' width." + }, + "a": { + "type": "integer", + "minimum": 0, + "description": "adder: the first addend, prepared." + }, + "b": { + "type": "integer", + "minimum": 0, + "description": "adder: the second, which the sum replaces." + }, + "carry_in": { + "type": "boolean", + "description": "adder: a carry in." + }, + "phases": { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "number" + }, + "description": "qsvt: φ₀ … φ_d, radians." + }, + "x": { + "type": "number", + "minimum": -1, + "maximum": 1, + "description": "qsvt: the signal." + }, + "matrix": { + "type": "array", + "description": "qsvt: [[a, b], [b, c]], real and symmetric, its eigenvalues within [-1, 1]." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/build_algorithm/1", + "type": "object", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.algorithms/1", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", + "required": [ + "call", + "value", + "gradient", + "params", + "method", + "how", + "evaluations", + "qubits", + "gates", + "moved_gates", + "parameters", + "terms", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "gradient" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "value": { + "type": "number", + "description": "⟨ψ|H|ψ⟩ at the params." + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "∂E/∂p for each parameter p, by name." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The point, by name." + }, + "method": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "how": { + "type": "string" + }, + "evaluations": { + "type": "integer", + "minimum": 0, + "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "moved_gates": { + "type": "integer", + "minimum": 0, + "description": "Gates a parameter moves." + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0, + "description": "The Hamiltonian's Pauli terms." + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "optimize" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + } + } + }, + { + "type": "object", + "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "reference" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "vqe" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "reference": { + "anyOf": [ + { + "type": "object", + "required": [ + "ground_energy", + "how", + "gap" + ], + "properties": { + "ground_energy": { + "type": "number" + }, + "first_excited": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "how": { + "type": "string" + }, + "gap": { + "type": "number", + "description": "The best energy found above the ground energy." + } + } + }, + { + "type": "object", + "required": [ + "unchecked" + ], + "properties": { + "unchecked": { + "type": "string" + } + } + } + ] + }, + "ansatz": { + "type": "object", + "required": [ + "qasm", + "params", + "kind" + ], + "properties": { + "qasm": { + "type": "string" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "kind": { + "const": "hardware_efficient" + } + } + } + } + }, + { + "type": "object", + "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "graph", + "layers", + "program", + "hamiltonian", + "maxcut" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "qaoa" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 0 + }, + "edges": { + "type": "array", + "items": { + "type": "array", + "minItems": 3, + "maxItems": 3 + } + } + } + }, + "layers": { + "type": "integer", + "minimum": 0 + }, + "program": { + "type": "string" + }, + "hamiltonian": { + "type": "array" + }, + "maxcut": { + "type": "object", + "required": [ + "max_cut", + "optimal", + "optimal_count", + "how", + "expected_cut", + "ratio", + "most_likely", + "p_optimal", + "bits" + ], + "properties": { + "max_cut": { + "type": "number" + }, + "optimal": { + "type": "array", + "items": { + "type": "string" + } + }, + "optimal_count": { + "type": "integer", + "minimum": 0 + }, + "how": { + "type": "string" + }, + "expected_cut": { + "type": "number" + }, + "ratio": { + "type": "number" + }, + "most_likely": { + "type": "object", + "required": [ + "bits", + "probability", + "cut", + "optimal" + ], + "properties": { + "bits": { + "type": "string" + }, + "probability": { + "type": "number" + }, + "cut": { + "type": "number" + }, + "optimal": { + "type": "boolean" + } + } + }, + "p_optimal": { + "type": "number" + }, + "bits": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", + "required": [ + "call", + "algorithm", + "qasm", + "qubits", + "gates", + "reads", + "expected", + "check" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "build" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "qasm": { + "type": "string" + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "reads": { + "type": "object", + "description": "How to read the program's result." + }, + "expected": { + "type": "object", + "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." + }, + "check": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "exact", + "random", + "none" + ] + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": "number" + }, + "reference": { + "type": "string" + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, { "name": "providers_list", "title": "List the person's quantum providers", @@ -35463,6 +47736,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -35470,6 +47748,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -35484,7 +47786,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -36032,6 +48334,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -36056,6 +48365,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -36178,6 +48602,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -36188,11 +48631,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -36257,10 +48695,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -36298,6 +48732,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -38105,6 +50543,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -38358,6 +51027,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -38365,6 +51039,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -38379,7 +51077,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -38927,6 +51625,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -38951,6 +51656,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -39071,6 +51891,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -39081,11 +51920,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -39150,10 +51984,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -39191,6 +52021,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -40998,6 +53832,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, diff --git a/wai/wai-quantum-cli/docs/service-mcp.json b/wai/wai-quantum-cli/docs/service-mcp.json index cb88e73fc..0af8ca9bd 100644 --- a/wai/wai-quantum-cli/docs/service-mcp.json +++ b/wai/wai-quantum-cli/docs/service-mcp.json @@ -7,8 +7,17 @@ "description": "Run an OpenQASM program and return measurement counts, Pauli expectation values and/or amplitudes. The service chooses the method (bit-exact or double-precision state vector up to 32 qubits, single precision on a GPU to 33, stabilizer tableau for Clifford circuits up to 32768 qubits, matrix product states up to 4096, sparse Pauli dynamics for expectation values up to 1024 with an error bound, an exact density matrix or trajectories for noise), reports why and how accurate, and signs the result. Give `intent` (an exact distribution, or a reference program it must equal or whose state it must prepare) and the engine checks it with the run. Every answer carries `verdict`: the level the engine checked to (proof, evidence, executed, parsed, refused), whether the intent holds and a plain statement, sealed in the receipt. Waits up to 50 s; a longer job answers with status running and an id for get_quantum_job.", "inputSchema": { "type": "object", - "required": [ - "qasm" + "anyOf": [ + { + "required": [ + "qasm" + ] + }, + { + "required": [ + "source" + ] + } ], "properties": { "qasm": { @@ -71,9 +80,10 @@ "cutrank_single", "stabilizer_rank", "density_matrix", - "trajectories" + "trajectories", + "pulse" ], - "description": "Leave as auto unless you need a particular method." + "description": "Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." }, "seed": { "type": "integer", @@ -371,6 +381,154 @@ } } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", + "properties": { + "format": { + "type": "string", + "enum": [ + "qasm", + "qir", + "jeff" + ], + "description": "Its format." + }, + "program": { + "type": "string", + "description": "The program's text: QIR (LLVM text) or OpenQASM." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64: jeff." + } + } + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes." } } }, @@ -450,6 +608,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -457,6 +620,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -471,7 +658,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -1019,6 +1206,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -1043,6 +1237,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -1165,6 +1474,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -1175,11 +1503,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -1244,10 +1567,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -1285,6 +1604,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -3092,6 +3415,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -3345,6 +3899,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -3352,6 +3911,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -3366,7 +3949,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -3914,6 +4497,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -3938,6 +4528,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -4058,6 +4763,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -4068,11 +4792,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -4137,10 +4856,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -4178,6 +4893,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -5985,6 +6704,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -8258,9 +9208,10 @@ "cutrank_single", "stabilizer_rank", "density_matrix", - "trajectories" + "trajectories", + "pulse" ], - "description": "Leave as auto unless you need a particular method." + "description": "Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." }, "seed": { "type": "integer", @@ -8559,6 +9510,128 @@ } ] }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes." + }, "programs": { "type": "array", "minItems": 1, @@ -8667,6 +9740,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -8674,6 +9752,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -8688,7 +9790,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -9236,6 +10338,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -9260,6 +10369,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -9382,6 +10606,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -9392,11 +10635,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -9461,10 +10699,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -9502,6 +10736,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -11309,6 +12547,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -11562,6 +13031,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -11569,6 +13043,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -11583,7 +13081,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -12131,6 +13629,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -12155,6 +13660,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -12275,6 +13895,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -12285,11 +13924,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -12354,10 +13988,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -12395,6 +14025,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -14202,6 +15836,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -16475,9 +18340,10 @@ "cutrank_single", "stabilizer_rank", "density_matrix", - "trajectories" + "trajectories", + "pulse" ], - "description": "Leave as auto unless you need a particular method." + "description": "Leave as auto unless you need a particular method; pulse runs a pulse program (OpenPulse calibrations on physical qubits, see pulse_schedule) under the pulse options, its error bounded." }, "seed": { "type": "integer", @@ -16776,6 +18642,128 @@ } ] }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes." + }, "programs": { "type": "array", "minItems": 1, @@ -16805,6 +18793,32 @@ } }, "description": "Each input of qasm and its values: every combination runs, the names in sorted order, the first varying slowest; an integer input's values are whole numbers." + }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", + "properties": { + "format": { + "type": "string", + "enum": [ + "qasm", + "qir", + "jeff" + ], + "description": "Its format." + }, + "program": { + "type": "string", + "description": "The program's text: QIR (LLVM text) or OpenQASM." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64: jeff." + } + } } } }, @@ -17888,6 +19902,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -17895,6 +19914,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -17909,7 +19952,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -18457,6 +20500,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -18481,6 +20531,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -18603,6 +20768,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -18613,11 +20797,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -18682,10 +20861,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -18723,6 +20898,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -20530,6 +22709,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -20783,6 +23193,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -20790,6 +23205,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -20804,7 +23243,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -21352,6 +23791,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -21376,6 +23822,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -21496,6 +24057,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -21506,11 +24086,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -21575,10 +24150,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -21616,6 +24187,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -23423,6 +25998,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -28825,6 +31631,324 @@ ] } }, + { + "name": "convert_program", + "title": "Convert a program between formats", + "description": "Carry a program between OpenQASM 3, QIR (LLVM text, read under its base and adaptive profiles, written as QIR 2.0) and jeff (its Cap'n Proto message, as base64). The answer is the program written, the program as OpenQASM 3 (what every other tool takes), each note with its code (a rotation at an arbitrary angle, a custom gate read by its name, what a format leaves out), what was read and written, and the check: the output read back and held to the program by the equivalence ladder. A construct a reader cannot hold exactly is refused with its code (Q700 to Q721) and its place: quote the code, and never guess around it. A conversion larger than the service takes is refused with the command that runs it locally.", + "inputSchema": { + "type": "object", + "required": [ + "to" + ], + "properties": { + "program": { + "type": "string", + "description": "The program's text: OpenQASM or QIR." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64: jeff." + }, + "from": { + "type": "string", + "enum": [ + "qasm", + "qir", + "jeff" + ], + "description": "Its format; found from its bytes when not given." + }, + "to": { + "type": "string", + "enum": [ + "qasm", + "qir", + "jeff" + ], + "description": "The format to write." + }, + "profile": { + "type": "string", + "enum": [ + "base", + "adaptive" + ], + "description": "QIR's profile to write: by default base when the program's measurements all come at the end, else adaptive." + }, + "check": { + "type": "boolean", + "description": "false: write it without the check." + } + } + }, + "annotations": { + "readOnlyHint": true + }, + "outputSchema": { + "$id": "wai-quantum://schemas/convert_program/1", + "type": "object", + "description": "What convert_program answers.", + "anyOf": [ + { + "anyOf": [ + { + "type": "object", + "description": "A program carried from one format to another (OpenQASM 3, QIR as LLVM text, jeff as its Cap'n Proto message) and checked (engine::formats::convert_json): the program written, the program as read in OpenQASM 3, the readers' and writer's notes with their codes, what was read and written, and the check that holds the output to the input.", + "required": [ + "ok", + "format", + "from", + "to", + "qasm", + "notes", + "read", + "written", + "check" + ], + "properties": { + "ok": { + "const": true + }, + "format": { + "const": "wai.quantum.convert/1" + }, + "from": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "to": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program written, for a text format (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program written, for a binary format (jeff), as standard base64." + }, + "qasm": { + "type": "string", + "description": "The program as read, as OpenQASM 3: what every other tool takes." + }, + "notes": { + "type": "array", + "items": { + "type": "object", + "description": "One of the reader's diagnostics: its code, what happens to the construct it is about, its message (without the line or the code), and where it stands.", + "required": [ + "code", + "outcome", + "message" + ], + "properties": { + "code": { + "type": "string" + }, + "outcome": { + "enum": [ + "refused", + "lowered", + "carried", + "preserved", + "warned" + ] + }, + "message": { + "type": "string" + }, + "line": { + "type": "integer", + "minimum": 1 + }, + "column": { + "type": "integer", + "minimum": 1 + }, + "length": { + "type": "integer", + "minimum": 0 + } + } + }, + "description": "Each warning and note, with its code (Q7xx for the formats) and, for QIR, its line." + }, + "read": { + "type": "object", + "required": [ + "format" + ], + "description": "What was read: the format, its version, a QIR module's profile, entry point, qubits, results and declared capabilities, a jeff module's tool, entry point, qubits and bits." + }, + "written": { + "type": "object", + "required": [ + "format" + ], + "description": "What was written: the format, its version, and QIR's profile." + }, + "check": { + "anyOf": [ + { + "type": "null" + }, + { + "type": "object", + "required": [ + "what", + "verdict" + ], + "properties": { + "what": { + "type": "string", + "description": "What was held to what." + }, + "verdict": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "tableau", + "exact", + "rewrites", + "random", + "state", + "shape", + "steps", + "distribution", + "identity", + "none" + ], + "description": "The equivalence ladder's check (tableau, exact and rewrites are proofs; random is evidence); steps: the same steps one for one; distribution: every outcome's probability the same (evidence); identity: OpenQASM passed through; none: unchecked." + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": [ + "number", + "null" + ] + } + } + } + } + } + ], + "description": "The output read back and held to the program read (or, for a program read into OpenQASM, written back to its format and read again), or null when no check was asked." + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, { "name": "improve_qasm", "title": "Improve a quantum program", @@ -37213,9 +40337,20 @@ "inputSchema": { "type": "object", "required": [ - "qasm", "target" ], + "anyOf": [ + { + "required": [ + "qasm" + ] + }, + { + "required": [ + "source" + ] + } + ], "properties": { "qasm": { "type": "string", @@ -37262,85 +40397,12 @@ } } }, - "mitigate": { - "description": "Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object.", - "anyOf": [ - { - "type": "string", - "enum": [ - "zne", - "pea", - "pec", - "cdr", - "vd", - "readout" - ] - }, - { - "type": "object", - "required": [ - "method" - ], - "properties": { - "method": { - "type": "string", - "enum": [ - "zne", - "pea", - "pec", - "cdr", - "vd", - "readout" - ] - }, - "shots": { - "type": "integer", - "minimum": 1, - "maximum": 1000000, - "description": "Shots per circuit (default 10000; 2000 per sampled circuit for pec)." - }, - "seed": { - "type": "integer", - "minimum": 0 - }, - "factors": { - "type": "array", - "items": { - "type": "number" - }, - "description": "zne: odd whole numbers (default 1, 3, 5); pea: factors from 1 to 10 (default 1, 1.5, 2)." - }, - "extrapolation": { - "type": "string", - "enum": [ - "richardson", - "linear", - "exponential" - ] - }, - "samples": { - "type": "integer", - "minimum": 2, - "description": "pec: sampled circuits (default 200)." - }, - "training": { - "type": "integer", - "minimum": 3, - "description": "cdr: training circuits (default 16)." - }, - "keep": { - "type": "integer", - "minimum": 0, - "description": "cdr: non-Clifford gates each training circuit keeps (default 2, and always one fewer than the program has)." - }, - "learn_shots": { - "type": "integer", - "minimum": 100, - "description": "pea, pec: shots per depth of the cycle benchmarking that learns the noise (default 60000)." - } - } - } - ] + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (input float theta;, input angle phi;), as {\"theta\": 0.3}: bound exactly before the program is read; a parameter left without one is refused (J050). In a sweep, the parameters it fixes." }, "seed": { "type": "integer", @@ -37558,6 +40620,227 @@ }, "repair": { "description": "Repair the program first, on the lines its diagnostics flag alone (as repair_qasm does): true, or the choices {\"max_iterations\": N, \"dyadic_bits\": K, \"sizes\": {\"q\": 3}}. The result's `repaired` holds the program that ran and each repair." + }, + "mitigate": { + "description": "Mitigate the job's expectation values (or, for readout, its counts) under its own noise: zne (the whole program folded U(U†U)^k and extrapolated), pea (the noise learned as a sparse Pauli–Lindblad model and amplified), pec (the learned channels inverted and sampled), cdr (a line fitted over near-Clifford training circuits), vd (two copies), readout (the counts' flips inverted). Needs noise and observables (shots for readout), at most 8 qubits. The result's `mitigation` gives raw and mitigated values with standard errors, the ideal value (known because this is a simulation), the method's bias and variance assumptions and its cost. A method's name, or an object.", + "anyOf": [ + { + "type": "string", + "enum": [ + "zne", + "pea", + "pec", + "cdr", + "vd", + "readout" + ] + }, + { + "type": "object", + "required": [ + "method" + ], + "properties": { + "method": { + "type": "string", + "enum": [ + "zne", + "pea", + "pec", + "cdr", + "vd", + "readout" + ] + }, + "shots": { + "type": "integer", + "minimum": 1, + "maximum": 1000000, + "description": "Shots per circuit (default 10000; 2000 per sampled circuit for pec)." + }, + "seed": { + "type": "integer", + "minimum": 0 + }, + "factors": { + "type": "array", + "items": { + "type": "number" + }, + "description": "zne: odd whole numbers (default 1, 3, 5); pea: factors from 1 to 10 (default 1, 1.5, 2)." + }, + "extrapolation": { + "type": "string", + "enum": [ + "richardson", + "linear", + "exponential" + ] + }, + "samples": { + "type": "integer", + "minimum": 2, + "description": "pec: sampled circuits (default 200)." + }, + "training": { + "type": "integer", + "minimum": 3, + "description": "cdr: training circuits (default 16)." + }, + "keep": { + "type": "integer", + "minimum": 0, + "description": "cdr: non-Clifford gates each training circuit keeps (default 2, and always one fewer than the program has)." + }, + "learn_shots": { + "type": "integer", + "minimum": 100, + "description": "pea, pec: shots per depth of the cycle benchmarking that learns the noise (default 60000)." + } + } + } + ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm: read to the job's qasm before the job is read (a module that does not read is refused with the reader's code, Q700 to Q721), the request keeping its source.", + "properties": { + "format": { + "type": "string", + "enum": [ + "qasm", + "qir", + "jeff" + ], + "description": "Its format." + }, + "program": { + "type": "string", + "description": "The program's text: QIR (LLVM text) or OpenQASM." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64: jeff." + } + } } } }, @@ -37637,6 +40920,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -37644,6 +40932,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -37658,7 +40970,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -38206,6 +41518,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -38230,6 +41549,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -38352,6 +41786,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -38362,11 +41815,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -38431,10 +41879,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -38472,6 +41916,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -40279,6 +43727,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -40532,6 +44211,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -40539,6 +44223,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -40553,7 +44261,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -41101,6 +44809,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -41125,6 +44840,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } }, @@ -41245,6 +45075,25 @@ "batch": { "type": "integer" }, + "bound": { + "type": "number", + "description": "The bound this result is held to, by method: a pulse run (class bounded): every probability within this of the exact solution of the model's master equation, the truncation bound and the rounding estimate together; stabilizer_rank's sampled mode (class estimate): the bound on the distance of the estimated state from the state, holding with the probability confidence states.", + "minimum": 0 + }, + "truncation_bound": { + "type": "number", + "description": "A pulse run: the proved bound, in the trace norm, on what the integrator's series leaves out." + }, + "rounding_estimate": { + "type": "number", + "description": "A pulse run: an estimate of floating-point rounding beside the bound, not a proof." + }, + "tolerance": { + "type": "number" + }, + "norm": { + "type": "string" + }, "t_count": { "type": "integer", "minimum": 0, @@ -41255,11 +45104,6 @@ "minimum": 1, "description": "stabilizer_rank: the stabilizer branches summed (2^t exactly), or drawn." }, - "bound": { - "type": "number", - "minimum": 0, - "description": "stabilizer_rank's sampled mode: the bound on the distance of the estimated state from the state, holding with the probability confidence states." - }, "confidence": { "type": "number", "description": "The probability a stated bound holds." @@ -41324,10 +45168,6 @@ "type": "number", "description": "A bound on |exact − value|: rigorous for the bounded class; with confidence beside it, holding with that probability." }, - "confidence": { - "type": "number", - "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." - }, "peak_terms": { "type": "integer" }, @@ -41365,6 +45205,10 @@ } } } + }, + "confidence": { + "type": "number", + "description": "The probability the bound holds, for a bound that holds with a stated probability (stabilizer_rank's sampled mode)." } } } @@ -43172,6 +47016,237 @@ } } } + }, + "pulse": { + "type": "object", + "description": "A pulse run (method pulse, engine::pulse): what was read and its distribution, the final populations, each capture's reading, the final density matrix's digest, the schedule's length, the integrator and its step, the device and where each parameter came from, and what the receipt binds (calibration).", + "required": [ + "read", + "outcome_bits", + "populations", + "simulated_qubits", + "density_hash", + "integrator", + "device", + "calibration" + ], + "properties": { + "read": { + "type": "string", + "description": "What the distribution reads: the captures together (into the program's bits when each writes one), or the final state." + }, + "outcome_bits": { + "type": "array", + "items": { + "type": "string" + }, + "description": "What each character of an outcome is, left to right: a program bit (c[0]) or a qubit ($0)." + }, + "distribution": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "number" + }, + "description": "The probability of each outcome, which the counts sample; null when the captures start at different samples." + }, + "populations": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The final state read on every simulated qubit, the highest qubit first, a level above 0 read as 1." + }, + "simulated_qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "captures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "frame": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "start_ns": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + }, + "p1": { + "type": "number" + }, + "p2": { + "type": "number" + } + } + } + }, + "leakage": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "p2": { + "type": "number" + } + } + }, + "description": "With three levels: each qubit's final probability of level 2." + }, + "trace": { + "type": "number" + }, + "density_hash": { + "type": "string", + "description": "The BLAKE3 of the final density matrix's bits: the same on every platform." + }, + "duration": { + "type": "integer" + }, + "duration_ns": { + "type": "number" + }, + "integrator": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "substeps": { + "type": "integer" + }, + "step_ns": { + "type": "number" + }, + "steps": { + "type": "integer" + }, + "norm_max": { + "type": "number" + }, + "frame": { + "type": "string" + } + } + }, + "device": { + "type": "object", + "properties": { + "levels": { + "type": "integer" + }, + "dt_ns": { + "type": "number" + }, + "qubits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "qubit": { + "type": "integer" + }, + "frequency_hz": { + "type": "number" + }, + "rabi_hz": { + "type": "number" + }, + "anharmonicity_hz": { + "type": "number" + }, + "t1_ns": { + "type": "number" + }, + "t2_ns": { + "type": "number" + }, + "from": { + "type": "object", + "additionalProperties": { + "enum": [ + "pulse", + "target", + "default", + "none" + ] + } + } + } + } + }, + "couplings": { + "type": "array" + }, + "model": { + "type": "string" + } + } + }, + "calibration": { + "type": "object", + "description": "What the receipt binds: the program's, its calibrations', the schedule's and the device's digests, and the target snapshot.", + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "not_modelled": { + "type": "array", + "items": { + "type": "string" + } + } + } } } }, @@ -43607,6 +47682,11 @@ "required": [ "programs" ] + }, + { + "required": [ + "source" + ] } ], "properties": { @@ -43614,6 +47694,30 @@ "type": "string", "description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use." }, + "source": { + "type": "object", + "required": [ + "format" + ], + "description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.", + "properties": { + "format": { + "enum": [ + "qasm", + "qir", + "jeff" + ] + }, + "program": { + "type": "string", + "description": "The program's text (OpenQASM, QIR)." + }, + "program_base64": { + "type": "string", + "description": "The program's bytes as base64 (jeff)." + } + } + }, "shots": { "type": "integer", "minimum": 0, @@ -43628,7 +47732,7 @@ }, "method": { "type": "string", - "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it." + "description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options." }, "observables": { "type": "array", @@ -44176,6 +48280,13 @@ }, "description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest." }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point." + }, "dry_run": { "type": "boolean", "description": "With true: what the host would do with the job or set, running nothing." @@ -44200,6 +48311,121 @@ ] } ] + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } } } } @@ -46391,6 +50617,9912 @@ } ] } + }, + { + "name": "pulse_schedule", + "title": "Read a pulse program into its schedule", + "description": "Read a pulse program (OpenPulse calibrations: ports, frames, waveforms, play, delay, shift_phase, set_phase, shift_frequency, set_frequency, captures and barriers) into its schedule on frames: every instruction at its sample, each waveform's samples (gaussian, drag, gaussian_square, constant, sech, sine, or explicit), each gate call with the samples its calibration spans, and the digests a pulse run's receipt binds (the program, its calibrations, the schedule). Durations are whole samples of dt (pulse.dt_ns, default 0.5 ns) or refused. A construct the reader does not take is refused with a Q code and its line. Sealed with the service's key. To run it, give the program to run_quantum_circuit with method \"pulse\".", + "inputSchema": { + "type": "object", + "required": [ + "qasm" + ], + "properties": { + "qasm": { + "type": "string", + "description": "A pulse program: OpenQASM 3 with `defcalgrammar \"openpulse\";`, `cal` blocks declaring ports (d0 drives qubit 0, m0 is its measurement port, a0 its acquisition port), frames (newframe(port, frequency Hz, phase)) and waveforms, a `defcal` for every gate it calls on physical qubits ($0), and the calls." + }, + "pulse": { + "type": "object", + "description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.", + "additionalProperties": false, + "properties": { + "dt_ns": { + "type": "number", + "exclusiveMinimum": 0, + "maximum": 1000, + "description": "The sample period, ns (default 0.5)." + }, + "levels": { + "type": "integer", + "enum": [ + 2, + 3 + ], + "description": "Levels kept per qubit (default 2; 3 shows leakage)." + }, + "tolerance": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1, + "description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it." + }, + "substeps": { + "type": "integer", + "minimum": 1, + "maximum": 4096, + "description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)." + }, + "qubits": { + "type": "object", + "description": "Each qubit's parameters by its index, over the target's and the defaults.", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency_ghz": { + "type": "number", + "description": "Its frequency, GHz." + }, + "rabi_mhz": { + "type": "number", + "description": "Its Rabi frequency at full amplitude, MHz." + }, + "anharmonicity_mhz": { + "type": "number", + "description": "Its anharmonicity, MHz." + }, + "t1_us": { + "type": "number", + "description": "Its relaxation time, µs." + }, + "t2_us": { + "type": "number", + "description": "Its coherence time, µs (at most 2·T1)." + } + } + } + }, + "couplings": { + "type": "array", + "description": "Static ZZ couplings.", + "items": { + "type": "object", + "required": [ + "qubits", + "zz_khz" + ], + "additionalProperties": false, + "properties": { + "qubits": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 2, + "maxItems": 2 + }, + "zz_khz": { + "type": "number", + "description": "The coupling's rate, kHz." + } + } + } + }, + "ports": { + "type": "object", + "description": "Ports by name: what each is for and the qubit it reaches.", + "additionalProperties": { + "type": "object", + "required": [ + "kind", + "qubit" + ], + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/pulse_schedule/1", + "type": "object", + "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.pulse/1", + "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A schedule or a check, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A pulse program's schedule (pulse_schedule, wai-quantum pulse schedule, POST /v1/pulse/schedule): its frames and ports, every instruction at its sample, each waveform's samples, the gate calls, the reader's notes, and the digests a run binds.", + "required": [ + "answer", + "dt_ns", + "duration", + "frames", + "waveforms", + "instructions", + "calls", + "calibration" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.pulse/1" + }, + "answer": { + "const": "schedule" + }, + "dt_ns": { + "type": "number", + "description": "The sample period, ns." + }, + "duration": { + "type": "integer", + "description": "The latest time of any frame, samples." + }, + "duration_ns": { + "type": "number" + }, + "grammar": { + "type": [ + "string", + "null" + ] + }, + "ports": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer" + } + } + } + }, + "frames": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "frequency_hz": { + "type": "number" + }, + "phase": { + "type": "number" + } + } + } + }, + "waveforms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "length": { + "type": "integer" + }, + "samples": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + } + }, + "samples_every": { + "type": "integer", + "description": "Each k-th sample is drawn, when the schedule holds more than the view writes out." + } + } + } + }, + "instructions": { + "type": "array", + "items": { + "type": "object", + "required": [ + "frame", + "op", + "start", + "length" + ], + "properties": { + "frame": { + "type": "integer" + }, + "op": { + "enum": [ + "play", + "delay", + "shift_phase", + "set_phase", + "shift_frequency", + "set_frequency", + "capture", + "barrier" + ] + }, + "start": { + "type": "integer" + }, + "length": { + "type": "integer" + }, + "line": { + "type": "integer" + }, + "waveform": { + "type": "integer" + }, + "phase": { + "type": "number" + }, + "frequency_hz": { + "type": "number" + }, + "carrier": { + "type": "number", + "description": "The carrier's phase at the play's first sample, cycles in [0, 1)." + }, + "value": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "calls": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "params": { + "type": "array", + "items": { + "type": "number" + } + }, + "start": { + "type": "integer" + }, + "end": { + "type": "integer" + }, + "line": { + "type": "integer" + } + } + } + }, + "bits": { + "type": "array", + "items": { + "type": "string" + } + }, + "qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "decimated": { + "type": "string" + }, + "diagnostics": { + "type": "array", + "items": { + "type": "object", + "description": "A reader's note or warning (qasm::diag).", + "properties": { + "code": { + "type": "string" + }, + "outcome": { + "type": "string" + }, + "message": { + "type": "string" + }, + "line": { + "type": "integer" + }, + "column": { + "type": "integer" + }, + "length": { + "type": "integer" + } + } + } + }, + "calibration": { + "type": "object", + "description": "What a pulse run's receipt binds of the program: the BLAKE3 of the control program's text, of its calibrations as written (every cal, defcal and defcalgrammar, joined by newlines), and of the schedule's JSON; a run adds the device's and the target snapshot's.", + "required": [ + "program", + "calibrations", + "schedule" + ], + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + } + } + }, + { + "type": "object", + "description": "A pulse job checked (pulse_check, wai-quantum pulse check, POST /v1/pulse/check): its receipt's signature, its program's digest, and the request run again with the result held to the one given.", + "required": [ + "answer", + "verified", + "signature", + "program", + "reproduced", + "differences", + "statement" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.pulse/1" + }, + "answer": { + "const": "check" + }, + "verified": { + "type": "boolean" + }, + "signature": { + "type": "boolean" + }, + "key": {}, + "program": { + "type": "boolean" + }, + "reproduced": { + "type": "boolean" + }, + "differences": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Each field (or field.member) whose value differs from the run here." + }, + "density_hash": { + "type": "object", + "properties": { + "given": {}, + "recomputed": {} + } + }, + "calibration": {}, + "statement": { + "type": "string" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "pulse_check", + "title": "Check a pulse run by running it again", + "description": "Check a pulse job as a host returned it ({\"request\", \"result\"}, the result with its receipt): the receipt's signature, the program's digest against the request's text, and the request run again here with the result held to the one given field by field (the density matrix's digest among them), each difference named. A pulse run is the same bits on every platform, so a result that does not reproduce was not made from that request by this engine. Sealed with the service's key. Quote `verified` and the statement.", + "inputSchema": { + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The pulse job's request." + }, + "result": { + "type": "object", + "description": "Its result, with its receipt." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/pulse_check/1", + "type": "object", + "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.pulse/1", + "description": "A pulse answer as every host gives it (engine::pulse: pulse_schedule and pulse_check on both servers, wai-quantum pulse, POST /v1/pulse/*, the Studio): the request, and the result sealed in a job's form. A pulse program's schedule on frames, or a pulse job checked by running it again. A pulse run itself is a job (method pulse) and follows job-result.v1.json. A result names the engine that made it and this schema (engine and schema). docs/pulse.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A schedule or a check, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A pulse program's schedule (pulse_schedule, wai-quantum pulse schedule, POST /v1/pulse/schedule): its frames and ports, every instruction at its sample, each waveform's samples, the gate calls, the reader's notes, and the digests a run binds.", + "required": [ + "answer", + "dt_ns", + "duration", + "frames", + "waveforms", + "instructions", + "calls", + "calibration" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.pulse/1" + }, + "answer": { + "const": "schedule" + }, + "dt_ns": { + "type": "number", + "description": "The sample period, ns." + }, + "duration": { + "type": "integer", + "description": "The latest time of any frame, samples." + }, + "duration_ns": { + "type": "number" + }, + "grammar": { + "type": [ + "string", + "null" + ] + }, + "ports": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "qubit": { + "type": "integer" + } + } + } + }, + "frames": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "string" + }, + "qubit": { + "type": "integer" + }, + "kind": { + "enum": [ + "drive", + "measure", + "acquire" + ] + }, + "frequency_hz": { + "type": "number" + }, + "phase": { + "type": "number" + } + } + } + }, + "waveforms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "length": { + "type": "integer" + }, + "samples": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + } + }, + "samples_every": { + "type": "integer", + "description": "Each k-th sample is drawn, when the schedule holds more than the view writes out." + } + } + } + }, + "instructions": { + "type": "array", + "items": { + "type": "object", + "required": [ + "frame", + "op", + "start", + "length" + ], + "properties": { + "frame": { + "type": "integer" + }, + "op": { + "enum": [ + "play", + "delay", + "shift_phase", + "set_phase", + "shift_frequency", + "set_frequency", + "capture", + "barrier" + ] + }, + "start": { + "type": "integer" + }, + "length": { + "type": "integer" + }, + "line": { + "type": "integer" + }, + "waveform": { + "type": "integer" + }, + "phase": { + "type": "number" + }, + "frequency_hz": { + "type": "number" + }, + "carrier": { + "type": "number", + "description": "The carrier's phase at the play's first sample, cycles in [0, 1)." + }, + "value": { + "type": "number" + }, + "bit": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "calls": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "params": { + "type": "array", + "items": { + "type": "number" + } + }, + "start": { + "type": "integer" + }, + "end": { + "type": "integer" + }, + "line": { + "type": "integer" + } + } + } + }, + "bits": { + "type": "array", + "items": { + "type": "string" + } + }, + "qubits": { + "type": "array", + "items": { + "type": "integer" + } + }, + "decimated": { + "type": "string" + }, + "diagnostics": { + "type": "array", + "items": { + "type": "object", + "description": "A reader's note or warning (qasm::diag).", + "properties": { + "code": { + "type": "string" + }, + "outcome": { + "type": "string" + }, + "message": { + "type": "string" + }, + "line": { + "type": "integer" + }, + "column": { + "type": "integer" + }, + "length": { + "type": "integer" + } + } + } + }, + "calibration": { + "type": "object", + "description": "What a pulse run's receipt binds of the program: the BLAKE3 of the control program's text, of its calibrations as written (every cal, defcal and defcalgrammar, joined by newlines), and of the schedule's JSON; a run adds the device's and the target snapshot's.", + "required": [ + "program", + "calibrations", + "schedule" + ], + "properties": { + "program": { + "type": "string" + }, + "calibrations": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "device": { + "type": "string" + }, + "target": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "calibration": { + "type": "object" + } + } + } + } + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + } + } + }, + { + "type": "object", + "description": "A pulse job checked (pulse_check, wai-quantum pulse check, POST /v1/pulse/check): its receipt's signature, its program's digest, and the request run again with the result held to the one given.", + "required": [ + "answer", + "verified", + "signature", + "program", + "reproduced", + "differences", + "statement" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.pulse/1" + }, + "answer": { + "const": "check" + }, + "verified": { + "type": "boolean" + }, + "signature": { + "type": "boolean" + }, + "key": {}, + "program": { + "type": "boolean" + }, + "reproduced": { + "type": "boolean" + }, + "differences": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Each field (or field.member) whose value differs from the run here." + }, + "density_hash": { + "type": "object", + "properties": { + "given": {}, + "recomputed": {} + } + }, + "calibration": {}, + "statement": { + "type": "string" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "gradient_qasm", + "title": "The exact gradient of a Hamiltonian's expectation by a program's parameters", + "description": "The expectation E = ⟨ψ|H|ψ⟩ of a Hamiltonian at a program's parameters, and its gradient by each parameter, exactly: by adjoint differentiation or the parameter-shift rule on the double-precision state vector (at most 20 qubits, no noise, measurements only at the end). The reader follows each parameter into the gates, so an argument may be any expression of the built-in functions. The answer states its method, that it is f64 and approximate, and a bound on the rounding of the value and of each component (precision.rounding_bound). Sealed with the service's key. Quote the gradient with its bound.", + "inputSchema": { + "type": "object", + "required": [ + "qasm", + "params", + "hamiltonian" + ], + "properties": { + "qasm": { + "type": "string", + "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." + }, + "hamiltonian": { + "type": "array", + "minItems": 1, + "maxItems": 4096, + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "pauli" + ], + "properties": { + "pauli": { + "type": "string" + }, + "coeff": { + "type": "number" + } + } + } + ] + }, + "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ], + "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/gradient_qasm/1", + "type": "object", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.algorithms/1", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", + "required": [ + "call", + "value", + "gradient", + "params", + "method", + "how", + "evaluations", + "qubits", + "gates", + "moved_gates", + "parameters", + "terms", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "gradient" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "value": { + "type": "number", + "description": "⟨ψ|H|ψ⟩ at the params." + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "∂E/∂p for each parameter p, by name." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The point, by name." + }, + "method": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "how": { + "type": "string" + }, + "evaluations": { + "type": "integer", + "minimum": 0, + "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "moved_gates": { + "type": "integer", + "minimum": 0, + "description": "Gates a parameter moves." + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0, + "description": "The Hamiltonian's Pauli terms." + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "optimize" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + } + } + }, + { + "type": "object", + "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "reference" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "vqe" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "reference": { + "anyOf": [ + { + "type": "object", + "required": [ + "ground_energy", + "how", + "gap" + ], + "properties": { + "ground_energy": { + "type": "number" + }, + "first_excited": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "how": { + "type": "string" + }, + "gap": { + "type": "number", + "description": "The best energy found above the ground energy." + } + } + }, + { + "type": "object", + "required": [ + "unchecked" + ], + "properties": { + "unchecked": { + "type": "string" + } + } + } + ] + }, + "ansatz": { + "type": "object", + "required": [ + "qasm", + "params", + "kind" + ], + "properties": { + "qasm": { + "type": "string" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "kind": { + "const": "hardware_efficient" + } + } + } + } + }, + { + "type": "object", + "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "graph", + "layers", + "program", + "hamiltonian", + "maxcut" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "qaoa" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 0 + }, + "edges": { + "type": "array", + "items": { + "type": "array", + "minItems": 3, + "maxItems": 3 + } + } + } + }, + "layers": { + "type": "integer", + "minimum": 0 + }, + "program": { + "type": "string" + }, + "hamiltonian": { + "type": "array" + }, + "maxcut": { + "type": "object", + "required": [ + "max_cut", + "optimal", + "optimal_count", + "how", + "expected_cut", + "ratio", + "most_likely", + "p_optimal", + "bits" + ], + "properties": { + "max_cut": { + "type": "number" + }, + "optimal": { + "type": "array", + "items": { + "type": "string" + } + }, + "optimal_count": { + "type": "integer", + "minimum": 0 + }, + "how": { + "type": "string" + }, + "expected_cut": { + "type": "number" + }, + "ratio": { + "type": "number" + }, + "most_likely": { + "type": "object", + "required": [ + "bits", + "probability", + "cut", + "optimal" + ], + "properties": { + "bits": { + "type": "string" + }, + "probability": { + "type": "number" + }, + "cut": { + "type": "number" + }, + "optimal": { + "type": "boolean" + } + } + }, + "p_optimal": { + "type": "number" + }, + "bits": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", + "required": [ + "call", + "algorithm", + "qasm", + "qubits", + "gates", + "reads", + "expected", + "check" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "build" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "qasm": { + "type": "string" + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "reads": { + "type": "object", + "description": "How to read the program's result." + }, + "expected": { + "type": "object", + "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." + }, + "check": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "exact", + "random", + "none" + ] + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": "number" + }, + "reference": { + "type": "string" + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "optimize_qasm", + "title": "Minimise a Hamiltonian's expectation over a program's parameters", + "description": "Minimise E = ⟨ψ|H|ψ⟩ over a program's parameters from the given params, deterministically: gradient descent with a fixed step, Adam, or SPSA from a seeded stream (at most 2000 steps). Every step's parameters and value (and gradient, or SPSA's perturbation and estimate) are listed, each step a link of a digest chain from the request, best and final given; the same request gives the same bytes on every platform. Sealed with the service's key: the receipt binds the program, every step, the method and the seed, and verify_quantum_result (or wai-quantum verify) re-runs it. A minimum found is a minimum along this path, not a proof of the global one.", + "inputSchema": { + "type": "object", + "required": [ + "qasm", + "params", + "hamiltonian" + ], + "properties": { + "qasm": { + "type": "string", + "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." + }, + "hamiltonian": { + "type": "array", + "minItems": 1, + "maxItems": 4096, + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "pauli" + ], + "properties": { + "pauli": { + "type": "string" + }, + "coeff": { + "type": "number" + } + } + } + ] + }, + "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." + }, + "optimizer": { + "anyOf": [ + { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + } + } + } + ], + "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." + }, + "steps": { + "type": "integer", + "minimum": 1, + "maximum": 2000, + "description": "Steps to take (default 100)." + }, + "step_size": { + "type": "number", + "exclusiveMinimum": 0, + "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ], + "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." + }, + "seed": { + "type": "integer", + "minimum": 0, + "description": "SPSA's seed (default 1)." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/optimize_qasm/1", + "type": "object", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.algorithms/1", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", + "required": [ + "call", + "value", + "gradient", + "params", + "method", + "how", + "evaluations", + "qubits", + "gates", + "moved_gates", + "parameters", + "terms", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "gradient" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "value": { + "type": "number", + "description": "⟨ψ|H|ψ⟩ at the params." + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "∂E/∂p for each parameter p, by name." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The point, by name." + }, + "method": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "how": { + "type": "string" + }, + "evaluations": { + "type": "integer", + "minimum": 0, + "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "moved_gates": { + "type": "integer", + "minimum": 0, + "description": "Gates a parameter moves." + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0, + "description": "The Hamiltonian's Pauli terms." + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "optimize" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + } + } + }, + { + "type": "object", + "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "reference" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "vqe" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "reference": { + "anyOf": [ + { + "type": "object", + "required": [ + "ground_energy", + "how", + "gap" + ], + "properties": { + "ground_energy": { + "type": "number" + }, + "first_excited": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "how": { + "type": "string" + }, + "gap": { + "type": "number", + "description": "The best energy found above the ground energy." + } + } + }, + { + "type": "object", + "required": [ + "unchecked" + ], + "properties": { + "unchecked": { + "type": "string" + } + } + } + ] + }, + "ansatz": { + "type": "object", + "required": [ + "qasm", + "params", + "kind" + ], + "properties": { + "qasm": { + "type": "string" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "kind": { + "const": "hardware_efficient" + } + } + } + } + }, + { + "type": "object", + "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "graph", + "layers", + "program", + "hamiltonian", + "maxcut" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "qaoa" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 0 + }, + "edges": { + "type": "array", + "items": { + "type": "array", + "minItems": 3, + "maxItems": 3 + } + } + } + }, + "layers": { + "type": "integer", + "minimum": 0 + }, + "program": { + "type": "string" + }, + "hamiltonian": { + "type": "array" + }, + "maxcut": { + "type": "object", + "required": [ + "max_cut", + "optimal", + "optimal_count", + "how", + "expected_cut", + "ratio", + "most_likely", + "p_optimal", + "bits" + ], + "properties": { + "max_cut": { + "type": "number" + }, + "optimal": { + "type": "array", + "items": { + "type": "string" + } + }, + "optimal_count": { + "type": "integer", + "minimum": 0 + }, + "how": { + "type": "string" + }, + "expected_cut": { + "type": "number" + }, + "ratio": { + "type": "number" + }, + "most_likely": { + "type": "object", + "required": [ + "bits", + "probability", + "cut", + "optimal" + ], + "properties": { + "bits": { + "type": "string" + }, + "probability": { + "type": "number" + }, + "cut": { + "type": "number" + }, + "optimal": { + "type": "boolean" + } + } + }, + "p_optimal": { + "type": "number" + }, + "bits": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", + "required": [ + "call", + "algorithm", + "qasm", + "qubits", + "gates", + "reads", + "expected", + "check" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "build" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "qasm": { + "type": "string" + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "reads": { + "type": "object", + "description": "How to read the program's result." + }, + "expected": { + "type": "object", + "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." + }, + "check": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "exact", + "random", + "none" + ] + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": "number" + }, + "reference": { + "type": "string" + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "vqe_ground_state", + "title": "Find a Hamiltonian's ground energy by the variational eigensolver", + "description": "The variational eigensolver: an ansatz (the program given as qasm with params, or ansatz {\"layers\": L}: layers of ry and rz on every qubit and a ring of cx, its parameters t0, t1, … from 0.1) optimised on the Hamiltonian as optimize_qasm does. At most 8 qubits the answer sets the energy found beside the exact ground energy by diagonalisation (reference.ground_energy and gap); the energy found is never below it. Sealed with the service's key. Report the gap: an ansatz that cannot reach the ground state stops above it.", + "inputSchema": { + "type": "object", + "required": [ + "hamiltonian" + ], + "properties": { + "hamiltonian": { + "type": "array", + "minItems": 1, + "maxItems": 4096, + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "pauli" + ], + "properties": { + "pauli": { + "type": "string" + }, + "coeff": { + "type": "number" + } + } + } + ] + }, + "description": "A Hamiltonian as Pauli terms summed: \"Z0 Z1\", \"0.5 X2\", \"-1.5\" (a constant), or {\"pauli\": \"Y0 Y1\", \"coeff\": -0.7}; qubit 0 is q[0]." + }, + "qasm": { + "type": "string", + "description": "The program, OpenQASM 3: its parameters declared `input float theta;` (or `input angle theta;`) and used in gates' arguments, through arithmetic, the built-in functions and gate definitions (not under a modifier, in a variable, a condition or an index: refused with Q129)." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "A value for each parameter, by name, as {\"theta\": 0.3}: bound exactly. Every parameter the program declares needs one (J050)." + }, + "ansatz": { + "type": "object", + "properties": { + "layers": { + "type": "integer", + "minimum": 1, + "maximum": 16 + }, + "qubits": { + "type": "integer", + "minimum": 1, + "maximum": 20 + } + }, + "description": "The built-in ansatz in place of qasm (layers default 2, qubits the Hamiltonian's)." + }, + "optimizer": { + "anyOf": [ + { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + } + } + } + ], + "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." + }, + "steps": { + "type": "integer", + "minimum": 1, + "maximum": 2000, + "description": "Steps to take (default 100)." + }, + "step_size": { + "type": "number", + "exclusiveMinimum": 0, + "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ], + "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." + }, + "seed": { + "type": "integer", + "minimum": 0, + "description": "SPSA's seed (default 1)." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/vqe_ground_state/1", + "type": "object", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.algorithms/1", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", + "required": [ + "call", + "value", + "gradient", + "params", + "method", + "how", + "evaluations", + "qubits", + "gates", + "moved_gates", + "parameters", + "terms", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "gradient" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "value": { + "type": "number", + "description": "⟨ψ|H|ψ⟩ at the params." + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "∂E/∂p for each parameter p, by name." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The point, by name." + }, + "method": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "how": { + "type": "string" + }, + "evaluations": { + "type": "integer", + "minimum": 0, + "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "moved_gates": { + "type": "integer", + "minimum": 0, + "description": "Gates a parameter moves." + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0, + "description": "The Hamiltonian's Pauli terms." + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "optimize" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + } + } + }, + { + "type": "object", + "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "reference" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "vqe" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "reference": { + "anyOf": [ + { + "type": "object", + "required": [ + "ground_energy", + "how", + "gap" + ], + "properties": { + "ground_energy": { + "type": "number" + }, + "first_excited": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "how": { + "type": "string" + }, + "gap": { + "type": "number", + "description": "The best energy found above the ground energy." + } + } + }, + { + "type": "object", + "required": [ + "unchecked" + ], + "properties": { + "unchecked": { + "type": "string" + } + } + } + ] + }, + "ansatz": { + "type": "object", + "required": [ + "qasm", + "params", + "kind" + ], + "properties": { + "qasm": { + "type": "string" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "kind": { + "const": "hardware_efficient" + } + } + } + } + }, + { + "type": "object", + "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "graph", + "layers", + "program", + "hamiltonian", + "maxcut" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "qaoa" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 0 + }, + "edges": { + "type": "array", + "items": { + "type": "array", + "minItems": 3, + "maxItems": 3 + } + } + } + }, + "layers": { + "type": "integer", + "minimum": 0 + }, + "program": { + "type": "string" + }, + "hamiltonian": { + "type": "array" + }, + "maxcut": { + "type": "object", + "required": [ + "max_cut", + "optimal", + "optimal_count", + "how", + "expected_cut", + "ratio", + "most_likely", + "p_optimal", + "bits" + ], + "properties": { + "max_cut": { + "type": "number" + }, + "optimal": { + "type": "array", + "items": { + "type": "string" + } + }, + "optimal_count": { + "type": "integer", + "minimum": 0 + }, + "how": { + "type": "string" + }, + "expected_cut": { + "type": "number" + }, + "ratio": { + "type": "number" + }, + "most_likely": { + "type": "object", + "required": [ + "bits", + "probability", + "cut", + "optimal" + ], + "properties": { + "bits": { + "type": "string" + }, + "probability": { + "type": "number" + }, + "cut": { + "type": "number" + }, + "optimal": { + "type": "boolean" + } + } + }, + "p_optimal": { + "type": "number" + }, + "bits": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", + "required": [ + "call", + "algorithm", + "qasm", + "qubits", + "gates", + "reads", + "expected", + "check" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "build" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "qasm": { + "type": "string" + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "reads": { + "type": "object", + "description": "How to read the program's result." + }, + "expected": { + "type": "object", + "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." + }, + "check": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "exact", + "random", + "none" + ] + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": "number" + }, + "reference": { + "type": "string" + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "qaoa_maxcut", + "title": "Solve Max-Cut on a graph by QAOA", + "description": "Max-Cut by the quantum approximate optimisation algorithm: the program (|+⟩ⁿ, then for each layer rzz(gamma·w) on every edge and rx(2·beta) on every qubit) and its cost Hamiltonian built from the graph (at most 20 vertices, 16 layers), optimised as optimize_qasm does from the params or a linear ramp, and read against the maximum cut found by brute force: the expected cut and its ratio to the maximum, the likeliest assignment and whether it is optimal, and the probability of an optimal one. Sealed with the service's key.", + "inputSchema": { + "type": "object", + "required": [ + "graph" + ], + "properties": { + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 2, + "maximum": 20 + }, + "edges": { + "type": "array", + "minItems": 1, + "maxItems": 400, + "items": { + "type": "array", + "minItems": 2, + "maxItems": 3, + "items": { + "type": "number" + } + }, + "description": "Each edge [i, j] or [i, j, weight]." + } + } + }, + "layers": { + "type": "integer", + "minimum": 1, + "maximum": 16, + "description": "QAOA's p (default 1)." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "gamma_0, beta_0, … to start from." + }, + "optimizer": { + "anyOf": [ + { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + } + } + } + ], + "description": "gradient_descent (θ ← θ − step·∇E), adam (default; beta1, beta2, epsilon), or spsa (two evaluations a step along a ±1 perturbation from the seeded stream; c, A, alpha, gamma)." + }, + "steps": { + "type": "integer", + "minimum": 1, + "maximum": 2000, + "description": "Steps to take (default 100)." + }, + "step_size": { + "type": "number", + "exclusiveMinimum": 0, + "description": "The step (gradient descent 0.1, Adam 0.05) or SPSA's gain a (0.2)." + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ], + "description": "adjoint (the default: one pass forward, one back) or parameter_shift (each gate a parameter moves run at shifted angles: two terms, four for a controlled rotation); both exact up to f64 rounding." + }, + "seed": { + "type": "integer", + "minimum": 0, + "description": "SPSA's seed (default 1)." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/qaoa_maxcut/1", + "type": "object", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.algorithms/1", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", + "required": [ + "call", + "value", + "gradient", + "params", + "method", + "how", + "evaluations", + "qubits", + "gates", + "moved_gates", + "parameters", + "terms", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "gradient" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "value": { + "type": "number", + "description": "⟨ψ|H|ψ⟩ at the params." + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "∂E/∂p for each parameter p, by name." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The point, by name." + }, + "method": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "how": { + "type": "string" + }, + "evaluations": { + "type": "integer", + "minimum": 0, + "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "moved_gates": { + "type": "integer", + "minimum": 0, + "description": "Gates a parameter moves." + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0, + "description": "The Hamiltonian's Pauli terms." + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "optimize" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + } + } + }, + { + "type": "object", + "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "reference" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "vqe" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "reference": { + "anyOf": [ + { + "type": "object", + "required": [ + "ground_energy", + "how", + "gap" + ], + "properties": { + "ground_energy": { + "type": "number" + }, + "first_excited": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "how": { + "type": "string" + }, + "gap": { + "type": "number", + "description": "The best energy found above the ground energy." + } + } + }, + { + "type": "object", + "required": [ + "unchecked" + ], + "properties": { + "unchecked": { + "type": "string" + } + } + } + ] + }, + "ansatz": { + "type": "object", + "required": [ + "qasm", + "params", + "kind" + ], + "properties": { + "qasm": { + "type": "string" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "kind": { + "const": "hardware_efficient" + } + } + } + } + }, + { + "type": "object", + "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "graph", + "layers", + "program", + "hamiltonian", + "maxcut" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "qaoa" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 0 + }, + "edges": { + "type": "array", + "items": { + "type": "array", + "minItems": 3, + "maxItems": 3 + } + } + } + }, + "layers": { + "type": "integer", + "minimum": 0 + }, + "program": { + "type": "string" + }, + "hamiltonian": { + "type": "array" + }, + "maxcut": { + "type": "object", + "required": [ + "max_cut", + "optimal", + "optimal_count", + "how", + "expected_cut", + "ratio", + "most_likely", + "p_optimal", + "bits" + ], + "properties": { + "max_cut": { + "type": "number" + }, + "optimal": { + "type": "array", + "items": { + "type": "string" + } + }, + "optimal_count": { + "type": "integer", + "minimum": 0 + }, + "how": { + "type": "string" + }, + "expected_cut": { + "type": "number" + }, + "ratio": { + "type": "number" + }, + "most_likely": { + "type": "object", + "required": [ + "bits", + "probability", + "cut", + "optimal" + ], + "properties": { + "bits": { + "type": "string" + }, + "probability": { + "type": "number" + }, + "cut": { + "type": "number" + }, + "optimal": { + "type": "boolean" + } + } + }, + "p_optimal": { + "type": "number" + }, + "bits": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", + "required": [ + "call", + "algorithm", + "qasm", + "qubits", + "gates", + "reads", + "expected", + "check" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "build" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "qasm": { + "type": "string" + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "reads": { + "type": "object", + "description": "How to read the program's result." + }, + "expected": { + "type": "object", + "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." + }, + "check": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "exact", + "random", + "none" + ] + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": "number" + }, + "reference": { + "type": "string" + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } + }, + { + "name": "build_algorithm", + "title": "Write the program for a standard algorithm, checked against its reference", + "description": "An OpenQASM 3 program for a standard algorithm, with how to read its result, what it gives, and the equivalence ladder's verdict on it against a reference matrix or truth table built from the definitions (check: exact on every basis state up to 8 qubits, the adder's up to 16; past that unchecked). qpe: the phase φ of p(2πφ) on counting qubits; amplitude_estimation: the amplitude a that A = ry(2·arcsin √a) gives the good state, by phase estimation of the Grover operator; adder: the ripple-carry adder of bits-bit integers in place (with a and b, prepared and measured); qsvt: quantum signal processing from phases, of a signal x or of a real symmetric 2 × 2 matrix through its block encoding (all phases zero give the Chebyshev polynomial). Sealed with the service's key. Run the program with run_quantum_circuit.", + "inputSchema": { + "type": "object", + "required": [ + "algorithm" + ], + "properties": { + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "counting": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "qpe, amplitude_estimation: counting qubits (default 4)." + }, + "phase": { + "type": "number", + "description": "qpe: the phase φ, in turns." + }, + "amplitude": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "amplitude_estimation: the good state's probability a." + }, + "bits": { + "type": "integer", + "minimum": 1, + "maximum": 32, + "description": "adder: the integers' width." + }, + "a": { + "type": "integer", + "minimum": 0, + "description": "adder: the first addend, prepared." + }, + "b": { + "type": "integer", + "minimum": 0, + "description": "adder: the second, which the sum replaces." + }, + "carry_in": { + "type": "boolean", + "description": "adder: a carry in." + }, + "phases": { + "type": "array", + "minItems": 2, + "maxItems": 64, + "items": { + "type": "number" + }, + "description": "qsvt: φ₀ … φ_d, radians." + }, + "x": { + "type": "number", + "minimum": -1, + "maximum": 1, + "description": "qsvt: the signal." + }, + "matrix": { + "type": "array", + "description": "qsvt: [[a, b], [b, c]], real and symmetric, its eigenvalues within [-1, 1]." + } + } + }, + "annotations": { + "readOnlyHint": true, + "idempotentHint": true, + "openWorldHint": false + }, + "outputSchema": { + "$id": "wai-quantum://schemas/build_algorithm/1", + "type": "object", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "anyOf": [ + { + "title": "wai.quantum.algorithms/1", + "description": "An answer of the variational and algorithm library as every host gives it (engine::variational and engine::algorithms: gradient_qasm, optimize_qasm, vqe_ground_state, qaoa_maxcut and build_algorithm on both servers, wai-quantum gradient, optimize, vqe, qaoa and build, POST /v1/gradient, /v1/optimize, /v1/vqe, /v1/qaoa and /v1/build, and the Studio): the request, and the result sealed in a job's form. A result names the engine that made it and this schema (engine and schema) and the call that made it. docs/variational.md explains each.", + "type": "object", + "required": [ + "request", + "result" + ], + "properties": { + "request": { + "type": "object", + "description": "The call's request, as given." + }, + "result": { + "description": "A gradient, an optimisation, a VQE, a QAOA run or a built program, with its receipt.", + "anyOf": [ + { + "type": "object", + "description": "A Hamiltonian's expectation at the request's params and its exact gradient by each parameter (engine::variational::gradient).", + "required": [ + "call", + "value", + "gradient", + "params", + "method", + "how", + "evaluations", + "qubits", + "gates", + "moved_gates", + "parameters", + "terms", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "gradient" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "value": { + "type": "number", + "description": "⟨ψ|H|ψ⟩ at the params." + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "∂E/∂p for each parameter p, by name." + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "The point, by name." + }, + "method": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "how": { + "type": "string" + }, + "evaluations": { + "type": "integer", + "minimum": 0, + "description": "Circuit evaluations (adjoint: the forward run and each gate derivative applied; parameter shift: each shifted run)." + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "moved_gates": { + "type": "integer", + "minimum": 0, + "description": "Gates a parameter moves." + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0, + "description": "The Hamiltonian's Pauli terms." + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "An optimisation of a Hamiltonian's expectation over the program's parameters, every step a link of a digest chain from the request (engine::variational::optimize).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "optimize" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + } + } + }, + { + "type": "object", + "description": "The variational eigensolver: an optimisation, and the exact ground energy by diagonalisation beside the energy found (engine::variational::vqe).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "reference" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "vqe" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "reference": { + "anyOf": [ + { + "type": "object", + "required": [ + "ground_energy", + "how", + "gap" + ], + "properties": { + "ground_energy": { + "type": "number" + }, + "first_excited": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "how": { + "type": "string" + }, + "gap": { + "type": "number", + "description": "The best energy found above the ground energy." + } + } + }, + { + "type": "object", + "required": [ + "unchecked" + ], + "properties": { + "unchecked": { + "type": "string" + } + } + } + ] + }, + "ansatz": { + "type": "object", + "required": [ + "qasm", + "params", + "kind" + ], + "properties": { + "qasm": { + "type": "string" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "kind": { + "const": "hardware_efficient" + } + } + } + } + }, + { + "type": "object", + "description": "Max-Cut by QAOA: the program and Hamiltonian built from the graph, optimised, and the cut set beside the maximum cut by brute force (engine::variational::qaoa).", + "required": [ + "call", + "optimizer", + "qubits", + "gates", + "parameters", + "terms", + "start", + "steps", + "chain", + "best", + "final", + "evaluations", + "precision", + "graph", + "layers", + "program", + "hamiltonian", + "maxcut" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "qaoa" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "optimizer": { + "type": "object", + "required": [ + "name", + "steps", + "step_size" + ], + "properties": { + "name": { + "enum": [ + "gradient_descent", + "adam", + "spsa" + ] + }, + "steps": { + "type": "integer", + "minimum": 0 + }, + "step_size": { + "type": "number" + }, + "gradient": { + "enum": [ + "adjoint", + "parameter_shift" + ] + }, + "beta1": { + "type": "number" + }, + "beta2": { + "type": "number" + }, + "epsilon": { + "type": "number" + }, + "c": { + "type": "number" + }, + "A": { + "type": "number" + }, + "alpha": { + "type": "number" + }, + "gamma": { + "type": "number" + }, + "seed": { + "type": "integer", + "minimum": 0 + } + } + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "parameters": { + "type": "array", + "description": "The program's parameters, in the order it declares them.", + "items": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "float", + "angle", + "float[64]" + ] + } + } + } + }, + "terms": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's first link: BLAKE3 of the domain wai.quantum.trace/1 and the request's canonical text." + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "step", + "params", + "value", + "digest" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Gradient descent and Adam: the gradient at the step's params." + }, + "perturbation": { + "type": "array", + "items": { + "enum": [ + 1.0, + -1.0 + ] + }, + "description": "SPSA: the step's perturbation, from the seeded stream." + }, + "estimate": { + "type": "array", + "items": { + "type": "number" + }, + "description": "SPSA: the gradient's estimate." + }, + "gains": { + "type": "object", + "required": [ + "a", + "c" + ], + "properties": { + "a": { + "type": "number" + }, + "c": { + "type": "number" + } + }, + "description": "SPSA: the step's gains a_k and c_k." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "This step's link of the chain: BLAKE3 of the previous link and the step's canonical text without its digest." + } + } + }, + "minItems": 2 + }, + "chain": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The chain's last link." + }, + "best": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "final": { + "type": "object", + "required": [ + "step", + "params", + "value" + ], + "properties": { + "step": { + "type": "integer", + "minimum": 0 + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "number" + } + }, + "value": { + "type": "number" + } + } + }, + "evaluations": { + "type": "integer", + "minimum": 0 + }, + "precision": { + "type": "object", + "description": "What the arithmetic is: IEEE-754 double precision, approximate, and an a priori bound on each reported number's rounding (first order in 2^-53, doubled), from the value the same circuit has in exact arithmetic.", + "required": [ + "arithmetic", + "exact", + "rounding_bound", + "reading" + ], + "properties": { + "arithmetic": { + "const": "f64" + }, + "exact": { + "const": false + }, + "rounding_bound": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "number", + "minimum": 0 + }, + "gradient": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + }, + "description": "Each component's bound, by parameter." + } + } + }, + "reading": { + "type": "string" + } + } + }, + "note": { + "type": "string" + }, + "graph": { + "type": "object", + "required": [ + "nodes", + "edges" + ], + "properties": { + "nodes": { + "type": "integer", + "minimum": 0 + }, + "edges": { + "type": "array", + "items": { + "type": "array", + "minItems": 3, + "maxItems": 3 + } + } + } + }, + "layers": { + "type": "integer", + "minimum": 0 + }, + "program": { + "type": "string" + }, + "hamiltonian": { + "type": "array" + }, + "maxcut": { + "type": "object", + "required": [ + "max_cut", + "optimal", + "optimal_count", + "how", + "expected_cut", + "ratio", + "most_likely", + "p_optimal", + "bits" + ], + "properties": { + "max_cut": { + "type": "number" + }, + "optimal": { + "type": "array", + "items": { + "type": "string" + } + }, + "optimal_count": { + "type": "integer", + "minimum": 0 + }, + "how": { + "type": "string" + }, + "expected_cut": { + "type": "number" + }, + "ratio": { + "type": "number" + }, + "most_likely": { + "type": "object", + "required": [ + "bits", + "probability", + "cut", + "optimal" + ], + "properties": { + "bits": { + "type": "string" + }, + "probability": { + "type": "number" + }, + "cut": { + "type": "number" + }, + "optimal": { + "type": "boolean" + } + } + }, + "p_optimal": { + "type": "number" + }, + "bits": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "description": "A program an algorithm builder writes (engine::algorithms): its text, how to read it, what it gives, and the equivalence ladder's verdict against a reference built from the definitions.", + "required": [ + "call", + "algorithm", + "qasm", + "qubits", + "gates", + "reads", + "expected", + "check" + ], + "properties": { + "engine": { + "type": "object", + "description": "The engine that made the result: the wai-quantum crate's name and version.", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "const": "wai-quantum" + }, + "version": { + "type": "string" + } + } + }, + "schema": { + "const": "wai.quantum.algorithms/1" + }, + "call": { + "const": "build" + }, + "receipt": { + "title": "wai.quantum.receipt/2", + "description": "A result's receipt: an Ed25519 signature, by the key it names, over digest = BLAKE3(\"wai:quantum-service-receipt\\x02\" ‖ len ‖ request ‖ len ‖ result), each of request and result in its RFC 8785 canonical text (the result without its receipt member), each length 8 bytes big-endian. Whatever members the request and the result hold are sealed, the result's engine and schema among them. The first receipts (no canon member, $defs/first) signed serde_json's own text under the domain ending \\x01; they still verify.", + "type": "object", + "required": [ + "alg", + "canon", + "key", + "digest", + "signature" + ], + "properties": { + "alg": { + "const": "ed25519" + }, + "canon": { + "const": "rfc8785", + "description": "The canonical form the digest is taken over." + }, + "key": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The signing key, 32 bytes in hex." + }, + "digest": { + "type": "string", + "minLength": 64, + "maxLength": 64, + "description": "The digest signed, 32 bytes in hex." + }, + "signature": { + "type": "string", + "minLength": 128, + "maxLength": 128, + "description": "The signature, 64 bytes in hex." + } + } + }, + "algorithm": { + "enum": [ + "qpe", + "amplitude_estimation", + "adder", + "qsvt" + ] + }, + "qasm": { + "type": "string" + }, + "qubits": { + "type": "integer", + "minimum": 0 + }, + "gates": { + "type": "integer", + "minimum": 0 + }, + "reads": { + "type": "object", + "description": "How to read the program's result." + }, + "expected": { + "type": "object", + "description": "What it gives: a distribution's likeliest outcomes, a sum, or a polynomial's value." + }, + "check": { + "type": "object", + "required": [ + "verdict", + "how", + "why" + ], + "properties": { + "verdict": { + "enum": [ + "equivalent", + "different", + "unchecked" + ] + }, + "how": { + "enum": [ + "exact", + "random", + "none" + ] + }, + "why": { + "type": "string" + }, + "global_phase": { + "type": "number" + }, + "reference": { + "type": "string" + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "description": "A refusal as data: the message, every code in it (the last is the code), its outcome and meaning as the code's table gives them. A host that refuses for its own reasons gives the error alone.", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "code": { + "type": [ + "string", + "null" + ] + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + }, + "outcome": { + "enum": [ + "refused", + "retry", + "failed", + "lowered", + "carried", + "preserved", + "warned", + "dropped", + "defaulted" + ] + }, + "meaning": { + "type": "string" + } + } + } + ] + } } ] } diff --git a/wai/wai-quantum/views/manifest.json b/wai/wai-quantum/views/manifest.json index f6d9a5efd..995fbf707 100644 --- a/wai/wai-quantum/views/manifest.json +++ b/wai/wai-quantum/views/manifest.json @@ -4,19 +4,19 @@ "placeholder": "__WAI_QUANTUM_VIEW__", "limit_bytes": 1048576, "bytes": { - "page": 802560, - "script": 93848, - "styles": 49020, - "engine_wasm": 193530, - "engine_wasm_base64": 258040, + "page": 804985, + "script": 94493, + "styles": 50804, + "engine_wasm": 193526, + "engine_wasm_base64": 258036, "engine_js": 401202 }, "sha256": { - "page": "7fcd5c7db808a247e6ea03ce9d88ecbcab06ee70c502ad2f6a342e4a28339145", - "script": "4d7997c0c814dac55b0eb56575ccde40978c503b83a1bab106340c43fa749e09", - "styles": "118b40374f3adb9c67b6ee4d54a98c7dbeab9e49c259537393d61b2c26129a4b", - "engine_wasm": "7e8e04e51a5bf479ddaea762108e0916ee8f6a79d622ca57d38fd55fe00850ed", - "engine_js": "068e6d7cd99c7f8a83b5bd5ed07a351f4c8eaf319af1ddffa0b2a3b3ee0695a1" + "page": "8bf0b0cfd064a5fb53fedbe34d15bd2954e756fdf985452dbb08c9e5722311ff", + "script": "152484a251cd06eea4e65c45f6e6b8810be8d0932ec4dcdf3ae3cb4131e1f036", + "styles": "11ebcd4416c68e9eaf1156ca6f7c92b9a96744895ed13c377eba98fdd8dca9a6", + "engine_wasm": "ba6e11c8c0a256723b826be4167a973cf8bc82193e73d5205455e5d3454fa3f1", + "engine_js": "a7e3cf66d42fce8af4afc4395ebdacc76831a1ab54f826054ce9fa5f8df16f34" }, "sources": { "wai/quantum-studio/build-views.mjs": "da5b161829a990b3d1bb4c1b3ec7c8f254ff7b5078476156e504ae322bc4f010", @@ -32,7 +32,7 @@ "wai/quantum-studio/locales/en/estimate_view.json": "b20c94f96751eee548b011ea19f6ded9ecd8648cae32885b6b71b7d5e631b2b1", "wai/quantum-studio/locales/en/examples.json": "dd2f2f4aef033b00b3700c6eb7151c18dd1b43537ef0beeb17a8ffc069a564b2", "wai/quantum-studio/locales/en/flags.json": "d2beeef25cee8ec742d692e424ec54bdc821449733ae98b2882cc97711efffdd", - "wai/quantum-studio/locales/en/frame.json": "e92b8b8e81304c83c243688ea7ae7f8cd4f582f3e7eebc909aef79299b123c53", + "wai/quantum-studio/locales/en/frame.json": "8ed953be6f391aad92f56da73e5a4f4188de9f1d46dc125a7c2a228c48e59e82", "wai/quantum-studio/locales/en/gallery.json": "5d0c2992e39ea0f82541e0491b46f4fd724085d95a988f8c15a1e3657d2eb149", "wai/quantum-studio/locales/en/generators.json": "85eb826cc6353cf12bc3fa45bbb8721210a311f145b9b46493c3e2bb44e7a3c2", "wai/quantum-studio/locales/en/hardware.json": "745786e872062468680655326362f49ae85dabae6ae9021145072dd4dbd7fbf1", @@ -44,6 +44,7 @@ "wai/quantum-studio/locales/en/state_views.json": "a467fe4e7c8baffa9c08dee8c66e3b12a07e4b3a6598df0a43e84340808bd037", "wai/quantum-studio/locales/en/study.json": "851328d1f199db6d2bfe2984d430b89ec5a67b890b8615e2ce14341d04b364ae", "wai/quantum-studio/locales/en/taste.json": "f26d76d981eb32755c9b7b443b94368bf715c55b3234efd44850d20b0d979386", + "wai/quantum-studio/locales/en/update.json": "fb5bd53755a51a7eebb75a839c375af660433977965266fe022b5c79a0f503ac", "wai/quantum-studio/locales/en/verdict_view.json": "24f0afd12cd8dab87d9060f3b7ca7a124f09ed450555bc9bf97db8fbfe9d3f38", "wai/quantum-studio/locales/en/versions.json": "25e491e4a7b4989db08a89b771237fb50130183ee8debd30bbd10b523dedf49c", "wai/quantum-studio/locales/en/visual_edit.json": "a192c00167a149c34070bc244e2a1b56f322bb9debb00a5db21ebaaed83900cc", @@ -55,7 +56,7 @@ "wai/quantum-studio/src/estimate-view.js": "40cb4bd738afb628dd686cdad44813d9d09910fbc60905098852dcca6cfe1b27", "wai/quantum-studio/src/i18n.js": "f661474772b05ef6614f2f6096e85d94cd479c4fcd9448f34e8d312a2fd43498", "wai/quantum-studio/src/result-parts.js": "f919bd1a76498443ff7bf996023405a61e662ba52020addf1733caab459dfb9c", - "wai/quantum-studio/src/studio.css": "5156ab565d7127f3d6cc9ea43c0cb1f020551340a1e779b6f77feae2079248f9", + "wai/quantum-studio/src/studio.css": "8891f2a1b71e1ada344ee1dc41939ba9cd41232f25ab2703d05394c141855997", "wai/quantum-studio/src/tokens.css": "492fbaf8a6cc5b1f7e89346336af3e0a1930a0b48a23731d80d86c128a9032c3", "wai/quantum-studio/src/verdict-view.js": "aec18c93c6f502657ffe2981ca4d9ae0956e1277638d1a9bb1b0846ac8e80160", "wai/quantum-studio/src/views/check.js": "2edae7b446e72a49293478ebcbfe21792b74762dcfb097fb9e75ec3a4feb8d9a", diff --git a/wai/wai-quantum/views/wai-quantum-views.html b/wai/wai-quantum/views/wai-quantum-views.html index ea30cda16..9a412b916 100644 --- a/wai/wai-quantum/views/wai-quantum-views.html +++ b/wai/wai-quantum/views/wai-quantum-views.html @@ -6,15 +6,15 @@ WAI Quantum -
- - -- 2.54.0 (Apple Git-157) From bda065b52f0bd571337dd6e036e5341bfdee20dd Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Sat, 31 Oct 2026 13:38:54 -0400 Subject: [PATCH 7/7] wai-quantum-py: the getting-started notebook's method list names stabilizer_rank The notebook prints every method with its accuracy, and the Python workflow holds each cell to its stored output. The stabilizer-rank method is new in this branch, so its line goes into the stored output, in the engine's order. Nothing else in any notebook's outputs changed. Co-Authored-By: Claude Opus 5.5 --- wai/wai-quantum-py/notebooks/getting-started.ipynb | 1 + 1 file changed, 1 insertion(+) diff --git a/wai/wai-quantum-py/notebooks/getting-started.ipynb b/wai/wai-quantum-py/notebooks/getting-started.ipynb index ff96a1baa..7e301a134 100644 --- a/wai/wai-quantum-py/notebooks/getting-started.ipynb +++ b/wai/wai-quantum-py/notebooks/getting-started.ipynb @@ -372,6 +372,7 @@ "stabilizer exact; with Pauli noise, counts are noisy samples and expectations estimates\n", "pauli bounded\n", "mps exact when nothing is truncated, otherwise heuristic\n", + "stabilizer_rank exact; with terms or epsilon, an estimate with its bound\n", "tensor_network exact\n", "cutrank exact; single when only a single-precision table fits\n", "cutrank_single single\n", -- 2.54.0 (Apple Git-157)