wai: wasmQ, an OpenQASM 3 program and the WebAssembly its externs call, run the same everywhere, metered and receipted #659
270 changed files with 26928 additions and 349 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# step: quantum job receipts · receipt_verify.py
|
||||
# order: 701
|
||||
# paths: wai/extensions/quantum-providers.md
|
||||
# paths: wai/extensions/quantum-providers.md wai/extensions/quantum-wasmq.md
|
||||
# working-directory: .
|
||||
# independent: quantum-receipts media python3 -I quantum-conformance/tools/receipt_differential.py --second-only --corpus quantum-conformance/receipts
|
||||
#
|
||||
|
|
@ -16,6 +16,6 @@
|
|||
python3 -I wai/quantum-conformance/receipts/generate.py --check
|
||||
python3 -I wai/quantum-conformance/receipts/generate.py --self-test
|
||||
python3 -I wai/quantum-conformance/tools/receipt_verify.py --self-test wai/wai-quantum/src/engine/testdata/es-number-tostring.txt
|
||||
for plant in lenient-key no-alg last-duplicate no-inexact measured-simulator whole-cap lax-small-order-r no-canonical-spelling set-seal-only names-layout-only; do
|
||||
for plant in lenient-key no-alg last-duplicate no-inexact measured-simulator whole-cap lax-small-order-r no-canonical-spelling set-seal-only names-layout-only wasmq-unchecked; do
|
||||
python3 -I wai/quantum-conformance/tools/receipt_differential.py --second-only --plant "$plant" | tail -1
|
||||
done
|
||||
|
|
|
|||
53
.github/workflows/wai-quantum-cli.yml
vendored
53
.github/workflows/wai-quantum-cli.yml
vendored
|
|
@ -29,33 +29,44 @@ on:
|
|||
- 'wai/wai-quantum/**'
|
||||
- 'wai/wai-quantum-cli/**'
|
||||
- 'wai/wai-quantum-qpu/**'
|
||||
- 'wai/wai-wasmq/**'
|
||||
- 'wai/quantum-conformance/eval/**'
|
||||
- 'wai/quantum-conformance/wasmq/**'
|
||||
- 'wai/wai-quantum-writer/**'
|
||||
# The writer's model runs on this crate, which it path-depends on.
|
||||
- 'jouleclaw/jouleclaw-rs/crates/jouleclaw-loader-gguf/**'
|
||||
- 'wai/quantum-conformance/eval/**'
|
||||
- 'wai/quantum-cross-simulator/**'
|
||||
- 'wai/quantum-conformance/receipts/**'
|
||||
- 'wai/quantum-conformance/tools/receipt_verify.py'
|
||||
- 'wai/quantum-conformance/tools/receipt_differential.py'
|
||||
- 'wai/quantum-conformance/tools/wasmq_mutants.py'
|
||||
- 'wai/quantum-conformance/tools/referee.py'
|
||||
- 'wai/extensions/quantum-providers.md'
|
||||
- 'wai/extensions/quantum-wasmq.md'
|
||||
- 'rust-toolchain.toml'
|
||||
- '.github/workflows/wai-quantum-cli.yml'
|
||||
# Nightly, beside the pushes: each rule's weakenings (below), which take a second build.
|
||||
schedule:
|
||||
- cron: '41 3 * * *'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'wai/wai-quantum/**'
|
||||
- 'wai/wai-quantum-cli/**'
|
||||
- 'wai/wai-quantum-qpu/**'
|
||||
- 'wai/wai-wasmq/**'
|
||||
- 'wai/quantum-conformance/eval/**'
|
||||
- 'wai/quantum-conformance/wasmq/**'
|
||||
- 'wai/wai-quantum-writer/**'
|
||||
# The writer's model runs on this crate, which it path-depends on.
|
||||
- 'jouleclaw/jouleclaw-rs/crates/jouleclaw-loader-gguf/**'
|
||||
- 'wai/quantum-conformance/eval/**'
|
||||
- 'wai/quantum-cross-simulator/**'
|
||||
- 'wai/quantum-conformance/receipts/**'
|
||||
- 'wai/quantum-conformance/tools/receipt_verify.py'
|
||||
- 'wai/quantum-conformance/tools/receipt_differential.py'
|
||||
- 'wai/quantum-conformance/tools/wasmq_mutants.py'
|
||||
- 'wai/quantum-conformance/tools/referee.py'
|
||||
- 'wai/extensions/quantum-providers.md'
|
||||
- 'wai/extensions/quantum-wasmq.md'
|
||||
- 'rust-toolchain.toml'
|
||||
- '.github/workflows/wai-quantum-cli.yml'
|
||||
|
||||
|
|
@ -194,9 +205,27 @@ jobs:
|
|||
python3 -I wai/quantum-conformance/receipts/generate.py --self-test
|
||||
python3 -I wai/quantum-conformance/tools/receipt_verify.py --self-test wai/wai-quantum/src/engine/testdata/es-number-tostring.txt
|
||||
python3 -I wai/quantum-conformance/tools/receipt_differential.py --reference wai/wai-quantum-cli/target/release/wai-quantum
|
||||
for plant in lenient-key no-alg last-duplicate no-inexact measured-simulator whole-cap lax-small-order-r no-canonical-spelling set-seal-only names-layout-only; do
|
||||
for plant in lenient-key no-alg last-duplicate no-inexact measured-simulator whole-cap lax-small-order-r no-canonical-spelling set-seal-only names-layout-only wasmq-unchecked; do
|
||||
python3 -I wai/quantum-conformance/tools/receipt_differential.py --reference wai/wai-quantum-cli/target/release/wai-quantum --plant "$plant" | tail -1
|
||||
done
|
||||
# Each rule of a wasmQ job's form weakened in each verifier, from its code (the check
|
||||
# dropped, a comparison moved by one, a count or a digest read loosely, a null member read
|
||||
# as absent and an absent one as null), and every weakening caught by the differential:
|
||||
# the second verifier's as files, the engine's as one build that holds every weakening,
|
||||
# each switched on alone (wasmq_mutants.py). Counted per rule. Nightly.
|
||||
- name: Each rule's weakenings caught, in both verifiers
|
||||
if: github.event_name == 'schedule'
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
python3 -I wai/quantum-conformance/tools/wasmq_mutants.py python --reference wai/wai-quantum-cli/target/release/wai-quantum --jobs 4
|
||||
m="$RUNNER_TEMP/wasmq-mutants"
|
||||
rm -rf "$m" && mkdir -p "$m"
|
||||
git worktree add --detach "$m/wt" HEAD
|
||||
python3 -I wai/quantum-conformance/tools/wasmq_mutants.py rust-schemata "$m/wt/wai/wai-quantum/src/engine/wasmq.rs" "$m/mutants.json"
|
||||
(cd "$m/wt/wai/wai-quantum-cli" && CARGO_TARGET_DIR="$m/target" cargo build --locked --release)
|
||||
python3 -I wai/quantum-conformance/tools/wasmq_mutants.py rust --reference "$m/target/release/wai-quantum" --mutants "$m/mutants.json" --jobs 4
|
||||
git worktree remove --force "$m/wt"
|
||||
# The release binary, pinned by version and SHA-256, rather than a build from source.
|
||||
# Every WAI workflow that runs wasmtime pins this one version, and every run passes
|
||||
# -W nan-canonicalization=y -W relaxed-simd-deterministic=y: every NaN a float
|
||||
|
|
@ -264,6 +293,24 @@ jobs:
|
|||
wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y "$w" estimate --demo-key --json --qubit us-e3 < "$RUNNER_TEMP/est.qasm" > "$RUNNER_TEMP/wasi-estimate.json" 2> /dev/null
|
||||
cmp "$RUNNER_TEMP/native-estimate.json" "$RUNNER_TEMP/wasi-estimate.json" || { echo "::error::an estimate differs under wasmtime"; exit 1; }
|
||||
echo "the WASI component's output equals the native build's"
|
||||
# verify gives its verdict at its own bound under wasm32 as natively: a job of 384 MiB,
|
||||
# one of 2^22 values, and one more of each (too_large).
|
||||
- name: The WASI component judges a job at verify's bound
|
||||
shell: bash
|
||||
working-directory: wai/wai-quantum-cli
|
||||
run: |
|
||||
set -euo pipefail
|
||||
w=target/wasm32-wasip2/release/wai-quantum.wasm
|
||||
n=target/release/wai-quantum
|
||||
d=$(mktemp -d "$RUNNER_TEMP/bound.XXXX")
|
||||
python3 -I tests/verify_at_bound.py "$d"
|
||||
for f in long longer many more; do
|
||||
$n verify --json "$d/$f.json" > "$d/native-$f.txt" || true
|
||||
wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y --dir "$d" "$w" verify --json "$d/$f.json" > "$d/wasi-$f.txt" || true
|
||||
test -s "$d/native-$f.txt" || { echo "::error::no verdict at verify's bound ($f)"; exit 1; }
|
||||
cmp "$d/native-$f.txt" "$d/wasi-$f.txt" || { echo "::error::verify at its bound differs under wasmtime ($f)"; exit 1; }
|
||||
done
|
||||
rm -rf "$d"
|
||||
|
||||
cli-macos:
|
||||
name: command line · macos
|
||||
|
|
|
|||
197
.github/workflows/wai-quantum-wasmq.yml
vendored
Normal file
197
.github/workflows/wai-quantum-wasmq.yml
vendored
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
name: wai-quantum wasmQ
|
||||
|
||||
# wasmQ (wai/extensions/quantum-wasmq.md): an OpenQASM 3 program and the WebAssembly its
|
||||
# `extern`s call, run with the same result bytes and fuel on every host and sealed in a
|
||||
# receipt (wai/wai-wasmq). Each leg runs the crate's tests on its host and checks the
|
||||
# conformance vectors, which pin each run's whole job digest, so every leg passing is the
|
||||
# claim that the bytes are the same on linux x86_64, macOS arm64 and wasm32. The linux leg
|
||||
# also rebuilds the reference modules and requires the modules of record byte for byte.
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'wai/wai-wasmq/**'
|
||||
- 'wai/quantum-conformance/wasmq/**'
|
||||
- 'wai/extensions/quantum-wasmq.*'
|
||||
- 'wai/wai-quantum/**'
|
||||
- 'rust-toolchain.toml'
|
||||
- '.github/workflows/wai-quantum-wasmq.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'wai/wai-wasmq/**'
|
||||
- 'wai/quantum-conformance/wasmq/**'
|
||||
- 'wai/extensions/quantum-wasmq.*'
|
||||
- 'wai/wai-quantum/**'
|
||||
- 'rust-toolchain.toml'
|
||||
- '.github/workflows/wai-quantum-wasmq.yml'
|
||||
|
||||
jobs:
|
||||
relevant:
|
||||
name: does this change touch it
|
||||
runs-on: linux
|
||||
outputs:
|
||||
run: ${{ steps.gate.outputs.run }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- id: gate
|
||||
run: |
|
||||
set -euo pipefail
|
||||
r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-quantum-wasmq.yml \
|
||||
"${{ github.event.pull_request.base.sha }}" \
|
||||
"${{ github.event.pull_request.head.sha }}")
|
||||
echo "this change touches wasmQ: $r"
|
||||
echo "run=$r" >> "$GITHUB_OUTPUT"
|
||||
|
||||
native:
|
||||
name: profile, engines, reference modules, adversarial, vectors · ${{ matrix.os }}
|
||||
needs: relevant
|
||||
if: needs.relevant.outputs.run == 'true'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [linux, macos]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install Rust 1.99.1
|
||||
shell: bash
|
||||
run: |
|
||||
export PATH="$HOME/.cargo/bin:$PATH"
|
||||
command -v rustup >/dev/null 2>&1 || \
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.99.1
|
||||
rustup toolchain install 1.99.1 --profile minimal --component clippy
|
||||
rustup default 1.99.1
|
||||
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
- name: The crate's tests, every engine of this host
|
||||
shell: bash
|
||||
working-directory: wai/wai-wasmq
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cargo test --locked --release --no-fail-fast 2>&1 | tee "$RUNNER_TEMP/wasmq.log"
|
||||
if grep -q 'FAILED' "$RUNNER_TEMP/wasmq.log"; then echo "::error::a test failed"; exit 1; fi
|
||||
# Every test file of the crate ran, and none ran empty: a file nobody runs, or
|
||||
# one whose tests are all compiled out, would otherwise pass unseen.
|
||||
for f in tests/*.rs; do
|
||||
t=$(basename "$f" .rs)
|
||||
awk -v t="tests/$t.rs" '$1 == "Running" && $2 == t { seen = 1; next } seen && /^test result: ok\. [1-9][0-9]* passed; 0 failed/ { ok = 1; exit } seen && /^test result:/ { exit } END { exit ok ? 0 : 1 }' "$RUNNER_TEMP/wasmq.log" \
|
||||
|| { echo "::error::tests/$t.rs did not run and pass with at least one test"; exit 1; }
|
||||
done
|
||||
grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/wasmq.log" || { echo "::error::no test ran"; exit 1; }
|
||||
- name: The vectors, each engine, and their digest
|
||||
shell: bash
|
||||
working-directory: wai/wai-wasmq
|
||||
run: |
|
||||
set -euo pipefail
|
||||
for e in native interpreter interpreter-prepared; do
|
||||
cargo run --locked --release -q --bin wasmq_vectors -- verify ../quantum-conformance/wasmq "$e" | tail -1
|
||||
done
|
||||
- name: Clippy, warnings denied
|
||||
shell: bash
|
||||
working-directory: wai/wai-wasmq
|
||||
run: cargo clippy --locked --release --all-targets -- -D warnings
|
||||
# wai-quantum holds a wasmQ job's form beside its receipts (engine::wasmq), and its
|
||||
# engine builds without them; each feature set builds, without warnings.
|
||||
- name: wai-quantum's engine with the receipts and without them
|
||||
if: matrix.os == 'linux'
|
||||
shell: bash
|
||||
working-directory: wai/wai-quantum
|
||||
env:
|
||||
RUSTFLAGS: -D warnings
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cargo check --locked --no-default-features --features quantum_engine --lib
|
||||
cargo check --locked --no-default-features --features quantum_engine,quantum_receipt --lib
|
||||
|
||||
modules:
|
||||
name: the reference modules rebuild to their modules of record · linux
|
||||
needs: relevant
|
||||
if: needs.relevant.outputs.run == 'true'
|
||||
runs-on: linux
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install Rust 1.99.1 with the wasm32-unknown-unknown target
|
||||
shell: bash
|
||||
run: |
|
||||
export PATH="$HOME/.cargo/bin:$PATH"
|
||||
command -v rustup >/dev/null 2>&1 || \
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.99.1
|
||||
rustup toolchain install 1.99.1 --profile minimal
|
||||
rustup default 1.99.1
|
||||
rustup target add --toolchain 1.99.1 wasm32-unknown-unknown
|
||||
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
- name: Build and compare
|
||||
shell: bash
|
||||
run: bash wai/wai-wasmq/modules/build.sh --check
|
||||
- name: The sources the modules of record were built from
|
||||
shell: bash
|
||||
run: bash wai/wai-wasmq/modules/build.sh --sources
|
||||
|
||||
wasip2:
|
||||
name: interpreter and vectors under wasm32-wasip2 (wasmtime)
|
||||
needs: relevant
|
||||
if: needs.relevant.outputs.run == 'true'
|
||||
runs-on: linux
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install Rust 1.99.1 with the wasm32-wasip2 target
|
||||
shell: bash
|
||||
run: |
|
||||
export PATH="$HOME/.cargo/bin:$PATH"
|
||||
command -v rustup >/dev/null 2>&1 || \
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.99.1
|
||||
rustup toolchain install 1.99.1 --profile minimal
|
||||
rustup default 1.99.1
|
||||
rustup target add --toolchain 1.99.1 wasm32-wasip2
|
||||
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
# The release binary, pinned by version and SHA-256, with both determinism settings on
|
||||
# every run (scripts/check-wasmtime-pin.py). Here wasmtime is the host the interpreter
|
||||
# runs in; the modules the interpreter runs are interpreted, not compiled by it.
|
||||
- name: Install wasmtime 50.0.1
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
[ "$(uname -m)" = x86_64 ] || { echo "::error::the pinned wasmtime archive is x86_64; this host is $(uname -m)"; exit 1; }
|
||||
if ! command -v xz >/dev/null 2>&1; then
|
||||
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo"
|
||||
$SUDO apt-get update -qq
|
||||
$SUDO apt-get install -y -qq xz-utils
|
||||
fi
|
||||
v=50.0.1
|
||||
f="wasmtime-v$v-x86_64-linux.tar.xz"
|
||||
curl --proto '=https' --tlsv1.2 -sSfL -o "$RUNNER_TEMP/$f" \
|
||||
"https://github.com/bytecodealliance/wasmtime/releases/download/v$v/$f"
|
||||
echo "685466455dd42a14774a86c36c8f2e45cbb9bd6d92a850139315df60a75498a5 $RUNNER_TEMP/$f" | sha256sum -c -
|
||||
tar -xJf "$RUNNER_TEMP/$f" -C "$RUNNER_TEMP"
|
||||
echo "$RUNNER_TEMP/wasmtime-v$v-x86_64-linux" >> "$GITHUB_PATH"
|
||||
- name: The tests under wasm32, the interpreter the only engine
|
||||
shell: bash
|
||||
working-directory: wai/wai-wasmq
|
||||
run: |
|
||||
set -euo pipefail
|
||||
W=$(cd .. && pwd)
|
||||
CARGO_TARGET_WASM32_WASIP2_RUNNER="wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y --dir $W::$W" \
|
||||
cargo test --locked --release --target wasm32-wasip2 --no-default-features --no-fail-fast \
|
||||
--lib --tests 2>&1 | tee "$RUNNER_TEMP/wasip2.log"
|
||||
if grep -q 'FAILED' "$RUNNER_TEMP/wasip2.log"; then echo "::error::a test failed under wasip2"; exit 1; fi
|
||||
for f in tests/*.rs; do
|
||||
t=$(basename "$f" .rs)
|
||||
awk -v t="tests/$t.rs" '$1 == "Running" && $2 == t { seen = 1; next } seen && /^test result: ok\. [1-9][0-9]* passed; 0 failed/ { ok = 1; exit } seen && /^test result:/ { exit } END { exit ok ? 0 : 1 }' "$RUNNER_TEMP/wasip2.log" \
|
||||
|| { echo "::error::tests/$t.rs did not run and pass under wasip2 with at least one test"; exit 1; }
|
||||
done
|
||||
- name: The vectors under wasm32
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cargo build --locked --release --target wasm32-wasip2 --manifest-path wai/wai-wasmq/Cargo.toml --no-default-features --bin wasmq_vectors
|
||||
wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y --dir wai/quantum-conformance/wasmq::/v \
|
||||
wai/wai-wasmq/target/wasm32-wasip2/release/wasmq_vectors.wasm verify /v interpreter,interpreter-prepared | tail -1
|
||||
|
|
@ -34,6 +34,7 @@ PHRASES=(
|
|||
'[Nn]obody signs'
|
||||
'[Nn]ot one signs'
|
||||
'[Nn]one signs'
|
||||
'\b[Nn]either\b[^.]* signs?\b'
|
||||
'[Bb]est[- ]in[- ]class'
|
||||
'\b[Bb]eats\b [A-Z]'
|
||||
'\b[Ss]uperior(ity)?\b'
|
||||
|
|
|
|||
|
|
@ -62,6 +62,13 @@ expect() { # expect <pass|fail> <what> [text the output must hold]
|
|||
}
|
||||
|
||||
mk; expect pass "the pinned release, run every way with both settings, passes"
|
||||
mk; mkdir -p "$tmp/wai/c"; printf '[features]\nwasmtime = ["dep:wasmtime"]\n[target.x.dependencies]\nwasmtime = { version = "=50.0.1", default-features = false }\n' > "$tmp/wai/c/Cargo.toml"
|
||||
expect pass "a crate that pins the release exactly passes"
|
||||
mk; printf '[dependencies]\nwasmtime = { version = "50", default-features = false }\n' > "$tmp/wai/c/Cargo.toml"
|
||||
expect fail "a crate on a caret range of the release fails" 'a crate pins the release the workflows run'
|
||||
mk; printf '[dependencies]\nwasmtime = "=49.0.2"\n' > "$tmp/wai/c/Cargo.toml"
|
||||
expect fail "a crate on another release fails" 'depends on wasmtime =49.0.2'
|
||||
rm -rf "$tmp/wai"
|
||||
|
||||
mk; rep "v=50.0.1" "v=49.0.2"
|
||||
expect fail "another version" "downloads wasmtime 49.0.2"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,10 @@ requires that
|
|||
a module path, and every `CARGO_TARGET_<triple>_RUNNER` that is wasmtime, passes
|
||||
`-W nan-canonicalization=y` and `-W relaxed-simd-deterministic=y`;
|
||||
4. at least one download and one run were found, so a check that looked in the wrong
|
||||
place fails rather than passing on nothing.
|
||||
place fails rather than passing on nothing;
|
||||
5. every crate under wai/ that depends on wasmtime as a library pins it to that release
|
||||
exactly (`version = "=PIN"`), so the engine a crate embeds is the one the workflows
|
||||
run (wai-wasmq's native engine, extensions/quantum-wasmq.md §4.6).
|
||||
|
||||
check-wasmtime-pin.py [--root DIR]
|
||||
|
||||
|
|
@ -51,6 +54,9 @@ INVOKE = re.compile(
|
|||
r"(?:^|[\s;&|(`/\"'=])wasmtime\s+(?:(?:run|serve|compile)\b|[^\s-]\S*\.(?:c?wasm|wat)\b)"
|
||||
)
|
||||
RUNNER = re.compile(r"CARGO_TARGET_\w+_RUNNER\s*[:=]\s*[\"']?wasmtime\b")
|
||||
# A Cargo dependency on the wasmtime library, and the version it asks for.
|
||||
CRATE_DEP = re.compile(r"^\s*wasmtime\s*=")
|
||||
CRATE_VERSION = re.compile(r"version\s*=\s*\"([^\"]+)\"|^\s*wasmtime\s*=\s*\"([^\"]+)\"")
|
||||
|
||||
|
||||
def logical_lines(text):
|
||||
|
|
@ -130,13 +136,34 @@ def main(argv):
|
|||
d, r = check_file(os.path.join(wf, name), f".github/workflows/{name}", findings)
|
||||
downloads += d
|
||||
runs += r
|
||||
crates = 0
|
||||
wai = os.path.join(root, "wai")
|
||||
for dirpath, dirnames, filenames in os.walk(wai):
|
||||
dirnames[:] = [d for d in dirnames if d not in ("target", "node_modules", ".git")]
|
||||
if "Cargo.toml" not in filenames:
|
||||
continue
|
||||
path = os.path.join(dirpath, "Cargo.toml")
|
||||
rel = os.path.relpath(path, root)
|
||||
section = ""
|
||||
for n, line in enumerate(open(path, encoding="utf-8").read().splitlines(), 1):
|
||||
if line.strip().startswith("["):
|
||||
section = line.strip()
|
||||
continue
|
||||
# Only a dependency table names a crate; `wasmtime = [...]` in [features] does not.
|
||||
if "dependencies" not in section or not CRATE_DEP.match(line):
|
||||
continue
|
||||
crates += 1
|
||||
v = CRATE_VERSION.search(line)
|
||||
ver = (v.group(1) or v.group(2)) if v else None
|
||||
if ver != "=" + PIN:
|
||||
findings.append(f"{rel}:{n}: depends on wasmtime {ver or '(no version)'}; a crate pins the release the workflows run, \"={PIN}\"")
|
||||
if downloads == 0 or runs == 0:
|
||||
findings.append(f"found {downloads} wasmtime download(s) and {runs} run(s) under {wf}: this check looked in the wrong place")
|
||||
for f in findings:
|
||||
print(f"::error::{f}")
|
||||
if findings:
|
||||
return 1
|
||||
print(f"check-wasmtime-pin: {downloads} downloads of wasmtime {PIN}, each checked against its digest; {runs} runs, each with both settings")
|
||||
print(f"check-wasmtime-pin: {downloads} downloads of wasmtime {PIN}, each checked against its digest; {runs} runs, each with both settings; {crates} crate dependencies, each on ={PIN}")
|
||||
return 0
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,8 @@ printf 'Carriage is not a differentiator any more.\n' > "$tmp/differentiator.md"
|
|||
printf 'It is not a rate-competitive codec.\n' > "$tmp/rate-competitive.md"
|
||||
printf 'This is the moat <!-- allow-phrase: -->\n' > "$tmp/prose-empty.md"
|
||||
printf 'WAI_MOAT_DIR <!-- allow-phrase: an environment variable name, not prose -->\n' > "$tmp/prose-reasoned.md"
|
||||
printf 'Neither, in what they publish, meters the callout or signs what ran.\n' > "$tmp/neither-signs.md"
|
||||
printf 'Neither engine appears in a receipt.\n' > "$tmp/neither-clean.md"
|
||||
printf 'The decoder is integer all the way down.\n' > "$tmp/prose-clean.md"
|
||||
|
||||
expect 1 "prose: superiority" bash "$prose" "$tmp/superiority.md"
|
||||
|
|
@ -119,6 +121,8 @@ expect 1 "prose: unclaimed" bash "$prose" "$tmp/unclaimed.md"
|
|||
expect 1 "prose: fast win" bash "$prose" "$tmp/fast-win.md"
|
||||
expect 1 "prose: differentiator" bash "$prose" "$tmp/differentiator.md"
|
||||
expect 1 "prose: rate-competitive" bash "$prose" "$tmp/rate-competitive.md"
|
||||
expect 1 "prose: neither ... signs" bash "$prose" "$tmp/neither-signs.md"
|
||||
expect 0 "prose: neither, of our own two things" bash "$prose" "$tmp/neither-clean.md"
|
||||
expect 1 "prose: an opt-out with an empty reason is not honoured" bash "$prose" "$tmp/prose-empty.md"
|
||||
expect 0 "prose: an opt-out with a reason is honoured" bash "$prose" "$tmp/prose-reasoned.md"
|
||||
expect 0 "prose: a clean file is clean" bash "$prose" "$tmp/prose-clean.md"
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ and a role are fixed once registered.
|
|||
| `wai.quantum.circuit` | payload | registered | binary | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
|
||||
| `wai.quantum.circuit2` | payload | registered | binary | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
|
||||
| `wai.quantum.job` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
|
||||
| `wai.quantum.wasmq` | payload | registered | binary | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
|
||||
| `wai.route.record` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
|
||||
| `wai.semantic.clip` | payload | registered | image | standalone | royalty-free | behavioral | — | §5 Neural capabilities |
|
||||
| `wai.semantic.perco2` | payload | registered | image | standalone | non-commercial | behavioral | — | §5 Neural capabilities |
|
||||
|
|
@ -446,6 +447,7 @@ and a role are fixed once registered.
|
|||
| `wai.quantum.landscape/sample` | a fabric kernel: the sampling of an energy-landscape job |
|
||||
| `wai.quantum.circuit/1` | a contract revision: the `ext` of a wai.quantum.circuit payload's contract (quantum-sim §2.1), a part of the capability's definition |
|
||||
| `wai.quantum.circuit2/1` | a contract revision: the `ext` of a wai.quantum.circuit2 payload's contract (quantum-sim §2.1), a part of the capability's definition |
|
||||
| `wai.quantum.wasmq/1` | a contract revision: the `profile` of a wai.quantum.wasmq payload's contract and of its run's result (quantum-wasmq §2.2, §6.4, §10), a part of the capability's definition |
|
||||
| `wai.quantum.job-record/1` | a document with no schema file: the record a job service's store keeps a job in (wai-quantum-service) |
|
||||
| `wai.quantum.provider-job/1` | a document with no schema file: the record wai-quantum-qpu keeps of a job on a person's provider, written before the job is sent |
|
||||
| `wai.quantum.optimize-checkpoint/1` | a document with no schema file: an optimisation's checkpoint (wai-quantum's `engine::variational`) |
|
||||
|
|
@ -453,6 +455,7 @@ and a role are fixed once registered.
|
|||
| `wai.quantum.docs-manifest/1` | a document with no schema file: the list of documents tools/quantum-docs checks |
|
||||
| `wai.quantum.write/1` | a document with no schema file: the transcript wai-quantum-writer keeps of writing a program for a task |
|
||||
| `wai.quantum.model/1` | a document with no schema file: the manifest of a writer's model, the file wai-model.json (wai-quantum-writer's `coder`) |
|
||||
| `wai.quantum.wasmq.result/1` | a document with no schema file: the result of a wasmQ run, held to its form by wai-quantum's `engine::wasmq` (quantum-wasmq §6.4, §6.5) |
|
||||
| `wai.quantum.job-key/1` | a digest domain: the digest a job service keeps a client's idempotency key under, the client's name beside the key (wai-quantum-service) |
|
||||
| `wai.quantum.trace/1` | a digest domain: an optimisation trace's first link is BLAKE3 of it and the request's canonical text (wai-quantum's `engine::variational`) |
|
||||
| `wai.quantum.circuit3` | refused on purpose: not a capability; the circuit core's test gives it to see no gateset read from it |
|
||||
|
|
@ -463,6 +466,9 @@ and a role are fixed once registered.
|
|||
| `wai.quantum.provider/2` | refused on purpose: a version of the provider protocol that no text defines; the reference provider's test sends it to see it answered unsupported_version (quantum-providers §10) |
|
||||
| `wai.quantum.provider/9` | refused on purpose: a version of the provider protocol that no text defines; the protocol schema's test sends it to see it answered unsupported_version (quantum-providers §10) |
|
||||
| `wai.quantum.provider/999` | refused on purpose: a version of the provider protocol that no text defines; the provider conformance corpus sends it to see it answered unsupported_version (quantum-providers §10) |
|
||||
| `wai.quantum.wasmq/2` | refused on purpose: a wasmQ profile that no text defines; wasmQ's tests, the receipts corpus and its verifiers put it in a contract or a result to see the job refused (quantum-wasmq §6.5, rules 4 and 11) |
|
||||
| `wai.quantum.wasmq/1x` | refused on purpose: the wasmQ profile one letter longer; the receipts' differential check puts it in a contract to see both verifiers refuse the job (quantum-wasmq §6.5, rule 4) |
|
||||
| `wai.quantum.wasmx` | refused on purpose: not a capability; wasmQ's adversarial test and its vectors put it in a payload's manifest to see the envelope refused with W013 (quantum-wasmq §2.3) |
|
||||
|
||||
| wire identifier (not a capability) | kind | status | defined in |
|
||||
|---|---|---|---|
|
||||
|
|
|
|||
|
|
@ -1008,6 +1008,7 @@ standard. See the linked extension for each.
|
|||
| `wai.ternary.tt` | WQTT container (balanced-ternary MPS cores — packed trits + integer per-column scales) | a **quantum-inspired** (tensor-network) transform ported from the ternary/MPS fabric with ONE change: the per-column scale is an **integer**, so the whole decode is `i64`/`i128` and the reconstruction is byte-identical on every machine — **reconstruction-equivalence** (a portable recon hash), receiptable. Scope: a **provenance** transform, measured at 13.3 dB SNR for 3.8× with six residual layers (`Lossy` tier; the extension's §5). Encoder-side float SVD only · [ternary-tt](extensions/ternary-tt.md) |
|
||||
| `wai.quantum.circuit` | WQC container (gate op-log — Clifford+T + dyadic phase) | the wire carries a **circuit** (kilobytes, linear in gate count), the sink CLASSICALLY simulates it in a fixed-point **complex** floor (`Amp` = i64 re/im), and the reconstructed `2^n`-amplitude statevector is byte-identical on every machine — **statevector-equivalence** (a portable statevector hash); measurement is sampled by the pinned `splitmix64` so a shot histogram at a pinned `(seed, shots)` converges too (**shot-histogram-equivalence**). The dyadic phase ladder transports the **QFT** ("quantum FFT") as a circuit, reconstructed byte-exact; the phase table is frozen as existing content was made with it, so `P(k)` deviates from the ideal phase for k ≥ 8 and applies none for k ≥ 19, and new content uses `wai.quantum.circuit2`. No quantum hardware — NISQ noise breaks the determinism the standard rests on; this makes a quantum *computation* transportable + receiptable, with **no** speedup claimed · [quantum-sim](extensions/quantum-sim.md) |
|
||||
| `wai.quantum.circuit2` | WQC container under magic `WQC2` (the same gate op-log) | the successor of `wai.quantum.circuit`, with the same statevector- and shot-histogram-equivalence: a correctly rounded phase table (each component of every `P(k)` within half a unit of 2^30·e^{2πi/2^k}), so the dyadic phase ladder gives the **QFT**; a byte-canonical contract; an op-log that ends exactly after its last op. A new capability, not a change to the old one, because a registered capability's payload format is fixed (§8): a reader that predates it rejects a `WQC2` payload at the magic · [quantum-sim](extensions/quantum-sim.md) |
|
||||
| `wai.quantum.wasmq` | WAI1 envelope whose payload is a `WQM1` bundle: an OpenQASM 3 program of Clifford gates, the WebAssembly modules its `extern`s call and their priors, each pinned by BLAKE3 in a canonical contract | **result-equivalence** · [quantum-wasmq](extensions/quantum-wasmq.md) §6.4: every conforming runner gives an envelope the same result bytes, the same fuel for every callout and the same fault, on every host and engine. A run is whole-number arithmetic throughout: a stabilizer tableau, outcomes from an integer stream, and modules held to a deterministic profile (Lime1, nothing imported, memory and stack bounded, NaNs canonical, fuel counted on the module as written), sealed in the job receipt |
|
||||
|
||||
*Scene carriage* ([scene-carriage](extensions/scene-carriage.md)) maps a world (`WWLD`),
|
||||
an audio scene (`WSCN`), the assets a world names and timed media items onto ISO/IEC
|
||||
|
|
|
|||
162
wai/changes/2026-11-05-wasmq-hybrid-quantum-classical.md
Normal file
162
wai/changes/2026-11-05-wasmq-hybrid-quantum-classical.md
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
### wasmQ: an OpenQASM 3 program and the WebAssembly its `extern`s call, run the same everywhere, metered and receipted
|
||||
|
||||
- **The extension** [`extensions/quantum-wasmq.md`](extensions/quantum-wasmq.md) registers
|
||||
`wai.quantum.wasmq` (SPEC §5): a WAI1 envelope whose payload carries an OpenQASM 3 program,
|
||||
the WebAssembly modules that define its `extern` functions and their priors, each pinned by
|
||||
BLAKE3 in a canonical contract, so the envelope's digest names all of it. Its interface is
|
||||
[`extensions/quantum-wasmq.wit`](extensions/quantum-wasmq.wit).
|
||||
- **Whole numbers from end to end.** This version runs Clifford programs (the gates that take
|
||||
no angle) on a stabilizer tableau, with each random outcome one bit of an integer stream the
|
||||
text defines, so a result's bytes are the same on every conforming runner.
|
||||
- **The profile.** A module is a core module in the Lime1 feature set that imports nothing,
|
||||
bounds its memory and its size, and has no start function, threads, vectors, references or
|
||||
growing table; each rule has a refusal code (`W001`–`W017`), and a reader refuses on reading
|
||||
everything a run could not finish for a reason of the bundle's own. WebAssembly 3.0's
|
||||
deterministic profile leaves `memory.grow`, `table.grow` and the call depth to the host; the
|
||||
profile fixes all three.
|
||||
- **What a run asks of its host.** A reader bounds from the bundle alone, and a program as it
|
||||
reads it, what a run asks of a host outside its modules' fuel: the program's text, nesting,
|
||||
qubits, bits, steps and the bits its calls pass, the memory and code among a bundle's modules,
|
||||
an envelope's size, its results, and the work of its steps, its calls, its instances, its
|
||||
compiling and the most fuel it may be given. So an envelope that opens on one host opens and
|
||||
finishes on every host, a 32-bit one among them. The reader's nesting bound (`Q130`, as every
|
||||
reading of a program counts it) and its bounds for programs from others (`Q323`) hold for a
|
||||
bundle's program; `Q209` keeps its meaning, definitions and calls past 32.
|
||||
- **A determined measurement, word by word.** The stabilizer tableau finds a determined
|
||||
outcome as the sign of the stabilizers' product, a machine word of rows at a time, without
|
||||
copying the tableau: at the most qubits, milliseconds where it took seconds, with the same
|
||||
outcome, which a test holds to the full product on random states.
|
||||
- **Fuel and stack, defined on the module.** Fuel is charged at the start of each run of
|
||||
instructions, with the weights of the pinned wasmtime's own default count, and a page a
|
||||
module grows at what zeroing it costs. The stack is
|
||||
bounded by weight: each function's frame weighs a base and its parameters, results, locals,
|
||||
the most operands its body holds and its bytes, and the frames suspended at calls may weigh 2^23 together, so the bound holds for
|
||||
a frame of any size. A test holds the native engine to eight bytes of stack for each unit.
|
||||
- **Two engines, one result.** The pinned wasmtime runs the module prepared to meter itself;
|
||||
an interpreter of the crate's own, which also runs on wasm32, meters it itself. Every
|
||||
instruction, charge, trap and fault agrees between them, and a host reaches a module's
|
||||
memory the same way on both, as its export `memory`.
|
||||
- **Callouts in the program.** The reader takes `extern` calls as steps when asked
|
||||
(`qasm::read_callouts`, which returns the program with its steps, `qasm::Step`, and its
|
||||
`extern`s): a call runs in program order between gates, its arguments bits or integers
|
||||
known on reading, its result written to bits a later `if` reads. Every other reading still
|
||||
refuses them (`Q125`), and nothing in the reader's existing types changes. An `extern` lowers
|
||||
to an integer function when its widths fit 64 bits, and to lists otherwise: the Component
|
||||
Model's canonical ABI.
|
||||
- **The receipt.** A run goes shot by shot and seals its result in the job receipt the
|
||||
engine already signs: counts, the fuel of every callout, the modules' digests, a digest of
|
||||
every call's inputs and outputs, and the fault that stopped it (fuel, stack, a trap or a
|
||||
result past its width), as a signed fault receipt. Every member of the result is defined by
|
||||
the text.
|
||||
- **The command line**: `wai-quantum pack-wasmq`, `check-wasmq`, `run ENVELOPE.wai`
|
||||
(`--engine`, `--transcript`, `--replay`, each record written and read a call at a time), and
|
||||
`verify JOB --bundle ENVELOPE.wai`, which also runs the envelope again and compares byte for
|
||||
byte. A flag of a program's run given with an envelope, or an envelope's given with a
|
||||
program, is refused rather than ignored. A bundle goes to no provider: the provider protocol
|
||||
carries no call between gates, and the bring-your-own-quantum boundary is as it was.
|
||||
- **One verdict on every surface.** A wasmQ job is checked on the one path every job is
|
||||
(`engine::job::check`), so `wai-quantum verify` (with `--json` and `--lines`), the job
|
||||
service's `POST /v1/verify`, both MCP servers, the Python package, the desktop app, a view
|
||||
and a page give it the same verdict. Its text is read as the provider protocol's §8.2 reads
|
||||
every job's, and §8.4 gains one reason, `wasmq_form`: the job breaks a rule of
|
||||
quantum-wasmq §6.5, whose thirty-five numbered rules hold the contract, the result, the fuel,
|
||||
the fault and the counts to the profile, by what is sealed alone, under whichever key. Beside
|
||||
the verdict, `wasmq` states how the run ended, each rule it breaks, and where the host's
|
||||
unsealed words differ from what is sealed, which change no verdict. The form lives in the
|
||||
engine (`engine::wasmq`), and the runner takes its constants from there.
|
||||
- **Receipts of record.** The receipts corpus holds six wasmQ jobs the command line sealed
|
||||
(a run, one of a single instance, and faults in a call, of the run's budget, in an init and
|
||||
in a prior) and forty-four crafted from them: forty each breaking the one rule of §6.5 it
|
||||
names and no other (every rule but the first, which no receipt can break alone, as every
|
||||
place a number may be has a rule of its own, and rule 27, which rule 32 holds too), two
|
||||
breaking two, and two the same sealed content written otherwise or under another envelope. The second verifier, written in
|
||||
Python from §6.5 without the reference, gives `wasmq_form` on its own, and the differential
|
||||
holds the two to each other on every one-member change of each of the six; a planted
|
||||
verifier that skips the rules (`wasmq-unchecked`) is caught.
|
||||
- **Every surface, every body.** Text that does not read as a job's, a body that is no job,
|
||||
and a result with no receipt are each a verdict with that reason alone on every surface:
|
||||
the command line, both MCP tools, the job service over HTTP (a 200 verdict, no longer a
|
||||
400), the Python package, the desktop app, a page and a view. The service's tool given a
|
||||
job's members checks the body it is given, its unsealed status among them. The Python
|
||||
package judges a dict as the text it writes for it, and reads text that begins with a byte
|
||||
order mark as text. A job routes to an estimate's or an algorithm's verifier only when it
|
||||
is not a wasmQ job (`job::has_own_verifier`).
|
||||
- **The command line's `--lines`** reads each line on its own: a line that is not UTF-8,
|
||||
or blank, is that line's `unreadable`, and a file of no line is refused. `verify` says a
|
||||
job found unreadable or with no receipt was not judged, and runs no envelope for it.
|
||||
- **The form, tightened.** A call that stopped the run is one of the calls made: its
|
||||
callout's fuel counts it, and its largest call is at least what it used. A whole number
|
||||
past 2^53 − 1 is no count however a reader holds it. Rule 1's walk is linear in the text,
|
||||
however long a member's name. A member is present whatever its value, `null` among them.
|
||||
- **Writer and verifier agree.** Each budget is at most 2^39 when packed (`W017`), as every
|
||||
verifier holds a contract to it. The program's qubits are defined for a program that names
|
||||
physical qubits, and the bits' order for several registers; a vector pins both. A hybrid
|
||||
reading's refusal for controls offers no method its run cannot use.
|
||||
- **Every tie the writer keeps is a rule.** Rules 20 to 35 hold what the runner guarantees
|
||||
between members:
|
||||
- a returned call used 1 to the most one call used, and the stopped one the fault's fuel;
|
||||
when the most is a returned call's, the others used 1 each at least;
|
||||
- each set of instances passed every prior, a prior costing its bytes and 3 at least, and
|
||||
called the `wasmq-seed` or `init` a lifecycle fault shows its module exports; the set a
|
||||
lifecycle fault stopped passed the priors of the modules before its own; the stopped
|
||||
call's fuel is on top of all of it; and each prior passed whole fits one lifecycle call's
|
||||
limit;
|
||||
- a call's fault is in its callout's module, a prior's in a module with one, a
|
||||
`bad_result` in a call or a prior;
|
||||
- a lifecycle fault is in shot 0 for one instance a run, and before any call in shot 0;
|
||||
- a fuel fault used its whole limit, and any other fault at least what its reason shows
|
||||
was charged (1; 2 for `bad_result`; 788 for `stack_exhausted`, the frames §3.2 allows
|
||||
to pass 2^23);
|
||||
- with no call returned, the transcript is the run's end alone, which the receipt holds;
|
||||
- §4.8's products and sums over what a receipt shows: a shot's bits (a name's length in
|
||||
characters), the shots' bits, the work (4097 for each call made among it), the calls a
|
||||
shot's 2^21 steps hold, and the envelope's bytes, its manifest and its contract with its
|
||||
frames.
|
||||
|
||||
§6.5 says what it leaves free, and why, among it a program's and a module's least length
|
||||
and an `extern`'s spelling; a result's `qubits` is at least 1. Rule 6 no longer repeats the bounds rules 6 and 31 imply, and rules 8,
|
||||
14 and 18 no longer repeat what rules 20, 25 and 30 hold.
|
||||
- **The outcome, exactly.** §6.1 gives a shot's outcome as every bit the program declares at
|
||||
its top level, written or not; a block's own bits are in no outcome; a measurement in a
|
||||
program that calls externs names its bit (`Q324` refuses one that does not). Vectors pin
|
||||
bits nothing writes and a block's own bit, and refuse a measurement with no bit.
|
||||
- **The differential's rules stage**: each rule of the form at its bound, on both sides,
|
||||
sealed again, each verdict written by hand, the review's labelled cases among them; the
|
||||
second verifier's own hand-labelled cases run through the reference as well; and weakenings
|
||||
of each rule, generated in both verifiers, each caught.
|
||||
- **One answer, every kind of job.** An estimate or an algorithm's answer with no receipt, or
|
||||
that is no job, is that reason alone on the command line, its MCP tool, `POST /v1/verify`
|
||||
and the service's tool, as every other job is; one is run again only once its receipt and
|
||||
§8.4's rules hold (`job::answer_of`, `job::answer_of_text`), and the service runs an
|
||||
algorithm's answer again as the command line does, its tool alike given the job's text,
|
||||
the job, or its members. A job past what a surface reads, in its bytes or in its values, is
|
||||
`too_large`, a new reason of §8.4 reported alone, stating both (`read_at_most`):
|
||||
`wai-quantum verify` reads 384 MiB and 2^22 values on every host, in about 1 GiB of memory;
|
||||
`POST /v1/verify` and `/mcp` read 4 MiB and 2^19 values, and check off the service's async
|
||||
workers, two at a time. `/mcp` answers a verify call past that with its verdict by its id,
|
||||
reading a message past six times that only as far as its id, method and tool. A check
|
||||
holds one reading of a job at a time. A job of any depth reaches its verdict through a
|
||||
view's request and an MCP call, `unreadable` past 127, judged before the message is read
|
||||
whole. An estimate whose request runs again nowhere is not valid and says why
|
||||
(`rerun_error`), as an algorithm's answer does, on every surface. `verify` prints the verdict
|
||||
of text that does not read and of no job. The Python package reads a str as a path only
|
||||
when it names a file, and gives a verdict for every str and dict, a lone surrogate's
|
||||
among them.
|
||||
- **Breaking:** `POST /v1/verify` answers 200 with a verdict for a body that is not JSON, no
|
||||
job, has no receipt (`unreadable`, `not_a_job`, `no_receipt`) or is past 4 MiB or 2^19
|
||||
values (`too_large`), where it answered 400 for the first three and 413 past 1 MiB; a
|
||||
client reads `valid` and `reasons`. Its OpenAPI document says
|
||||
so. `wai-quantum verify` reads at most 384 MiB and 2^22 values of a job, where it read any
|
||||
file whole.
|
||||
- **Breaking:** the command line's MCP server answers a line that is not UTF-8 with JSON-RPC
|
||||
-32700 and reads on, where it ended its session.
|
||||
- **Breaking:** the Python package's `verify` given a str that names no file reads it as the
|
||||
job's text and gives its verdict (`unreadable` for a path that is not there), where it
|
||||
raised `FileNotFoundError`.
|
||||
- **Reference modules** from the engine's own code: the qLDPC decoder (matching for codes
|
||||
with a matching graph, Relay-BP otherwise) and the atom rearrangement planner, modules of
|
||||
record built on x86_64 Linux and committed with their sources' digests. Their results equal
|
||||
the same functions compiled natively, called directly and in the middle of circuits.
|
||||
- **Vectors** in `quantum-conformance/wasmq/`: envelopes with the result each must give on
|
||||
every engine and host, and modules and envelopes a runner refuses, at least one for every
|
||||
code, each one defect away from one that is accepted.
|
||||
|
|
@ -844,7 +844,7 @@ package of several components: the
|
|||
media classes `graphics` (7) and `text` (8) beside packaging's others, the rungs each medium
|
||||
takes, how each component is cut at the lead's piece starts, each piece's object and `target`,
|
||||
and the decoded-output digest each entry states. The reference package is written by
|
||||
`wai-pack` under `compose/policy.toml`: the lead `v`, a 320 × 180 test pattern (the fixture
|
||||
`wai-pack` under `compose/policy.toml`: the lead `v`, a test pattern of 320 × 180 (the fixture
|
||||
`compose-01`) with an integer base and a supplied AV1 floor for every piece; `g`,
|
||||
`vector-conformance`'s title card and credit roll; `t`, three captions; `s`, a score with a
|
||||
FLAC floor of each piece's mixdown, which this page does not decode (no route: it holds no
|
||||
|
|
|
|||
|
|
@ -542,6 +542,7 @@ as a set: none for a valid receipt. It is valid exactly when there is none.
|
|||
| `unreadable` | the text breaks a rule of reading (§8.2). Reported alone |
|
||||
| `not_a_job` | the value is not an object whose `request` and `result` are both objects. Reported alone |
|
||||
| `no_receipt` | the result has no `receipt`. Reported alone |
|
||||
| `too_large` | the job is longer than the surface reads, in its bytes or in its values (one, and one more for each `,`, `:`, `[` and `{` outside its strings: what a check holds follows them), which it states with the verdict (`read_at_most`: `{"bytes", "values"}`); it judged none of it. Reported alone. `wai-quantum verify`, on every host, reads 384 MiB and 2^22 values, more than any job holds; the job service's `POST /v1/verify` and `/mcp` read 4 MiB and 2^19 values. A job given as a string is its text's bytes and values; one given parsed in a message, as it is written there |
|
||||
| `receipt_form` | the receipt is not an object; its `alg` is not `ed25519`; it has a `canon` other than `rfc8785`; or its `key`, `digest` or `signature` is not lower-case hex of its length. When it is reported, the next three are not checked |
|
||||
| `digest_mismatch` | the digest the receipt states is not the digest (§8.2) of this request and result |
|
||||
| `bad_key` | `key` is refused by the strict rules (§8.2). When it is reported, the signature is not checked |
|
||||
|
|
@ -556,6 +557,7 @@ as a set: none for a valid receipt. It is valid exactly when there is none.
|
|||
| `execution` | a stated provider's result whose `execution` breaks a rule of §8.3; or, for a kind with rows, is neither one of the rows that hold for its provenance nor stated by `nobody`; or, for `http` and `process`, is not stated by `provider` or `nobody` |
|
||||
| `compiled_program` | a stated provider's result whose `compiled.program` is not the BLAKE3 of `compiled.qasm3`'s UTF-8 bytes, when `qasm3` is a string and `program` is 64 lower-case hex digits |
|
||||
| `cost_confirmation` | a stated provider's result whose `cost.confirmed` is `true` on a free run or `false` on one that is not free (§7), when both are `true` or `false` |
|
||||
| `wasmq_form` | a wasmQ job's result (its `format` is `wai.quantum.wasmq.result/1`, [quantum-wasmq](quantum-wasmq.md)) whose request or result breaks a rule of [quantum-wasmq §6.5](quantum-wasmq.md#65-verifying): the job is not one that profile writes |
|
||||
|
||||
A provider's result is one whose `method` is `provider`. It is *stated* when it
|
||||
carries a member `counts_source` or a member `execution` (whatever their
|
||||
|
|
@ -598,6 +600,12 @@ A verifier also states, for a provider's result (one with no receipt
|
|||
included), its class as its provenance reads it, and, in the stated form, its
|
||||
counts' source and its `execution`, each as the result gives it.
|
||||
|
||||
A wasmQ job's result is held to `wasmq_form` whatever its `method`, and to the provider
|
||||
rules too when its `method` is `provider`. A verifier also states, for a wasmQ job, what
|
||||
quantum-wasmq §6.5 says it states beside the verdict: how the run ended, each rule it
|
||||
breaks and where the body's unsealed members differ from what is sealed. None of that
|
||||
changes the verdict.
|
||||
|
||||
These are all the rules: what §8.1 names and this table does not check
|
||||
(`compiled.hash` and `placement`, the notes, the `ideal` figures, the
|
||||
estimate's contents) is the host's word, unchecked. The schemas
|
||||
|
|
@ -686,6 +694,10 @@ whether each `qasm` is that program (`derived`, beside the reasons); that is the
|
|||
engine's check of the set, not a rule of its receipt, and a verifier that does
|
||||
not write programs out does not make it.
|
||||
|
||||
A program that calls WebAssembly between its gates ([quantum-wasmq](quantum-wasmq.md))
|
||||
is not a program of §4: it has steps between gates that this protocol does not carry. A
|
||||
client MUST NOT send one to a provider; it runs where its runner is (quantum-wasmq §7).
|
||||
|
||||
## 9. Conformance
|
||||
|
||||
`wai-quantum-qpu/conformance/provider-v1.json` holds the vectors:
|
||||
|
|
@ -731,9 +743,17 @@ surface that verifies is held to the manifest by its own tests, given each
|
|||
receipt's text: the job service over HTTP and as a tool, the command line's tool
|
||||
(each takes the job's text), the Python package (text, bytes or a path), the
|
||||
desktop app and a browser tab. A surface given a job already parsed into objects
|
||||
(a tool's `request` and `result`, a Python dict) cannot see what parsing loses:
|
||||
(a tool's `request` and `result`, a view's object) cannot see what parsing loses:
|
||||
a member named twice (`unreadable`), and a whole number past what its reader
|
||||
keeps (`inexact_number`). It reports every other reason, and is held to the
|
||||
keeps (`inexact_number`). A job parsed deeper than a text is read (127) is
|
||||
`unreadable` there too, however deep it is: a message that carries a job (a tool's
|
||||
call, a view's request) is read so that the job reaches its verdict (a job nested past
|
||||
127, or past what the surface reads, is judged before the message is read whole, and the
|
||||
message around it may nest at most 8 more), and a message that does not read is the
|
||||
protocol's error, as a line that is not UTF-8 is to the command line's MCP server, which
|
||||
answers it and reads on. The Python package judges a dict as the text it writes
|
||||
for it, so a dict's nesting and its whole numbers are judged as text's are; only a
|
||||
member named twice is past what a dict can hold. It reports every other reason, and is held to the
|
||||
manifest on every receipt but those. A tool's text is a JSON string, which holds
|
||||
UTF-8 only, so text that is not UTF-8 reaches a verifier only as a file's bytes.
|
||||
|
||||
|
|
|
|||
988
wai/extensions/quantum-wasmq.md
Normal file
988
wai/extensions/quantum-wasmq.md
Normal file
|
|
@ -0,0 +1,988 @@
|
|||
# WAI Extension: Hybrid Quantum-Classical Execution (`wai.quantum.wasmq`)
|
||||
|
||||
Status: **Draft.** Reference implementation: `wai-wasmq` (the profile, `src/profile.rs`;
|
||||
the prepared module, `src/meter.rs`; the interpreter, `src/interp.rs`; the engines,
|
||||
`src/engine.rs`; the lowering, `src/abi.rs`; the envelope, `src/envelope.rs`; the run and
|
||||
its receipt, `src/run.rs`), the OpenQASM reader's callouts (`wai-quantum`,
|
||||
`qasm::read_callouts`), and the command line's `pack-wasmq`, `check-wasmq`, `run` and
|
||||
`verify` (`wai-quantum-cli`, `src/wasmq.rs`). A job's form (§6.5) is the engine's, where
|
||||
every verifier of its receipts reaches it (`wai-quantum`, `engine::wasmq`). Interface: [`quantum-wasmq.wit`](quantum-wasmq.wit).
|
||||
Vectors: [`../quantum-conformance/wasmq/`](../quantum-conformance/wasmq/).
|
||||
|
||||
Keywords **MUST**, **MUST NOT**, **SHOULD** and **MAY** are RFC 2119/8174.
|
||||
|
||||
## 0. What this extension adds
|
||||
|
||||
A hybrid quantum program runs classical code between its gates: it decodes a syndrome
|
||||
and corrects the error before the next round, or plans the moves that fill an atom
|
||||
array. OpenQASM 3 declares such a function with `extern` and leaves its body, its binary
|
||||
form and how it is linked outside the language. This extension fills that gap for WAI
|
||||
Quantum, and nothing else:
|
||||
|
||||
- **One envelope.** A WAI1 envelope of capability `wai.quantum.wasmq` carries the
|
||||
OpenQASM 3 program, the WebAssembly modules that define its `extern`s, and the modules'
|
||||
parameter files (priors), each pinned by BLAKE3 in a canonical contract (§2).
|
||||
- **One profile.** A module is a core WebAssembly module in the Lime1 feature set, which
|
||||
imports nothing, whose memory, size and stack are bounded, and which uses nothing whose
|
||||
result a host may choose (§3).
|
||||
- **The same bytes and the same fuel everywhere.** Fuel, the stack's weight and the NaN a
|
||||
float instruction makes are defined on the module as written (§4), so every runner
|
||||
gives a callout the same results, the same fuel and the same fault. The reference runs
|
||||
each module on two engines, a native one and an interpreter that also runs on wasm32,
|
||||
and every vector holds on both, on every host.
|
||||
- **A receipt.** A run seals its result in the job receipt the engine already signs
|
||||
(`engine::receipt`): the counts, the fuel each callout used, the modules' digests, a
|
||||
digest of every call's inputs and outputs, and the fault that stopped the run, if one
|
||||
did (§6).
|
||||
|
||||
This version of the profile runs Clifford programs, in whole numbers from end to end
|
||||
(§5.1, §6.1). A run simulates the quantum program and runs the classical code for real.
|
||||
§7 says what holds when the quantum part runs on hardware, and §10 what this version
|
||||
leaves out.
|
||||
|
||||
## 1. Principles
|
||||
|
||||
1. **Nothing outside reaches the result.** A module imports nothing: no clock, no
|
||||
random source, no file, no network, no host function. Its only inputs are its bytes,
|
||||
its priors, the seed the run gives it and the bits the program passes (§3.2, §5.3).
|
||||
2. **The host chooses nothing.** Every place where WebAssembly lets an engine choose (a
|
||||
NaN's bits, a relaxed vector instruction, how deep calls may go, when memory runs out,
|
||||
when to stop a long computation) is fixed by the profile or refused (§3, §4).
|
||||
3. **Fuel is the measure, not time.** A callout's budget is a number of weighted
|
||||
instructions (§4.2). It is the same on every host; wall-clock time is not, and the
|
||||
profile does not claim one.
|
||||
4. **The direction is the hardware's.** The quantum program calls the module, as a
|
||||
real-time controller calls classical code between gates. A module drives no gates.
|
||||
5. **One form for one bundle.** A bundle has exactly one envelope, so its BLAKE3 names
|
||||
it, and a receipt that names the digest names the program, the modules, the priors and
|
||||
the run (§2.4).
|
||||
6. **What is read is what runs.** A reader refuses on reading every bundle a run could
|
||||
not finish for a reason of the bundle's own (§2.3). A run that starts ends in a
|
||||
receipt, unless the host itself fails (§6.3).
|
||||
|
||||
## 2. The envelope
|
||||
|
||||
### 2.1 Container and manifest
|
||||
|
||||
The envelope is a WAI1 container (SPEC §2). Its manifest is, in this order and with no
|
||||
other member:
|
||||
|
||||
```json
|
||||
{"wai":"1.0","media":"binary","intent":"replicate",
|
||||
"model_requirement":{"capability":"wai.quantum.wasmq","fallback":null},
|
||||
"conditioning":{"kind":"wasmq"},
|
||||
"target":{"qubits":17,"shots":32,"seed":1234}}
|
||||
```
|
||||
|
||||
`fallback` is `null`: a sink without this capability holds no way to run the program's
|
||||
callouts, so the envelope is inert there (SPEC §4). `target` is informational (SPEC §3)
|
||||
and is the contract's: the program's qubits (§2.2), the shots and the seed.
|
||||
`conditioning` carries no `prior`: SPEC §3.1's pin names a parameter set the sink
|
||||
supplies, and a wasmQ envelope carries its modules' priors itself, each pinned in the
|
||||
contract (§2.2).
|
||||
|
||||
### 2.2 Payload and contract
|
||||
|
||||
```text
|
||||
payload = "WQM1" | u32 contract_len | contract | frames
|
||||
frames = program | for each module, in order: the module, then each of its priors in order
|
||||
```
|
||||
|
||||
`contract_len` is little-endian. The contract is JSON in the canonical form of RFC 8785
|
||||
(JCS), with exactly these members:
|
||||
|
||||
| member | |
|
||||
|---|---|
|
||||
| `profile` | `"wai.quantum.wasmq/1"` |
|
||||
| `program` | `{ "blake3", "bytes", "inputs" }`: the OpenQASM 3 source's digest and length, and the values of its integer `input`s (an object, empty when there are none) |
|
||||
| `modules` | for each module: `{ "name", "blake3", "bytes", "priors": [{ "name", "blake3", "bytes" }] }` |
|
||||
| `callouts` | one for each `extern` the program declares, in the order it declares them: `{ "extern", "module", "export" }`, the module by its index |
|
||||
| `run` | `{ "shots", "seed", "method", "state", "fuel": { "per_call", "per_job", "per_instance" } }` (§6.1, §4.2) |
|
||||
|
||||
`blake3` is the BLAKE3 digest of the frame as 64 lowercase hexadecimal digits; `bytes`
|
||||
its length. A `name` is for people. `method` is `stabilizer`, the one method of this
|
||||
version (§5.1). `state` is `shot` (a fresh instance of each module every shot) or `job`
|
||||
(one instance for the run, its shots in order). `shots` is 1 to 2^20. `seed` and the
|
||||
size of each input are at most 2^53 − 1, so that every JSON reader holds them exactly, and
|
||||
each budget at most 2^39 (§4.8). `per_job` is held to less with any module: its eight
|
||||
operations for each unit of fuel take all of a run's work at 2^39, and a run's other work
|
||||
is never nothing (§4.8). Every module is named by
|
||||
at least one callout. The program's text is at most 1 MiB, and the modules'
|
||||
bytes at most 512 KiB among them.
|
||||
|
||||
**The program's qubits** are the qubits it declares, all its registers together; a program
|
||||
that declares none and names physical qubits (`$0`, `$5`) has one more than the highest
|
||||
index it names, the qubits below it among them.
|
||||
|
||||
### 2.3 Reading an envelope
|
||||
|
||||
A reader MUST refuse an envelope, with the code of §3.3, when:
|
||||
|
||||
- it is longer than 128 MiB, its first four bytes are not `WAI1`, its capability is not
|
||||
`wai.quantum.wasmq`, its manifest is not the one §2.1 gives for its contract byte for
|
||||
byte, or any byte follows the payload (`W013`);
|
||||
- the payload's magic is not `WQM1`, the contract is not in its RFC 8785 form, holds a
|
||||
member §2.2 does not list or lacks one, or the frames do not end exactly where the
|
||||
payload ends (`W013`);
|
||||
- a frame's BLAKE3 is not the one the contract pins: the program, a module, a prior
|
||||
(`W014`);
|
||||
- a module breaks the profile (§3: its code), the modules hold more than 4096 pages among
|
||||
them (`W003`, §4.7), or more than 512 KiB of bytes (`W010`);
|
||||
- the program is longer than 1 MiB, is refused by the reader, calls nothing, has a gate
|
||||
outside §5.1's, or is past a bound §4.8 reads it within (`W016`);
|
||||
- the callouts are not one for each `extern` in the order declared, a module is named
|
||||
by none, a callout's export is not the type its `extern` lowers to, or a module the
|
||||
host must write to or read a list from does not export what §5.2 asks (`W015`);
|
||||
- the run is outside §2.2's ranges, or past what §4.8 lets a run ask of its host (`W017`).
|
||||
|
||||
A writer checks the same rules and writes nothing that breaks one. An envelope that
|
||||
passes them runs: nothing about a bundle is left for a run to find (§6.3).
|
||||
|
||||
### 2.4 One envelope for one bundle
|
||||
|
||||
A writer MUST write the frames in §2.2's order, the contract in its canonical form with
|
||||
its callouts in the order the program declares its `extern`s, and the manifest exactly
|
||||
as §2.1 gives it. A reader that holds these rules reads every bundle from exactly one
|
||||
sequence of bytes, so the envelope's BLAKE3 (`envelope_blake3`) names the bundle, and a
|
||||
receipt that binds it binds every frame.
|
||||
|
||||
## 3. The module profile
|
||||
|
||||
### 3.1 A core module
|
||||
|
||||
A module is a core WebAssembly module (WebAssembly 3.0, §5 Binary Format), not a
|
||||
component. It MAY be the core module of a component: its exports are the canonical
|
||||
lowering of the functions [`quantum-wasmq.wit`](quantum-wasmq.wit) declares, so a
|
||||
component host can wrap it, and a host of this profile calls it directly.
|
||||
|
||||
### 3.2 The rules
|
||||
|
||||
A module MUST validate under the **Lime1** feature set of the WebAssembly tool
|
||||
conventions: WebAssembly 1.0 with mutable globals, multi-value, sign extension,
|
||||
non-trapping float-to-int conversion, `memory.copy` and `memory.fill`, extended constant
|
||||
expressions and the overlong `call_indirect` encoding. Every instruction is in the
|
||||
encoding that feature set gives it, and every function body ends with the `end` of its
|
||||
own block. And:
|
||||
|
||||
| rule | why |
|
||||
|---|---|
|
||||
| It imports nothing. | Nothing outside the module reaches its result. A clock, a random source or any host function would. |
|
||||
| It has at most one memory, 32-bit, unshared, of 64 KiB pages, with a maximum of at most 4096 pages (256 MiB). | A memory without a maximum grows as far as a host lets it, which differs by host. |
|
||||
| It has no start function. | Nothing runs when an instance is made: every instruction runs in a metered call (§5.3). |
|
||||
| Nothing shared, no atomic instruction. | Lime1 has no threads. |
|
||||
| No vector instruction or type, relaxed or not. | A relaxed vector instruction's result is the engine's choice; the profile takes none. |
|
||||
| No instruction or type of another feature outside Lime1: references, exceptions, tail calls, garbage collection, passive segments. | Lime1's values are numbers. |
|
||||
| At most one table, of `funcref`, at most 2^16 entries, filled once from active segments of function indices; no instruction reads or changes it but `call_indirect`. | `table.grow` stays non-deterministic in the deterministic profile (below). |
|
||||
| In every function, at most 4096 parameters, locals and operands at once. | It bounds what one frame holds in an interpreter. |
|
||||
| At most 512 KiB of bytes, which is also what the modules of a bundle hold among them; at most 2^16 types, functions, globals, data segments and element segments each; at most 2^10 exports, each name at most 256 bytes; a function type of at most 2^8 parameters and 2^8 results; a function's entry in the code section of at most 2^14 bytes. | They bound what a reader, an engine and a frame need (§4.3), with room for what preparing a module adds (§4.4): a body of calls grows some 53 times prepared, and an engine compiles a function whole. |
|
||||
| Every active data and element segment fits where it is placed. | Instantiation then cannot fail. |
|
||||
| No export begins `__wasmq`, and an export a host calls has exactly its type (§5.2, §5.3). | The first are the prepared module's names (§4.4); a host passes the second arguments of those types. |
|
||||
|
||||
WebAssembly 3.0 defines a deterministic profile: every NaN an instruction makes is
|
||||
canonical and positive, and every relaxed vector instruction has a fixed behaviour. Even
|
||||
under it, `memory.grow` and `table.grow` remain non-deterministic, to indicate resource
|
||||
exhaustion, and the depth of calls an engine allows is an implementation limit. This
|
||||
profile takes the deterministic profile's rule for NaNs (§4.5) and closes the others: no
|
||||
vector instruction is taken, the table never grows, the memory grows only within the
|
||||
maximum the module declares (§4.7), and the stack is weighed (§4.3).
|
||||
|
||||
The limits of the last rows are each below the limits of the validator and the native
|
||||
engine the reference uses, and stay below them once a module is prepared: a test makes a
|
||||
module of the most bytes, its largest body all calls, with the most exports, names, table
|
||||
entries and memory and as many of each other item as fit beside them, and prepares,
|
||||
compiles and runs it on every engine (`wai-wasmq/tests/engines.rs`).
|
||||
|
||||
### 3.3 Refusal codes
|
||||
|
||||
| code | the module or envelope |
|
||||
|---|---|
|
||||
| `W001` | is not a valid core module in Lime1, for a reason no other code names (a component, a malformed module, a body that does not end, an encoding of another feature) |
|
||||
| `W002` | imports something |
|
||||
| `W003` | has more than one memory, a 64-bit one, one with a page size of its own, one without a maximum or past 4096 pages; or (envelope) has modules with more than 4096 pages among them |
|
||||
| `W004` | has a start function |
|
||||
| `W005` | has a shared memory, global, table or type, or an atomic instruction |
|
||||
| `W006` | has a vector instruction or type, relaxed or not |
|
||||
| `W007` | has an instruction or a type of a feature outside Lime1 that no other code names |
|
||||
| `W008` | has more than one table, one not of `funcref`, past 2^16 entries, or an instruction that reads or changes it other than `call_indirect` |
|
||||
| `W009` | has a function whose parameters, locals and operands can pass 4096 |
|
||||
| `W010` | is past a size the last rows of §3.2 give; or (envelope) has modules of more than 512 KiB among them |
|
||||
| `W011` | has a data or element segment that does not fit where it is placed |
|
||||
| `W012` | exports a name the profile reserves, or an export a host calls with another type than its own |
|
||||
| `W013` | (envelope) is not one this profile writes, or is past its size (§2.3) |
|
||||
| `W014` | (envelope) has a frame whose digest is not the one its contract pins |
|
||||
| `W015` | (envelope) has callouts that are not one for each `extern` in order, a module no callout names, an export of another type than its `extern` lowers to, or a module the host cannot reach as §5.2 asks |
|
||||
| `W016` | (envelope) has a program longer than 1 MiB, that the reader refuses, that calls nothing, with a gate outside §5.1's, or past a bound it is read within (§4.8) |
|
||||
| `W017` | (envelope) has a run outside the profile's ranges, or past what §4.8 lets a run ask of its host |
|
||||
|
||||
A module or an envelope that breaks more than one rule is refused with the code of one
|
||||
of them. Each refusal vector (§9) breaks exactly one.
|
||||
`wai-quantum check-wasmq MODULE.wasm` holds a module to the profile and names the code.
|
||||
|
||||
## 4. Running a module the same everywhere
|
||||
|
||||
### 4.1 Instances
|
||||
|
||||
An instance is made from the module with no imports. Its memory starts at its initial
|
||||
size, zeroed, with the active data segments copied in; its table holds the active element
|
||||
segments; its globals hold their initial values. A host MUST be able to hold the memory's
|
||||
maximum before it calls the instance (§4.7).
|
||||
|
||||
### 4.2 Fuel
|
||||
|
||||
Every call a host makes into an instance has a limit of fuel. Fuel is defined on the
|
||||
module as written, not on any engine:
|
||||
|
||||
- A function's body is a sequence of **runs**. A run starts at the function's first
|
||||
instruction and right after each `block`, `loop`, `if`, `else`, `end`, `br`, `br_if`,
|
||||
`br_table`, `return`, `call`, `call_indirect` and `unreachable`; it ends with the first
|
||||
of them that follows, or with the body.
|
||||
- The **weight** of an instruction is 0 for `nop`, `drop`, `block`, `loop`,
|
||||
`unreachable`, `return`, `else` and `end`, and 1 for every other. Entering a function
|
||||
weighs 1.
|
||||
- When execution reaches the start of a run, the run's weight (with 1 more for the first
|
||||
run of a body) is charged. Before `memory.copy` and `memory.fill` execute, the byte
|
||||
count they take is charged; before `memory.grow` executes, 1024 for each page it asks
|
||||
for is charged, whether or not the growth succeeds: zeroing a page costs a host what
|
||||
1024 instructions do.
|
||||
- When a charge takes the fuel below zero, the call stops with `fuel_exhausted`.
|
||||
|
||||
So a charge happens at the start of a run, before any of the run's instructions, and a
|
||||
call that traps in the middle of a run has been charged the whole run. On every path that
|
||||
does not stop early, the fuel a call uses is the number of instructions it executed under
|
||||
these weights, and one for each function it entered.
|
||||
|
||||
**Limits.** The contract gives three budgets. A callout's limit is `per_call`, and it
|
||||
covers every call the host makes for it (§5.2). The limit of an instance's lifecycle
|
||||
calls is `per_instance`, for each of them (§5.3). `per_job` is the run's: when less than
|
||||
a call's limit is left of it, what is left is the call's limit. The fuel a call used is
|
||||
its limit less what it left, and is taken from what is left of the run's; a call that
|
||||
stops with `fuel_exhausted` used its whole limit.
|
||||
|
||||
The weights are the default operator costs of the native engine the reference uses, with
|
||||
one for a byte of `memory.copy` or `memory.fill` and 1024 for a page of `memory.grow`. A
|
||||
test holds the profile's fuel equal to that engine's own count, on the module as written,
|
||||
over control flow, calls and memory instructions, with one difference it states: for
|
||||
`memory.grow` the profile charges 1024 for each page asked for, and that engine's own
|
||||
meter one for each page it gets (`wai-wasmq/tests/engines.rs`).
|
||||
|
||||
Fuel is a count of work, the same on every host. It is not a time: a host that must
|
||||
answer within a deadline measures its own instructions per second and sets the budget.
|
||||
|
||||
### 4.3 The stack
|
||||
|
||||
Calls are bounded by weight, not by count, so that the bound holds for a frame of any
|
||||
size on any engine. The **weight of a function's frame** is
|
||||
|
||||
```text
|
||||
576 + its parameters + its results + its locals + its operands + the bytes of its entry in the code section
|
||||
```
|
||||
|
||||
its parameters and results those of its type, its locals the ones it declares, its
|
||||
operands the most values its body holds on the operand stack at once (as a validator
|
||||
counts them after each instruction: a call's results among them), and its entry's bytes
|
||||
the value of the entry's own size field. The **stack's weight** is zero
|
||||
when a host calls an export. Before a `call` or `call_indirect` executes, the weight of
|
||||
the function that holds the instruction is added to it; when the callee returns, the
|
||||
same weight is taken off. A call that would take the stack's weight past **8 388 608**
|
||||
(2^23) stops with `stack_exhausted`, before the instruction does anything else: a
|
||||
`call_indirect` that is both past the stack and through an entry it cannot call stops
|
||||
for the stack.
|
||||
|
||||
So the frames suspended at calls never weigh more than 2^23 together, and one more
|
||||
frame runs on top of them. An interpreter that keeps a frame's parameters, locals and
|
||||
operands in slots needs at most one slot for each unit. The reference's native engine
|
||||
needs at most eight bytes for each unit: a test runs modules made to keep as much in a
|
||||
frame as the largest body allows (locals held across a call, a new value held at every
|
||||
step, the results of calls held on the operand stack across a call, the largest function
|
||||
types), each recursing to the limit, on a stack of exactly that size, and shows a smaller
|
||||
one fails (`wai-wasmq/tests/engines.rs`). It gives each call nearly twice that.
|
||||
|
||||
A function of a few instructions recurses some 14 000 deep; a function at the largest
|
||||
body the profile takes, some 490.
|
||||
|
||||
### 4.4 The prepared module
|
||||
|
||||
A host MAY run a module with an engine that implements §4.2, §4.3 and §4.5 itself (the
|
||||
reference interpreter does). The reference's native engine does not, so it runs the
|
||||
**prepared module**: the module with every instruction kept byte for byte, and added
|
||||
|
||||
1. two mutable globals, after the module's own, exported as `__wasmq_fuel` (i64) and
|
||||
`__wasmq_stack` (i32);
|
||||
2. at the start of each run whose weight is not zero, the charge
|
||||
`global.get F; i64.const w; i64.sub; global.set F; global.get F; i64.const 0; i64.lt_s; if; unreachable; end`;
|
||||
3. before `memory.copy` and `memory.fill`, the same charge of the byte count, and before
|
||||
`memory.grow`, of 1024 times the page count, each taken from the operand with
|
||||
`local.tee` of one added `i32` local;
|
||||
4. around each `call` and `call_indirect`, with `w` the weight of the function they are
|
||||
in, `global.get S; i32.const w; i32.add; global.set S; global.get S; i32.const 8388608; i32.gt_u; if; unreachable; end`
|
||||
before it and `global.get S; i32.const w; i32.sub; global.set S` after it;
|
||||
5. after each instruction of §4.5, a call of an added function that returns its argument,
|
||||
or the canonical NaN if the argument is a NaN;
|
||||
|
||||
with every custom section dropped. The host sets `__wasmq_fuel` to the call's limit and
|
||||
`__wasmq_stack` to 0 before each call. When the prepared module traps at `unreachable`
|
||||
with `__wasmq_fuel` below zero, the fault is `fuel_exhausted`; with `__wasmq_stack` past
|
||||
2^23, `stack_exhausted`; otherwise the module's own `unreachable`.
|
||||
|
||||
The prepared module is one way to hold §4.2, §4.3 and §4.5, and its bytes are the
|
||||
reference's own: this text does not fix them, and no receipt names them. What a
|
||||
conforming runner must reproduce is what those sections define.
|
||||
|
||||
### 4.5 NaNs
|
||||
|
||||
The result of `f32` and `f64` `add`, `sub`, `mul`, `div`, `min`, `max`, `sqrt`, `ceil`,
|
||||
`floor`, `trunc` and `nearest`, of `f32.demote_f64` and of `f64.promote_f32` is, when it
|
||||
is a NaN, the canonical positive NaN (`0x7fc00000`, `0x7ff8000000000000`): WebAssembly
|
||||
3.0's deterministic profile. Every other instruction already has one result everywhere.
|
||||
A test shows that a module whose result depends on a NaN's bits reads what the host chose
|
||||
when neither the preparation nor the engine canonicalises, and the canonical NaN when
|
||||
either does (`wai-wasmq/tests/adversarial.rs`).
|
||||
|
||||
### 4.6 Engines
|
||||
|
||||
The reference runs every module on two engines and holds them to the same bytes:
|
||||
|
||||
- **native**: the repository's one pinned release of wasmtime, compiling the prepared
|
||||
module with Cranelift, with NaN canonicalisation on, relaxed vector instructions fixed
|
||||
and refused, vector instructions, tail calls and every proposal past Lime1 off, its
|
||||
own fuel on as a backstop under the profile's, and a run's calls made on one thread with
|
||||
a stack of the size §4.3 bounds;
|
||||
- **interpreter**: `wai-wasmq`'s own, which runs the module as written and implements
|
||||
§4.2, §4.3 and §4.5 itself, and which also runs on wasm32 (where the native engine
|
||||
does not run). It also runs the prepared module, with its own metering off, as a check
|
||||
of the preparation on the vectors; that use is held to none of §4.8's bounds.
|
||||
|
||||
`wai-quantum run ENVELOPE.wai --engine native|interpreter` chooses; the receipt is the
|
||||
same.
|
||||
|
||||
### 4.7 Memory
|
||||
|
||||
`memory.grow` past the module's declared maximum returns −1, on every engine. Within the
|
||||
maximum, it succeeds: a host that cannot grow the memory within the maximum (it has run
|
||||
out of memory) MUST stop the run and seal nothing (§6.3), because what it would seal
|
||||
would be its own condition, not the module's.
|
||||
|
||||
The modules of a bundle hold at most 4096 pages among them, by the maxima they declare
|
||||
(`W003`), so that a 32-bit host holds any bundle's memory: a limit for each module alone
|
||||
would leave the number of modules to decide which hosts can run an envelope.
|
||||
|
||||
### 4.8 What a run asks of its host
|
||||
|
||||
Fuel is the work of the modules. A run also asks work and memory of its host that no
|
||||
fuel counts: reading the program, its steps on the tableau, a fresh instance's memory,
|
||||
compiling its modules, the result. So that an envelope that opens on one host opens and
|
||||
finishes on every host, a 32-bit one among them, a reader bounds all of it from the
|
||||
bundle alone, before anything runs, and refuses past the bounds; nothing here differs by
|
||||
engine. A receipt shows part of what these bounds count, and §6.5 holds a job to that part
|
||||
(rules 29 to 32).
|
||||
|
||||
**Reading.** The program is read within these bounds, each checked as it is read, so that
|
||||
a short program cannot make a reader hold or do more than a host has before it is refused
|
||||
(`W016`):
|
||||
|
||||
| bound | |
|
||||
|---|---|
|
||||
| its text | 1 MiB (a reader holds some eighty bytes of tokens for each) |
|
||||
| nesting | 128 (`Q130`): a reader's stack. A statement at the top level is at depth 1; each statement in a block or a body, each expression a statement holds, each operand of an operator, what a bracket holds and each index's indexed value is one deeper than what holds it; operators group as they bind, so a chain of 127 is at the bound; an `else if` is at its `if`'s depth, at most 1024 to one `if`; and a call's body is read in its place, one deeper than the call |
|
||||
| qubits | 32 768 |
|
||||
| bits: the program's and its blocks' own together, any one value's, and those of any one array, its elements times each element's | 2^20 |
|
||||
| steps, its loops unrolled | 2^21 |
|
||||
| the bits its calls take and give, summed over its steps | 2^23 |
|
||||
| the work of reading: one for each statement and loop iteration, for each value worked out one and one more for each bit or element it makes, and one for each bit declared | 2^26 |
|
||||
|
||||
Past one, the reader's code is `Q323`, or `Q111` for the qubits. **A run ends**: the
|
||||
reader unrolls every loop, a `while` included, to the bounds it reads or is told
|
||||
(`@wai.max_iterations`), so every jump in a program's steps goes forward.
|
||||
|
||||
**Memory.** A run's shots times the bits a shot holds (all the program's bits, its blocks'
|
||||
own among them, though an outcome shows only the program's, §6.1) are at most 2^28
|
||||
(`W017`). With the most memory (§4.7), the largest
|
||||
envelope (§2.3), the most code (§3.2), the most qubits, bits and steps and the bits of
|
||||
calls, these leave a run within a 32-bit host's address space at every limit at once,
|
||||
which a test holds the reference to under wasm32 (`wai-wasmq/tests/sweep.rs`).
|
||||
|
||||
**Work.** A run's work is at most 2^42 operations on a word (`W017`), where, with `n` the
|
||||
program's qubits and `r` = ⌈`n`/32⌉ (at least 1) the words of a tableau's run for one
|
||||
qubit:
|
||||
|
||||
| for each shot | operations |
|
||||
|---|---|
|
||||
| its fresh tableau | 2·`n`·`r` |
|
||||
| each gate | `r` |
|
||||
| each measurement or reset | 2·`n`·`r` |
|
||||
| each callout | 4096 for each call of the module's (its export, `cabi_realloc` for each list argument, and `cabi_post_<export>` after a list result), 4 for each bit it takes and gives, and 1 |
|
||||
| each other step | 1 |
|
||||
|
||||
| for each instance, one for each shot, or one for the run when `state` is `job` | operations |
|
||||
|---|---|
|
||||
| each module, and each call of `wasmq-seed`, `init`, and two for each prior | 4096 |
|
||||
| each byte of each module | 1 |
|
||||
| each page of the memory a module starts with | 8192 |
|
||||
|
||||
| for the run | operations |
|
||||
|---|---|
|
||||
| each byte of each module, compiled | 131 072 |
|
||||
| each unit of the most fuel it may be given, `per_job` | 8 |
|
||||
|
||||
A random measurement rewrites the tableau's rows that hold an X at its qubit; a determined
|
||||
one's outcome is the sign of the product of up to `n` stabilizers, which the reference
|
||||
finds a machine word of rows at a time without copying the tableau. Either reads the
|
||||
tableau about once, which is the `n`·`r` of its weight. A page a module grows is paid for in fuel (§4.2), as
|
||||
a page it starts with is counted here. This is a bound on a host's effort from the bundle
|
||||
alone, not a measure of it: fuel is the profile's measure of the modules' work (§4.2).
|
||||
The reference was measured at a 64th of the limit, each kind of work alone, on x86_64
|
||||
Linux natively and under wasm32: at the limit it would take at most about three hours.
|
||||
|
||||
## 5. Callouts
|
||||
|
||||
### 5.1 In the program
|
||||
|
||||
A program declares each function it calls with `extern`, its arguments and its result
|
||||
written as types:
|
||||
|
||||
```qasm
|
||||
extern decode64(bit[4]) -> bit[9];
|
||||
bit[4] s;
|
||||
bit[9] corr;
|
||||
s = measure a;
|
||||
corr = decode64(s);
|
||||
if (corr[0]) x d[0];
|
||||
```
|
||||
|
||||
An argument is `bit[n]`, `uint[k]` or `int[k]` (k from 1 to 64); the result is `bit[n]`
|
||||
or nothing. An argument is a bit register or an integer known on reading (a constant, a
|
||||
loop's variable, an `input`); the result goes into a bit register, in a declaration or
|
||||
an assignment, and a later condition reads it. Calls inside `for` loops unroll; calls
|
||||
under `if` run only on the shots that take the branch.
|
||||
|
||||
**The gates.** This version runs the Clifford gates that take no angle: `id`, `x`, `y`,
|
||||
`z`, `h`, `s`, `sdg`, `sx`, `sxdg`, `cx`, `cy`, `cz` and `swap`, and gates a program
|
||||
defines from them, with measurement, reset and conditions on bits, on at most 32 768
|
||||
qubits. A program with any other gate is refused (`W016`), whatever its angle: `rz(pi/2)`
|
||||
acts as `s`, and is refused all the same, so that no reader decides in floating point
|
||||
which gate a program holds. With these gates a state is a stabilizer tableau and every
|
||||
step of a run is whole-number arithmetic (§6.1).
|
||||
|
||||
OpenQASM 3 schedules an `extern` call and lets it run concurrently with other
|
||||
operations. This profile fixes one schedule: a call runs when the program reaches it, in
|
||||
program order, and completes before the next statement; it is atomic. A program read
|
||||
with any other reader of this repository keeps refusing an `extern` call (`Q125`).
|
||||
|
||||
### 5.2 Lowering
|
||||
|
||||
A callout has one of two forms, by its widths, as [`quantum-wasmq.wit`](quantum-wasmq.wit)
|
||||
declares them:
|
||||
|
||||
- **scalar**, when every argument and the result have at most 64 bits: each lowers to one
|
||||
`i64` (WIT `u64`), bit `i` of the register bit `i` of the integer, an `int[k]`
|
||||
sign-extended. The export's type is `(i64, …) -> (i64)`, or `-> ()` with no result.
|
||||
- **list**, otherwise: each `bit[n]` argument lowers to a `list<u8>` (an `i32` pointer and
|
||||
an `i32` length) and the result to one `i32` that points to a pointer and a length;
|
||||
`uint[k]` and `int[k]` arguments stay `i64`. The list's bytes are `ceil(n/8)` long, bit
|
||||
`i` in byte `i/8` at bit `i % 8`, the rest of the last byte zero: the Component Model's
|
||||
canonical ABI.
|
||||
|
||||
A host reaches a module's memory only as its export named `memory`. A module with a
|
||||
list-form callout exports it, and `cabi_realloc` when the callout has a list argument
|
||||
(`W015`). The exports a host calls have exactly these types (`W012`):
|
||||
|
||||
| export | type |
|
||||
|---|---|
|
||||
| `cabi_realloc` | `(i32, i32, i32, i32) -> (i32)` |
|
||||
| `cabi_post_<export>` | `(i32) -> ()` |
|
||||
| `wasmq-seed` | `(i64) -> ()` |
|
||||
| `wasmq-prior` | `(i32, i32, i32) -> ()` |
|
||||
| `init` | `() -> ()` |
|
||||
|
||||
A host makes a callout in these steps, each guest call under the callout's one limit,
|
||||
its stack's weight starting at zero:
|
||||
|
||||
1. For each list argument, in order: it calls `cabi_realloc(0, 0, 1, len)`, charges
|
||||
`len` fuel, and writes the bytes at the address returned.
|
||||
2. It calls the export.
|
||||
3. For a scalar result: a bit set at or above the result's width ends the run.
|
||||
4. For a list result at address `r`: `r` is a multiple of 4; it reads a pointer and a
|
||||
length at `r`; the length is `ceil(n/8)`; it charges that many fuel and reads the
|
||||
bytes; no bit past the width is set in the last byte; then it calls
|
||||
`cabi_post_<export>(r)` if the module exports it.
|
||||
|
||||
A step that cannot be done as written (bytes that do not fit in the memory at an
|
||||
address, an address not a multiple of 4, another length, a bit past the width) ends the
|
||||
run with `bad_result`, with the fuel used up to that step.
|
||||
|
||||
### 5.3 Lifecycle
|
||||
|
||||
Instances are made at the start of a shot, before its first step, one for each module in
|
||||
the contract's order (each shot when `state` is `shot`, once at the first shot when it is
|
||||
`job`); a fault in making one ends the run there, and no later module's is made. When an
|
||||
instance is made, the host calls, in this order and each if the module exports it, each
|
||||
under the limit `per_instance`:
|
||||
|
||||
1. `wasmq-seed(seed: u64)`, with the run's seed, or, when `state` is `shot`, the shot's
|
||||
seed (§6.1);
|
||||
2. `wasmq-prior(index: u32, bytes: list<u8>)` for each of the module's priors, in the
|
||||
contract's order, the bytes passed as a list argument is (§5.2, step 1);
|
||||
3. `init()`.
|
||||
|
||||
A module with priors exports `wasmq-prior`, `cabi_realloc` and its memory (`W015`).
|
||||
|
||||
### 5.4 Priors
|
||||
|
||||
A prior is a parameter file a module reads: a code's parity checks, a target register, a
|
||||
noise model, a calibration. It travels in the envelope and is pinned in the contract, so
|
||||
a module is never run against another prior than the one it was packed with (`W014`).
|
||||
|
||||
## 6. A run and its receipt
|
||||
|
||||
### 6.1 Shots and outcomes
|
||||
|
||||
A run goes shot by shot, in order. Each shot starts from `|0…0⟩` with every bit 0, and
|
||||
has a **stream**: the outputs of SplitMix64 from the state `s XOR 0x51574d31`, where `s`,
|
||||
the shot's seed, is SplitMix64's output for the state
|
||||
`seed + (shot + 1) · 0x9e3779b97f4a7c15` (all sums modulo 2^64).
|
||||
|
||||
A measurement of a qubit in the computational basis has an outcome that is determined by
|
||||
the state, or is 0 or 1 with equal chance; with §5.1's gates there is no other case. A
|
||||
determined outcome is the outcome, and takes nothing from the stream. A random outcome
|
||||
takes the stream's next value `x`, and is 1 when `x < 2^63`. A `reset` measures its qubit
|
||||
the same way, without writing a bit, and applies `x` to it when the outcome is 1; a
|
||||
reset of a qubit whose outcome is determined takes nothing from the stream.
|
||||
|
||||
A shot's outcome is its program's bits, `n` of them: every bit it declares at its top
|
||||
level, whether or not anything writes it, numbered in the order the program declares them
|
||||
(its first declared bit is bit 0, a register's bits in their order) and written bit
|
||||
`n − 1` first; the counts sum the shots that read each outcome. A bit that a block or a
|
||||
subroutine declares is its own (`Q322`): the steps read and write it, and no outcome holds
|
||||
it. Each measurement names the bit it writes: a `measure` with no target bit is refused
|
||||
in a program that calls externs (`Q324`), since its outcome is the bits it declares. A
|
||||
program that measures nothing has its bits as its outcome all the same, those its calls
|
||||
write and 0 for each bit nothing writes: no qubit is read for it.
|
||||
|
||||
### 6.2 Faults
|
||||
|
||||
A run stops at the first fault, seals what it ran, and reports:
|
||||
|
||||
| reason | |
|
||||
|---|---|
|
||||
| `fuel_exhausted` | a charge took the fuel below zero (§4.2); `budget` says whose limit it was: `call`, `instance`, or `run` when the limit was what was left of the run's |
|
||||
| `stack_exhausted` | §4.3 |
|
||||
| `unreachable`, `memory_out_of_bounds`, `table_out_of_bounds`, `indirect_call_null`, `indirect_call_type`, `integer_divide_by_zero`, `integer_overflow`, `invalid_conversion_to_integer` | the module trapped (WebAssembly 3.0, §4 Execution) |
|
||||
| `bad_result` | §5.2 |
|
||||
|
||||
A fault has the members `reason`, `shot`, `phase` (`seed`, `prior`, `init` or `call`),
|
||||
`module` (its name), `fuel` (what the stopped call used), `callout` (the `extern`'s
|
||||
name) when the phase is `call`, and `budget` when the reason is `fuel_exhausted`, and no
|
||||
other. The counts are of the shots that finished. A fault receipt is a receipt like any
|
||||
other: it verifies, and running the envelope again reproduces it.
|
||||
|
||||
### 6.3 What is never sealed
|
||||
|
||||
A host that could not run the bundle seals nothing: a refused envelope (§2.3, §3.3), a
|
||||
host that cannot hold the memory's maximum or grow within it (§4.7), an engine that
|
||||
fails for its own reasons. These are the host's condition, not the bundle's, and a
|
||||
receipt that recorded them would differ by host. Nothing a bundle holds can lead here:
|
||||
what a bundle could cause is refused on reading (§2.3, §4.7, §4.8) or sealed as a fault.
|
||||
|
||||
### 6.4 The result
|
||||
|
||||
The job body is the engine's (`engine::job`), with exactly four members:
|
||||
`{ "status", "method", "request", "result" }`. The request is
|
||||
`{ "wasmq": <the contract>, "envelope_blake3" }`. `status` is `done` when the result's
|
||||
`status` is `ok` and `fault` otherwise; `method` is the result's. The receipt signs the
|
||||
request and the result, as [the provider protocol's §8.2](quantum-providers.md#82-how-it-is-sealed-and-how-a-job-is-read)
|
||||
seals every job; `status` and `method` only repeat what is signed. They are the host's
|
||||
word, unsealed: a verdict takes nothing from them, and a check notes where they, or any
|
||||
other member of the body, differ from what is sealed (§6.5).
|
||||
|
||||
The result has exactly these members:
|
||||
|
||||
| member | |
|
||||
|---|---|
|
||||
| `format` | `"wai.quantum.wasmq.result/1"` |
|
||||
| `profile` | `"wai.quantum.wasmq/1"` |
|
||||
| `status` | `ok`, or `fault` when the run stopped |
|
||||
| `method`, `qubits`, `shots`, `seed` | the contract's method, the program's qubits (§2.2), the contract's shots and seed |
|
||||
| `shots_run` | the shots that finished |
|
||||
| `counts` | outcome to shots (§6.1) |
|
||||
| `callouts` | the callouts made, one that stopped the run among them |
|
||||
| `fuel` | `{ "used", "instances", "budget": { "per_call", "per_job", "per_instance" }, "callouts": { name: { "calls", "fuel", "max" } } }`: all the fuel used, the part of it lifecycle calls used, the contract's budgets, and for each `extern` the run called, its calls, their fuel and the most one of them used (an `extern` it did not call has no entry) |
|
||||
| `modules` | for each, in the contract's order: `{ "name", "blake3" }` |
|
||||
| `transcript_blake3` | BLAKE3 over `wai:wasmq-transcript\x01` and, for each callout that returned, in order: its shot (u64), the index of its `extern` (u32), its input's length (u32) and bytes, its output's length (u32) and bytes, and its fuel (u64), little-endian, the input the arguments' bits in order and the output the result's, packed as a list's bytes are (§5.2); after a fault, the bytes `fault`, the shot (u64), the reason's bytes and the fault's fuel (u64) |
|
||||
| `fault` | §6.2, when the run stopped |
|
||||
| `accuracy` | `{ "class": "exact" }` |
|
||||
| `energy` | `{ "unmetered": "the runner reads no energy meter; fuel is the profile's measure of work" }` |
|
||||
| `receipt` | the engine's job receipt (`engine::receipt`): Ed25519 over BLAKE3 of the request and the result in RFC 8785 form |
|
||||
|
||||
**Result-equivalence.** Every conforming runner, on every host and every engine, gives
|
||||
an envelope the same result: the same bytes in its RFC 8785 form, the receipt aside. So
|
||||
the receipt's digest is the same everywhere, and under one key the whole job is.
|
||||
|
||||
### 6.5 Verifying
|
||||
|
||||
A wasmQ job is a job like any other: every verifier of the engine's job receipts reads it
|
||||
and judges it by [the provider protocol's §8.4](quantum-providers.md#84-what-a-verifier-checks),
|
||||
and so gives it one verdict, wherever it is checked. `wai-quantum verify` (and its
|
||||
`--json` and `--lines`), the job service's `POST /v1/verify`, both MCP servers given the
|
||||
job's text, the Python package, the desktop app and a page read the job from its text as
|
||||
§8.2 reads every job's, so its seal and its numbers are held as every receipt's are. A
|
||||
surface given the job already parsed (a view, an MCP server given its members) cannot see
|
||||
what parsing loses, as the provider protocol's §9 says, and gives every other reason; the
|
||||
Python package judges a dict as the text it writes for it. A result
|
||||
whose `format` is `wai.quantum.wasmq.result/1` is a wasmQ job's, and §8.4 adds one reason
|
||||
for it, `wasmq_form`: the job breaks a rule below. Only what is sealed (the request, and
|
||||
the result less its receipt) and the form of its seal decide it. A signature shows that a key sealed a job and says
|
||||
nothing of what the job holds, so without the envelope to run again these rules are what
|
||||
hold a result to its contract and to itself: a key can seal any result of this form, and
|
||||
only running the envelope again shows that a result is the one it gives.
|
||||
|
||||
In these rules a number's value is the double it reads as (§8.2). A *count* is a number
|
||||
whose value is a whole number from 0 to 2^53 − 1, however it is written (`1`, `1.0` and
|
||||
`1e0` are one count, sealed as one); "at most" and "equals" compare counts, and a rule on
|
||||
a count fails when the number is not one. A *digest* is a string of 64 lowercase
|
||||
hexadecimal digits. Two values are *equal* as JSON values are, numbers by their value and
|
||||
an object's members in any order. "Exactly the members" means every one named and no
|
||||
other; a value that is not an object has none. A member is *present* when its object names
|
||||
it, whatever its value, `null` among them: "has no `fault`" and "has a `callout`" read
|
||||
so. A list or a map named below that is not an
|
||||
array or an object is read as an empty one, after its own rule has failed. `C` is the
|
||||
request's `wasmq` (the contract), `run` is `C`'s `run`, `r` is the result and `F` is
|
||||
`r`'s `fuel`. *The budget* `per_call`, `per_job` or `per_instance` is that member of `run`'s
|
||||
`fuel`. The job breaks the form when any of these fails:
|
||||
|
||||
1. No number in the request, or in the result less its receipt, has a magnitude past
|
||||
2^53 − 1.
|
||||
2. The request has exactly the members `wasmq` and `envelope_blake3`, and
|
||||
`envelope_blake3` is a digest.
|
||||
3. `C` has exactly the members §2.2 gives: `profile`, `program`, `modules`, `callouts`
|
||||
and `run`; its `program` exactly `blake3`, `bytes` and `inputs`; `run` exactly
|
||||
`shots`, `seed`, `method`, `state` and `fuel`; and `run`'s `fuel` exactly `per_call`,
|
||||
`per_job` and `per_instance`.
|
||||
4. `C`'s `profile` is `wai.quantum.wasmq/1`.
|
||||
5. The program's `blake3` is a digest; its `bytes` a count from 1 to 2^20; its `inputs` an
|
||||
object each of whose values is a number whose value is whole and at most 2^53 − 1 in
|
||||
size.
|
||||
6. `C`'s `modules` is an array that is not empty. Each module has exactly the members
|
||||
`name`, `blake3`, `bytes` and `priors`: `name` a string, `blake3` a digest, `bytes` a
|
||||
count of at least 1, and `priors` an array each of whose priors has exactly the members
|
||||
`name` (a string), `blake3` (a digest) and `bytes` (a count). The modules' `bytes` that
|
||||
are counts add up to at most 2^19, so each is at most that; rule 31 bounds a prior's.
|
||||
7. `C`'s `callouts` is an array that is not empty. Each callout has exactly the members
|
||||
`extern`, `module` and `export`: `extern` and `export` strings, and `module` a count
|
||||
less than the number of modules. No two callouts have the same `extern`, and each
|
||||
module's index is the `module` of a callout.
|
||||
8. `run`'s `shots` is a count from 1 to 2^20, its `seed` a count, its `method`
|
||||
`stabilizer`, its `state` `shot` or `job`, and each of its fuel's three budgets a count,
|
||||
`per_call` and `per_instance` each of at most 2^39 (§4.8; rule 30 holds `per_job` to
|
||||
less).
|
||||
9. `r` has exactly the members of §6.4 (`format`, `profile`, `status`, `method`,
|
||||
`qubits`, `shots`, `shots_run`, `seed`, `counts`, `callouts`, `fuel`, `modules`,
|
||||
`transcript_blake3`, `accuracy`, `energy` and `receipt`), and may have `fault`.
|
||||
10. The receipt is an object whose `canon` is `rfc8785`: the first form (§8.2) is older than
|
||||
this profile, and no host sealed a wasmQ job in it.
|
||||
11. `r`'s `format` is `wai.quantum.wasmq.result/1`, its `profile` `wai.quantum.wasmq/1`,
|
||||
its `accuracy` `{ "class": "exact" }` and its `energy` the one §6.4 gives; and its
|
||||
`method`, `shots` and `seed` equal `run`'s.
|
||||
12. `r`'s `qubits` is a count from 1 to 2^15 (a program declares a qubit at least, `Q100`),
|
||||
and its `transcript_blake3` a digest.
|
||||
13. `F` has exactly the members `used`, `instances`, `budget` and `callouts`; its `budget`
|
||||
equals `run`'s `fuel`; and `used` is a count of at most the budget `per_job` (0 when
|
||||
that is not a count).
|
||||
14. `F`'s `callouts` is an object. Each of its members is named by the `extern` of one of
|
||||
`C`'s callouts, and has exactly the members `calls`, `fuel` and `max`: `calls` a count
|
||||
of at least 1; `max` a count of at most the budget `per_call` (0 when that is not a
|
||||
count) and at most its own `fuel`; and `fuel` a count (rule 20 bounds it by its calls
|
||||
and their `max`).
|
||||
15. `F`'s `instances` and the `fuel` of each member of `F`'s `callouts`, added, are `F`'s
|
||||
`used`; and the `calls` of each member, added, are `r`'s `callouts`. Each of them is a
|
||||
count.
|
||||
16. `r`'s `modules` has as many entries as `C`'s, each with exactly the members `name`
|
||||
and `blake3`, its `blake3` a digest, and its `name` and `blake3` equal to those of
|
||||
`C`'s module at its index.
|
||||
17. `F`'s `instances` is a count of at most M × S × the budget `per_instance` (0 when that
|
||||
is not a count): S is the sum, over `C`'s modules, of 2 and the number of its priors
|
||||
(each instance's seed, its init and each prior, §4.2, §5.3); M, the instances made, is 1
|
||||
when `run`'s `state` is `job`, whatever the status; for any other `state` it is `r`'s
|
||||
`shots_run` (0 when it is not a count), plus 1 when `r`'s `status` is `fault`.
|
||||
18. When `r`'s `status` is `ok`: `r` has no `fault`, and its `shots_run` equals its
|
||||
`shots`. When it is `fault`: the fault has exactly the members `reason`, `shot`,
|
||||
`phase`, `module` and `fuel`, and may have `callout` and `budget`; `reason` is one §6.2
|
||||
names; `shots_run` is less than `shots`; `shot` equals `shots_run`; `phase` is `seed`,
|
||||
`prior`, `init` or `call`; `module` equals the `name` of one of `C`'s modules; `fuel`
|
||||
is a count, and in a phase other than `call` at most the budget `per_instance` (0 when
|
||||
that is not a count: a call's is held by its callout's `max`, below, and rule 14; rules
|
||||
20 and 25, with rule 15, hold either within `F`'s `used`); it has a
|
||||
`callout` exactly when its phase is `call`, and that is the `extern` of one of `C`'s
|
||||
callouts that names a member of `F`'s `callouts` whose `max` is at least the fault's
|
||||
`fuel` (the call that stopped is one of the calls made, §6.4); and it has
|
||||
a `budget` exactly when its reason is `fuel_exhausted`, and that is `run`, or `call` in
|
||||
a call and `instance` otherwise. Any other `status` breaks the form.
|
||||
19. `r`'s `counts` is an object; each of its names holds only `0` and `1` (the empty name
|
||||
among them), all of one length; each of its values is a count of at least 1; and its values, added, are `r`'s
|
||||
`shots_run`.
|
||||
|
||||
Rules 20 to 35 tie members to each other, as the writer does. In them *the fault* is `r`'s
|
||||
`fault` when `r`'s `status` is `fault` and that is an object, and there is none
|
||||
otherwise; a rule about the fault holds when there is none. A *call's fault* is a fault
|
||||
whose `phase` is `call`, and a *lifecycle fault* one that has a `phase` other than `call`.
|
||||
|
||||
20. For each member of `F`'s `callouts`, let `s` be 1 when the fault is a call's fault
|
||||
whose `callout` is that member's name, and 0 otherwise, and `e` the fault's `fuel` when
|
||||
`s` is 1 (0 when that is not a count) and 0 otherwise. `T`, its `fuel` less `e`, the fuel
|
||||
of its calls that returned, is not less than 0, and is from `k` to `k` × `max`, where `k`
|
||||
is its `calls` less `s` (0 when that is less than 0): the call that stopped used the
|
||||
fault's fuel, and each call that returned used at least 1 (§4.2: entering a function
|
||||
weighs 1) and at most the most one call used. When `max` is more than `e`, the most was a
|
||||
call's that returned, and each of the others used at least 1, so `T` is also at least
|
||||
`max` + `k` − 1. `calls`, `fuel` and `max` are counts.
|
||||
21. `F`'s `instances` is a count of at least `W` × `P` + `E`, the least that making the
|
||||
instances took outside a stopped call (§5.3: a shot's instances are made module by
|
||||
module in `C`'s order, each one's `wasmq-seed`, then its priors, then its `init`; passing
|
||||
a prior calls `cabi_realloc`, at least 2 since it returns a value, then charges the
|
||||
prior's bytes, then calls `wasmq-prior`, at least 1, §4.2, §5.2):
|
||||
- `P`, what each set of instances took at least: the sum, over every prior of every one
|
||||
of `C`'s modules, of 3 and the prior's `bytes` (0 when that is not a count), and 1
|
||||
more when the fault is a lifecycle fault in phase `seed` or `init`: its module exports
|
||||
that function, and each set called it;
|
||||
- `W`, the sets made whole: `r`'s `shots_run` (0 when that is not a count), plus 1 when
|
||||
there is a call's fault; when `run`'s `state` is `job` it is that or 1, whichever is
|
||||
less;
|
||||
- `E`, when the fault is a lifecycle fault, what the set it stopped took at least: the
|
||||
same sum, of 3 and its `bytes`, over the priors of each module before the one the fault
|
||||
names (the first of `C`'s modules with that `name`), and, when its phase is `init`, over
|
||||
that module's own; 0 otherwise, and when no module has that `name`.
|
||||
22. A call's fault's `module` equals the `name` of `C`'s module whose index is the
|
||||
`module` of each of `C`'s callouts whose `extern` is the fault's `callout` (rule 7
|
||||
allows one): a call runs in its callout's module (§2.2, §6.2). It fails when there is
|
||||
no such callout, or no such module.
|
||||
23. A fault whose `phase` is `prior` has as its `module` the `name` of one of `C`'s
|
||||
modules whose `priors` is not empty: a prior is passed only to a module that has one
|
||||
(§5.3).
|
||||
24. A fault whose `reason` is `bad_result` has the `phase` `call` or `prior`: only these
|
||||
pass bytes or take a result (§5.2).
|
||||
25. A lifecycle fault's `fuel` is a count, and `F`'s `instances` (a count) is at least it
|
||||
added to rule 21's `W` × `P` + `E`: what the stopped lifecycle call used is part of the
|
||||
instances' fuel, beside what the calls before it took.
|
||||
26. When `run`'s `state` is `job`, a lifecycle fault's `shot` is the count 0: the run's
|
||||
one instance of each module is made at the first shot (§5.3).
|
||||
27. A lifecycle fault whose `shot` is the count 0 comes with `r`'s `callouts` the count 0:
|
||||
the first shot's instances are made before its first step (§5.3). (Rule 32 holds this
|
||||
too, so rule 27 is never broken alone.)
|
||||
28. A fault whose `reason` is `fuel_exhausted` used its whole limit (§4.2). When its
|
||||
`budget` is `call`, its `fuel` is a count equal to the budget `per_call`; when it is
|
||||
`instance`, to the budget `per_instance` (each 0 when it is not a count). When it is
|
||||
`run`, `F`'s `used` is a count equal to the budget `per_job` (a count), and the fault's
|
||||
`fuel` is a count, less than its own limit: the budget `per_call` in a call's fault, and
|
||||
the budget `per_instance` in a lifecycle fault, each read as 0 when it is not a count (a
|
||||
fault with no `phase` has no limit here, and breaks rule 18): the run's budget was the
|
||||
limit only because less of it was left than the call's own.
|
||||
29. When `r`'s `counts` has a name, the length of the longest, in characters (Unicode code
|
||||
points), is at most 2^20, and `run`'s `shots` (0 when that is not a count) times that
|
||||
length at most 2^28: a program holds at most 2^20 bits, and a run's shots times them are
|
||||
at most 2^28 (§4.8). (Rule 19 holds each name to `0` and `1`, one byte each; a verifier
|
||||
counts a name that breaks it in characters too.)
|
||||
30. The part of a run's work that a receipt shows is at most 2^42 (§4.8):
|
||||
`S` × 2·`n`·`w` + `I` × Σ (4096 × (1 + 2 × `p`) + `b`) + 131072 × Σ `b` + 4097 × `K` + 8 ×
|
||||
the budget `per_job`. `S` is `run`'s `shots`; `n` is `r`'s `qubits`; `w` is ⌈`n`/32⌉, or
|
||||
1 when that is 0; `I` is 1 when `run`'s `state` is `job` and `S` otherwise; each sum is
|
||||
over `C`'s modules, `p` a module's number of priors and `b` its `bytes`; and `K` is `r`'s
|
||||
`callouts`. Every number here that is not a count is read as 0. The host's work is at
|
||||
least this: each shot's fresh tableau, each instance's module and its calls of
|
||||
`wasmq-prior` and of `cabi_realloc` for it, the run's compiling, each call made (its
|
||||
module's part, 4096, and its step, 1: a callout's step is counted in each shot whether or
|
||||
not it runs) and the run's fuel.
|
||||
31. The envelope the contract names is at most 2^27 bytes (§2.3): 20 bytes of magic and
|
||||
lengths, its manifest (§2.1's members, in that order and with no space: 192 bytes and the
|
||||
decimal digits of its `qubits`, `r`'s, and its `shots` and `seed`, `run`'s, each read as 0
|
||||
when it is not a count), `C` in RFC 8785 form (§2.2; no bytes when the request has no
|
||||
`wasmq`), and its frames (the program's `bytes`, each module's `bytes` and each prior's
|
||||
`bytes`, each 0 when it is not a count), added, are at most 2^27.
|
||||
32. `r`'s `callouts` is at most 2^21 × `H` (each 0 when it is not a count), where `H`, the
|
||||
shots that ran steps, is `r`'s `shots_run` and 1 more when there is a call's fault: a
|
||||
shot runs each of its steps at most once, every jump going forward, and a program has
|
||||
at most 2^21 steps (§4.8), each call one of them.
|
||||
33. Each prior passed whole fits within one lifecycle call's limit: 3 and its `bytes` (0 when
|
||||
that is not a count) are at most the budget `per_instance` (0 when that is not a count),
|
||||
for every prior of every one of `C`'s modules when `W` (rule 21) is at least 1, and for
|
||||
each prior `E` counts otherwise. Passing a prior is one stretch under one limit:
|
||||
`cabi_realloc`, its bytes and `wasmq-prior` (§5.2, §5.3).
|
||||
34. A fault's `fuel`, when it is a count, is at least what its `reason` shows was charged
|
||||
(§4.2), when it has one: 1 for every reason but `fuel_exhausted`, one §6.2 does not name
|
||||
or `null` among them (a call stops any other way only after its entry was charged); 2
|
||||
for `bad_result` (a value came back: the entry, and an instruction that made it); and 788
|
||||
for `stack_exhausted`. A frame weighs at most
|
||||
576 + 4096 + 2^8 + 2^14 = 21 312 (§3.2, §4.3), so the stack's weight passes 2^23 only at
|
||||
a call in the 394th frame entered or deeper, and each frame entered was charged at least
|
||||
2: its entry, and the run that holds its call.
|
||||
35. When no call returned, the transcript is what §6.4 gives such a run: when `r`'s
|
||||
`callouts` is 0, or 1 and the fault is a call's fault (each a count), `r`'s
|
||||
`transcript_blake3` is BLAKE3 over the bytes `wai:wasmq-transcript` and the byte 0x01
|
||||
and, when there
|
||||
is a fault, the bytes `fault`, the fault's `shot` (u64), its `reason`'s UTF-8 bytes and
|
||||
its `fuel` (u64), little-endian (`shot` and `fuel` each 0 when it is not a count, and
|
||||
`reason` no bytes when it is not a string).
|
||||
|
||||
**What the rules leave free, and why.** What else the writer fixes, the rules leave free,
|
||||
each for the reason given, and only running the envelope again (`--bundle`) holds a job to
|
||||
it:
|
||||
|
||||
- the `transcript_blake3`'s value once a call returned: it digests each call's input and
|
||||
output, which no receipt holds (rule 35 holds it when none returned); and each `blake3`
|
||||
against the bytes it pins, which no receipt holds;
|
||||
- `r`'s `qubits` within rule 12, the outcomes' length within rule 29, and the number of
|
||||
callouts within rules 30 and 32, against the program: its text is not sealed, only its
|
||||
digest and length, so how many qubits and bits it declares, and how many calls each shot
|
||||
makes, are its own;
|
||||
- which shot read which outcome, and the counts' spread: only the run shows them;
|
||||
- whether a module exports `wasmq-seed` or `init`, but for the one a fault in that phase
|
||||
names (rule 21): only its code shows it. So a fault in phase `seed` or `init` may name any
|
||||
module;
|
||||
- the instances' fuel within rules 17, 21 and 25: what each lifecycle call used past its
|
||||
least, and how far the module a fault names got, are its code's;
|
||||
- the fuel of each call within rules 14, 18, 20, 28 and 34, and a fault's fuel within rules
|
||||
18, 20, 21, 25, 28 and 34: where in its work a call traps, and how many bytes its arguments
|
||||
pass, are its module's and its program's;
|
||||
- a trap's `reason` against its phase: any guest call can trap any way, and only
|
||||
`bad_result` is the host's (rule 24);
|
||||
- the rest of §4.8's bounds (the steps of a shot past rule 32's count, the gates and
|
||||
measurements, the bits of calls, the pages a module starts with, the program's reading):
|
||||
each counts what only the program or the modules hold, so rules 29 to 32 take what a
|
||||
receipt shows, and a job a writer can write never breaks them;
|
||||
- the least length of a program and of a module, and the spelling of an `extern`: a program
|
||||
that packs declares an `extern`, a qubit and a call, a module that packs has a type, a
|
||||
function, an export and its code, and an `extern` is a name the reader reads, its letters
|
||||
any of Unicode's. So each has a least length, and an `extern` a form, that a rule could
|
||||
state; but they follow from the grammar, WebAssembly's binary format and Unicode's tables
|
||||
rather than from anything a run does, bound nothing a host does, and a rule at them would
|
||||
hold every verifier to those tables. Rules 5, 6 and 7 hold the program's and a module's
|
||||
`bytes` to at least 1 and an `extern` to a string, and leave the rest free.
|
||||
|
||||
Beside §8.4's reasons a verifier of the engine states, for a wasmQ job, `wasmq`:
|
||||
`outcome`, the sealed result's `status`; `problems`, what breaks each rule the job breaks,
|
||||
in words, each naming its rule first (`rule 19: ...`), the first 64 of them and then how
|
||||
many more; and `notes`, where the host's unsealed words
|
||||
differ from what is sealed or are missing ("the host's unsealed status says `done`; the
|
||||
sealed result says `fault`"). A note is no part of the verdict: the verdict is the sealed
|
||||
content's alone, so that every surface that checks a job gives the same one.
|
||||
|
||||
`wai-quantum verify JOB.json` prints the receipt's check, the outcome and each problem and
|
||||
note; `--json` gives the verdict as JSON. `--lines` reads a file of one job a line, each
|
||||
line on its own as a job's text (a line that is not UTF-8, or blank, is that line's
|
||||
`unreadable`; the newline that ends the file ends its last line), and gives one verdict a
|
||||
line, each a job's whatever its kind; a file with no line is refused. A job found
|
||||
unreadable, no job, with no receipt, or longer than the surface reads (`too_large`) is
|
||||
reported alone (§8.4), whatever kind of job it says it is: `verify` says that its form was
|
||||
not judged, and runs no envelope for it. `verify` reads at most 384 MiB and 2^22 values
|
||||
(§8.4), more than any job holds, in about 1 GiB of memory at most on every host: a file past the
|
||||
bytes is `too_large` by its size, before it is read, and one past the values once read,
|
||||
before it is parsed; a file of lines past the bytes is refused, and a line past the values
|
||||
is that line's `too_large`. With `--bundle ENVELOPE.wai` it also checks
|
||||
that the envelope is the one the receipt binds (its BLAKE3 is the request's
|
||||
`envelope_blake3`, and its contract is `C`), and runs it again here: the result must be
|
||||
the same, byte for byte, the receipt aside; with `--json` the verdict then also says
|
||||
`bundle` and `reproduced`, and is valid only when both hold. A wasmQ job carries no
|
||||
history, so `--history` is refused for one.
|
||||
|
||||
## 7. On hardware
|
||||
|
||||
**The bring-your-own-quantum boundary is unchanged.** WAI Quantum never pays for or
|
||||
resells hardware time; a person's providers speak `wai.quantum.provider/1`
|
||||
([quantum-providers](quantum-providers.md)), whose program is a fixed sequence of native
|
||||
gates measured at the end. A wasmQ bundle calls its modules between gates, which that
|
||||
protocol does not carry, so `run ENVELOPE.wai --provider NAME` is refused, and the hosted
|
||||
job service takes no bundle. A wasmQ run simulates the quantum part on this machine.
|
||||
|
||||
**Nothing here has run a module beside a quantum processor.** This repository has run
|
||||
wasmQ modules only on the hosts its tests name. What holds for a module on a machine
|
||||
that runs classical code between gates, and what does not:
|
||||
|
||||
- A scalar-form module (§5.2) is a function of integers that imports nothing. Whether a
|
||||
given machine takes it is that machine's to say.
|
||||
- The quantum part's measurements on hardware are not reproducible, so a hardware run
|
||||
has no single result to reproduce. Its classical part does: given the inputs each call
|
||||
received, a module gives the same outputs and the same fuel on every host, so a
|
||||
record of the calls (`run --transcript`) replays through the modules alone and is
|
||||
checked call by call (`run ENVELOPE.wai --replay TRANSCRIPT`), each of a shot the run
|
||||
has, in the order of its shots. Each call shows only itself; that a record is the whole
|
||||
of a run's shows in its digest, which a replay states and the receipt of a run that ended
|
||||
`ok` seals as `transcript_blake3`. A machine that ran the module would have to report
|
||||
those inputs and outputs for anyone to check them.
|
||||
- Fuel is not time (§4.2). A real-time deadline is the machine's; the profile states
|
||||
the work.
|
||||
|
||||
## 8. Reference modules
|
||||
|
||||
Two modules of record are built from code the engine already has, for
|
||||
`wasm32-unknown-unknown` with Lime1 (`wai-wasmq/modules/`, `build.sh`), and committed in
|
||||
[`../quantum-conformance/wasmq/modules/`](../quantum-conformance/wasmq/modules/) with
|
||||
the digests of the sources that made them. rustc's wasm32 output depends on the host it
|
||||
runs on, so they are built on x86_64 Linux, where CI rebuilds them and compares.
|
||||
|
||||
### 8.1 The qLDPC decoder
|
||||
|
||||
`quantum_qec`'s decoders: union-find matching for a code whose qubits each lie in at most
|
||||
two checks (the surface code), Relay-BP in fixed-point arithmetic otherwise (the
|
||||
bivariate-bicycle codes), as the engine itself chooses. Prior 0 is a code's parity
|
||||
checks in `CssCode::check_matrix_bytes`'s form. Exports: `decode` (list) and `decode64`
|
||||
(scalar). Tests hold every result to the same functions compiled natively, on every
|
||||
weight-two error of the distance-3 surface code and on random errors of the [[72,12]]
|
||||
bivariate-bicycle code (`CssCode::gross()`), and run memory rounds of the distance-3 and
|
||||
distance-5 surface codes and of that code (a 129-qubit circuit) with the decoder called
|
||||
between the syndrome and the correction, each shot ending in the code, on every engine
|
||||
with the same bytes.
|
||||
|
||||
### 8.2 The atom rearrangement planner
|
||||
|
||||
`quantum_atom::solve`, an exact Hungarian assignment of loaded atoms to target sites.
|
||||
Prior 0 is the target register in `target_bytes`'s form. Exports: `plan` (list) and
|
||||
`plan64` (scalar). A circuit loads each trap with probability ½, measures the occupancy,
|
||||
calls the planner, applies its moves and reads the array: every shot whose plan is
|
||||
feasible fills the target, and atoms are moved, never made or lost.
|
||||
|
||||
## 9. Conformance
|
||||
|
||||
[`../quantum-conformance/wasmq/`](../quantum-conformance/wasmq/) holds:
|
||||
|
||||
- `envelopes/`: envelopes, each with the result it MUST give on every engine and every
|
||||
host (`vectors.json`, `runs`): the status, the fault, the fuel, the transcript's
|
||||
digest, the result's digest, the receipt's digest and, under the vectors' key, the
|
||||
whole job's digest. Among them are runs that end in every fault reason §6.2 names, in
|
||||
every phase and of every budget; callouts of the list form, with a `cabi_post` call and
|
||||
with each way a list result is not one; a signed argument; two modules made in order; a
|
||||
program that declares no qubit and names physical ones, its bits in two registers; a
|
||||
program that measures nothing; one with bits nothing writes, and one whose block holds a
|
||||
bit of its own, which pin §6.1's outcome; and a program whose resets and measurements pin
|
||||
§6.1's stream;
|
||||
- `refuse/`: modules and envelopes a runner MUST refuse, each with its code
|
||||
(`vectors.json`, `refuse`), at least one for every code of §3.3, each one defect away
|
||||
from a module or an envelope that is accepted; the modules also as WebAssembly text
|
||||
where they have one. An envelope past §2.3's size has no vector, for its size: a test
|
||||
in `wai-wasmq/tests/sweep.rs` makes one;
|
||||
- `modules/`: the modules of record (§8).
|
||||
|
||||
Six wasmQ jobs the command line sealed are among the job receipts of
|
||||
[`../quantum-conformance/receipts/`](../quantum-conformance/receipts/) (`jobs/cli-wasmq-*`):
|
||||
a run of the surface-code round, one of a single instance for the whole run, and faults in
|
||||
a call, of the run's budget, in an instance's init and in a prior. Beside them are jobs
|
||||
crafted from them, sealed again, each of rules 2 to 31 broken alone by one at least, so the
|
||||
two verifiers of that corpus, which share no code, are held to each other on `wasmq_form`
|
||||
and on the rules each states broken, and on every change of one member of each of the six.
|
||||
|
||||
`wasmq_vectors verify wai/quantum-conformance/wasmq` checks them on every engine of the
|
||||
build and prints a digest of what it computed (each run's job and each refusal's code),
|
||||
the same on every host that conforms.
|
||||
|
||||
## 10. Versioning
|
||||
|
||||
`wai.quantum.wasmq/1` is this text. A change to anything that moves a result's bytes or
|
||||
a module's fuel (the weights, the runs, the stack's weights, the lowering, the stream,
|
||||
the transcript, the result's members) is a new profile version, and a receipt names the
|
||||
version it was made under.
|
||||
|
||||
This version leaves out, and a later one may add under a name of its own:
|
||||
|
||||
- gates that take an angle and gates outside the Clifford group, which need a method
|
||||
whose arithmetic this text would have to fix bit for bit. The state-vector method,
|
||||
which the engine runs in floating point, is not part of this version for that reason:
|
||||
`stabilizer` is its one method (§2.2);
|
||||
- floating-point arguments and results of a callout;
|
||||
- noise, and observables other than the counts.
|
||||
61
wai/extensions/quantum-wasmq.wit
Normal file
61
wai/extensions/quantum-wasmq.wit
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
// The WebAssembly interface of a wasmQ module (quantum-wasmq.md).
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// A wasmQ module is a core WebAssembly module (quantum-wasmq.md §3). Its exports are the
|
||||
// Component Model's canonical lowering of the functions below, so a component host can
|
||||
// wrap it, and a host of this profile calls it directly. An OpenQASM 3 `extern` lowers to
|
||||
// one of two forms (§5.2): scalar, every argument and the result at most 64 bits, each a
|
||||
// u64 or s64; or list, each `bit[n]` a list<u8>, the lowest bit first. A module with a
|
||||
// list-form export or a prior exports its memory as `memory`, where a host reaches it.
|
||||
//
|
||||
// The direction is the hardware's: the quantum program calls the module. A module
|
||||
// imports nothing (§3.2), so this package has no interface a module imports.
|
||||
|
||||
package wai:[email protected];
|
||||
|
||||
/// What a receipt names when a run stops (§6.2).
|
||||
interface receipt {
|
||||
enum fault-reason {
|
||||
unreachable,
|
||||
memory-out-of-bounds,
|
||||
table-out-of-bounds,
|
||||
indirect-call-null,
|
||||
indirect-call-type,
|
||||
integer-divide-by-zero,
|
||||
integer-overflow,
|
||||
invalid-conversion-to-integer,
|
||||
fuel-exhausted,
|
||||
stack-exhausted,
|
||||
bad-result,
|
||||
}
|
||||
}
|
||||
|
||||
/// A module's lifecycle (§5.3), every export optional: the seed, then each prior in the
|
||||
/// order the contract lists them, then `init`, each metered.
|
||||
world module {
|
||||
/// The seed for this instance: the run's, or the shot's when an instance lives for a shot.
|
||||
export wasmq-seed: func(seed: u64);
|
||||
/// Prior `index` of the module's priors, its bytes as the contract pins them.
|
||||
export wasmq-prior: func(index: u32, bytes: list<u8>);
|
||||
export init: func();
|
||||
}
|
||||
|
||||
/// The reference decoder (§8.1): the engine's qLDPC decoder. Prior 0 is a code's parity
|
||||
/// checks; a syndrome goes in, a correction comes out.
|
||||
world qldpc-decoder {
|
||||
include module;
|
||||
/// The list form: `extern decode(bit[m]) -> bit[n];` for any code.
|
||||
export decode: func(syndrome: list<u8>) -> list<u8>;
|
||||
/// The scalar form: `extern decode64(bit[m]) -> bit[n];`, m and n at most 64.
|
||||
export decode64: func(syndrome: u64) -> u64;
|
||||
}
|
||||
|
||||
/// The reference planner (§8.2): the engine's neutral-atom rearrangement. Prior 0 is the
|
||||
/// target register; an occupancy goes in, the moves come out as masks.
|
||||
world atom-planner {
|
||||
export wasmq-prior: func(index: u32, bytes: list<u8>);
|
||||
/// The list form: `extern plan(bit[n]) -> bit[2n+1];`.
|
||||
export plan: func(occupancy: list<u8>) -> list<u8>;
|
||||
/// The scalar form, for at most 31 sites.
|
||||
export plan64: func(occupancy: u64) -> u64;
|
||||
}
|
||||
|
|
@ -20,7 +20,9 @@ The OpenQASM 3 reader's corpus, programs with what the reader must do with
|
|||
each, is `qasm3/`, with a README of its own. The error-correction text formats
|
||||
(noisy Clifford circuits and detector error models, read and written back byte
|
||||
for byte, with what each must count and what must be refused) are `qec-text/`,
|
||||
with a README of its own. Programs in other formats (QIR under its profiles,
|
||||
with a README of its own. Programs that call WebAssembly between their gates (`wai.quantum.wasmq`), the
|
||||
reference modules of record and what a runner refuses are `wasmq/`, with a README of its
|
||||
own. Programs in other formats (QIR under its profiles,
|
||||
and jeff), each with the program it must read to, its round trip and its
|
||||
refusals, and OpenQASM written to each, are `formats/`, with a README of its
|
||||
own.
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ exactly the reasons the manifest names (§8.4): none for a valid one.
|
|||
|---|---|
|
||||
| `manifest.json` | every receipt in `jobs/`, the reasons a verifier must give it, how it was made, and what it is. Every expectation is written by hand from §8.4; none is copied from a verifier's output |
|
||||
| `jobs/cli-*.json` | made by the command line on this machine, sealed with the published demo key (`make.sh`): runs by several methods, a compile, and runs on the reference provider over a local process, free and priced |
|
||||
| `jobs/cli-wasmq-*.json` | wasmQ jobs ([quantum-wasmq](../../extensions/quantum-wasmq.md)) made by the command line from the profile's own envelopes (`../wasmq/envelopes/`) with the demo key (`make.sh`): a run of the surface-code round, one of a single instance for the whole run, and faults in a call, of the run's budget, in an instance's init and in a prior |
|
||||
| `jobs/service-*.json` | made by the free job service, sealed with its key (`make.sh`) |
|
||||
| `jobs/scripted-*.json` | provider jobs of every built-in kind (`sampler-v2`, `prx-circuits`, `native-turns` with and without a noise model, `cloud-tasks` on a processor and on its simulator, with rows of shots and with probabilities), each through a service that follows that provider's published contract, sealed with the demo key (`wai-quantum-qpu/tests/clients.rs`, `every_built_in_kind_states_what_it_sent_and_its_receipt_keeps_every_rule`, with `WAI_QUANTUM_RECEIPT_CORPUS` set to this directory) |
|
||||
| `jobs/first-form-*.json` | sealed by the job service as it was on 18 October 2026 (commit 72d18742d), so by the first form's own writer, not by a restatement of it |
|
||||
| `jobs/fixture-*.json` | the engine's pinned fixtures, sealed by earlier engines: a run before results named their engine, a provider job of the earlier form, and a compile |
|
||||
| `jobs/crafted-*.json` | made by `generate.py` from the receipts above, each changed one way: the seal's form, the strict signature (a weak-key forgery, `S + ℓ`, a mixed-order key, …), the first form, what any JSON reader and writer may do (and so must change nothing), the strict reader, and each rule of a provider's result, each sealed again with the demo key where the change is inside the seal so that one rule alone breaks |
|
||||
| `jobs/crafted-*.json` | made by `generate.py` from the receipts above, each changed one way: the seal's form, the strict signature (a weak-key forgery, `S + ℓ`, a mixed-order key, …), the first form, what any JSON reader and writer may do (and so must change nothing), the strict reader, and each rule of a provider's result and of a wasmQ job's form, each sealed again with the demo key where the change is inside the seal so that one rule alone breaks |
|
||||
|
||||
The made receipts are kept as they were made, each pinned by its digest in `made.lock.json`:
|
||||
a receipt missing or changed fails `generate.py --check`. A receipt made again differs in its
|
||||
|
|
@ -24,7 +25,9 @@ to pass a test. A row of §8.3 that a client stops writing is held by the receip
|
|||
- `wai-quantum verify --json FILE` (and `--lines FILE`, one job a line): the reference,
|
||||
`wai_quantum::engine::job::check`.
|
||||
- [`../tools/receipt_verify.py`](../tools/receipt_verify.py): written in Python from §8
|
||||
alone, by a reader who had not seen the reference. Standard library only: its BLAKE3,
|
||||
alone, by a reader who had not seen the reference. Its `wasmq_form`, a wasmQ job's form,
|
||||
was written the same way from [quantum-wasmq §6.5](../../extensions/quantum-wasmq.md#65-verifying),
|
||||
whose rules are numbered so that each can be read alone. Standard library only: its BLAKE3,
|
||||
Ed25519, RFC 8785 text and strict reader are its own, each held to published answers by
|
||||
`--self-test`.
|
||||
|
||||
|
|
@ -47,6 +50,35 @@ replaced) and requires the same reasons from both for every change, and two orac
|
|||
them: a change inside the request, the result or the receipt is never valid, and a change to
|
||||
the unsealed envelope, or a member added to the receipt, never changes the verdict.
|
||||
|
||||
A change of one member is caught by the seal before any rule of a job's form is read, so
|
||||
it cannot hold the two verifiers to those rules. The rules stage does: for each rule of a
|
||||
wasmQ job's form ([quantum-wasmq §6.5](../../extensions/quantum-wasmq.md#65-verifying)),
|
||||
the genuine wasmQ jobs changed at the rule's bound, on both sides of it where it has two,
|
||||
and sealed again with the demo key, each with the verdict written for it by hand from the
|
||||
text (`rule_cases` in the differential). Both verifiers must give every case its written
|
||||
verdict, so a rule dropped or a bound moved in either one fails: this stage, and the
|
||||
manifest, are what back "the two verifiers agree" on the form's rules. `--second-only`
|
||||
runs it for the second verifier. Each crafted wasmQ receipt that names one rule breaks that
|
||||
rule alone: the reference states one problem for it, and the second verifier that rule.
|
||||
|
||||
The labelled stage gives both verifiers the second verifier's own hand-labelled wasmQ cases
|
||||
(`receipt_verify.py --wasmq-cases`), each as its exact text: the labels its author wrote from
|
||||
the text bind the reference as they bind the second verifier, so one labelled corpus holds
|
||||
both.
|
||||
|
||||
[`../tools/wasmq_mutants.py`](../tools/wasmq_mutants.py) weakens each rule in each verifier,
|
||||
from the code (each check dropped, each comparison moved by one, a count or a digest read
|
||||
loosely, a null member read as absent and an absent one as null, the most of many read as the
|
||||
least), and requires the
|
||||
differential (`--wasmq-only --first`) to catch every weakening, counted per rule:
|
||||
|
||||
```sh
|
||||
python3 -I tools/wasmq_mutants.py python --reference PATH/wai-quantum
|
||||
python3 -I tools/wasmq_mutants.py rust-schemata ../wai-quantum/src/engine/wasmq.rs mutants.json # in a scratch checkout
|
||||
# build the command line from that checkout, then
|
||||
python3 -I tools/wasmq_mutants.py rust --reference PATH/wai-quantum --mutants mutants.json
|
||||
```
|
||||
|
||||
It also changes each number of the provider receipts to values past a double's whole numbers,
|
||||
and sets a job's shots in both its request and its result, to see a limit one verifier has and
|
||||
the other does not; and it seals those of the demo key again, so that each is judged by what it
|
||||
|
|
|
|||
|
|
@ -302,11 +302,50 @@ def seal_set(body, seed=DEMO):
|
|||
return out
|
||||
|
||||
|
||||
def _count(v):
|
||||
"""A count's value (quantum-wasmq section 6.5): a whole number from 0 to 2^53 - 1."""
|
||||
if isinstance(v, Raw):
|
||||
v = v.value
|
||||
if isinstance(v, bool) or not isinstance(v, (int, float)) or v != v or v in (float("inf"), float("-inf")):
|
||||
return None
|
||||
return int(v) if v == int(v) and 0 <= v <= 2 ** 53 - 1 else None
|
||||
|
||||
|
||||
def bare_transcript(r):
|
||||
"""The transcript_blake3 of a wasmQ result in which no call returned (quantum-wasmq
|
||||
section 6.5, rule 35): the prefix and, after a fault, its shot, reason and fuel. None
|
||||
when a call returned, or its callouts are no count."""
|
||||
if not isinstance(r, dict) or r.get("format") != "wai.quantum.wasmq.result/1":
|
||||
return None
|
||||
fault = r.get("fault") if r.get("status") == "fault" and isinstance(r.get("fault"), dict) else None
|
||||
in_call = 1 if fault is not None and fault.get("phase") == "call" else 0
|
||||
k = _count(r.get("callouts"))
|
||||
if k is None or k > in_call:
|
||||
return None
|
||||
data = b"wai:wasmq-transcript\x01"
|
||||
if fault is not None:
|
||||
reason = fault.get("reason")
|
||||
data += b"fault" + struct.pack("<Q", _count(fault.get("shot")) or 0) + (reason.encode("utf-8") if isinstance(reason, str) else b"") + struct.pack("<Q", _count(fault.get("fuel")) or 0)
|
||||
return blake3(data).hex()
|
||||
|
||||
|
||||
def retranscribed(before, b):
|
||||
"""b, a wasmQ job changed from before, its transcript made again as the writer makes it
|
||||
when no call returned, unless the change was to the transcript itself."""
|
||||
r = b.get("result")
|
||||
if isinstance(r, dict) and r.get("transcript_blake3") == before.get("result", {}).get("transcript_blake3"):
|
||||
t = bare_transcript(r)
|
||||
if t is not None:
|
||||
r["transcript_blake3"] = t
|
||||
return b
|
||||
|
||||
|
||||
def edited(body, edit, form="canonical"):
|
||||
"""body changed by edit (which may change request, result or both), sealed again."""
|
||||
"""body changed by edit (which may change request, result or both), sealed again; a
|
||||
wasmQ job in which no call returned keeps the transcript its writer would give it."""
|
||||
b = copy.deepcopy(body)
|
||||
edit(b)
|
||||
return seal(b, form=form)
|
||||
return seal(retranscribed(body, b), form=form)
|
||||
|
||||
|
||||
def rx(body, edit):
|
||||
|
|
@ -700,6 +739,138 @@ def cases():
|
|||
add("method-measured", edited(run, at(R + ("accuracy", "class"), "measured")), ["provider_class"], "the engine's own result labelled measured")
|
||||
add("method-simulated", edited(run, at(R + ("accuracy", "class"), "simulated")), ["provider_class"], "the engine's own result labelled simulated")
|
||||
add("method-class-unknown", edited(run, at(R + ("accuracy", "class"), "quasi-exact")), [], "a class a verifier does not know: not a reason, since a later version may add one")
|
||||
|
||||
# --- a wasmQ job (quantum-wasmq section 6.5): each sealed again, one rule broken
|
||||
wrun = load("cli-wasmq-run.json")
|
||||
wfault = load("cli-wasmq-fault.json")
|
||||
wjob = load("cli-wasmq-state-job.json")
|
||||
C = ("request", "wasmq")
|
||||
|
||||
def fewer(k, by=1):
|
||||
def f(b):
|
||||
counts = b["result"]["counts"]
|
||||
most = max(counts, key=lambda o: counts[o])
|
||||
counts[most] -= by
|
||||
if k:
|
||||
b["result"]["shots_run"] -= by
|
||||
return f
|
||||
|
||||
def both(name, value):
|
||||
def f(b):
|
||||
b["request"]["wasmq"]["run"][name] = value
|
||||
b["result"][name] = value
|
||||
return f
|
||||
|
||||
def budget(name, value):
|
||||
def f(b):
|
||||
b["request"]["wasmq"]["run"]["fuel"][name] = value
|
||||
b["result"]["fuel"]["budget"][name] = value
|
||||
return f
|
||||
|
||||
add("wasmq-counts-short", edited(wrun, fewer(False)), ["wasmq_form"], "a wasmQ run whose counts add up to one shot fewer than it ran (rule 19)")
|
||||
add("wasmq-ok-before-all-shots", edited(wrun, fewer(True)), ["wasmq_form"], "a wasmQ run that is ok after 31 of its 32 shots (rule 18)")
|
||||
add("wasmq-fuel-unaccounted", edited(wrun, lambda b: b["result"]["fuel"].update(instances=b["result"]["fuel"]["instances"] + 1)), ["wasmq_form"], "a wasmQ run whose instances and calls do not add up to the fuel it used (rule 15)")
|
||||
add("wasmq-fuel-past-job-budget", edited(wfault, budget("per_job", 100)), ["wasmq_form"], "a wasmQ fault that used 400 fuel under a run's budget of 100 (rule 13)")
|
||||
add("wasmq-instances-past-budget", edited(wjob, budget("per_instance", 8000)), ["wasmq_form"], "one instance for the whole run, given more fuel for its seed, init and prior than three stretches of 8000 (rule 17)")
|
||||
add("wasmq-fault-unnamed", edited(wfault, lambda b: (b["result"]["fault"].update(reason="out_of_fuel"), b["result"]["fault"].pop("budget"))), ["wasmq_form"], "a wasmQ fault of a reason the profile does not name (rule 18)")
|
||||
add("wasmq-result-member-added", edited(wrun, at(R + ("note",), "a member the profile does not write")), ["wasmq_form"], "a wasmQ result with a member the profile does not write (rule 9)")
|
||||
add("wasmq-contract-method", edited(wrun, both("method", "statevector")), ["wasmq_form"], "a wasmQ contract and result of a method the profile does not have (rule 8)")
|
||||
add("wasmq-seed-past-exact", edited(wrun, both("seed", 2 ** 53)), ["wasmq_form"], "a wasmQ seed of 2^53: a double holds it, so it is no inexact number, and the profile allows at most 2^53 - 1 (rules 1, 8)")
|
||||
add("wasmq-modules-other", edited(wrun, lambda b: b["result"]["modules"][0].update(blake3="ab" * 32)), ["wasmq_form"], "a wasmQ result naming a module the contract does not pin (rule 16)")
|
||||
add("wasmq-transcript-upper", edited(wrun, lambda b: b["result"].update(transcript_blake3=b["result"]["transcript_blake3"].upper())), ["wasmq_form"], "a wasmQ transcript digest in upper case (rule 12)")
|
||||
add("wasmq-first-form", seal(wrun, form="first"), ["wasmq_form"], "a wasmQ job sealed in the first form, older than the profile: the seal holds, and no host wrote it (rule 10)")
|
||||
def uncounted(b):
|
||||
b["result"].update(callouts=0)
|
||||
b["result"]["fuel"].update(callouts={}, instances=400)
|
||||
add("wasmq-call-fault-uncounted", edited(wfault, uncounted), ["wasmq_form"], "a call that stopped the run, which the fuel counts no call of: the stopped call is one of the calls made (rule 18)")
|
||||
|
||||
def past_largest(b):
|
||||
b["result"].update(callouts=2)
|
||||
b["result"]["fuel"]["callouts"]["f"].update(calls=2, fuel=401, max=399)
|
||||
b["result"]["fuel"]["used"] = 401
|
||||
add("wasmq-call-fault-past-largest", edited(wfault, past_largest), ["wasmq_form"], "a call that stopped after 400 fuel, where the most one call of it used is 399 (rule 18)")
|
||||
|
||||
# Each rule the corpus held no receipt for, broken alone (rule 1 cannot be: every place a
|
||||
# number may be has a rule of its own that holds it within 2^53 - 1).
|
||||
wrunf = load("cli-wasmq-fault-run.json")
|
||||
winit = load("cli-wasmq-fault-init.json")
|
||||
wprior = load("cli-wasmq-fault-prior.json")
|
||||
|
||||
def each(*edits):
|
||||
def f(b):
|
||||
for e in edits:
|
||||
e(b)
|
||||
return f
|
||||
|
||||
def later_shot(shot, state=None, instances=1, fuel=1, callouts=None):
|
||||
# The init fault moved to `shot`, after that many shots of one call each.
|
||||
def f(b):
|
||||
n = shot if callouts is None else callouts
|
||||
if state:
|
||||
b["request"]["wasmq"]["run"]["state"] = state
|
||||
b["result"].update(shots_run=shot, counts={"0": shot} if shot else {}, callouts=n)
|
||||
b["result"]["fuel"].update(instances=instances, callouts={"f": {"calls": n, "fuel": n, "max": 1}} if n else {}, used=instances + n)
|
||||
b["result"]["fault"].update(shot=shot, fuel=fuel)
|
||||
return f
|
||||
|
||||
def second_module(fault_module):
|
||||
def f(b):
|
||||
c = b["request"]["wasmq"]
|
||||
c["modules"].append({"name": "m2", "blake3": "cd" * 32, "bytes": 57, "priors": []})
|
||||
c["callouts"].append({"extern": "g", "module": 1, "export": "g"})
|
||||
b["result"]["modules"].append({"name": "m2", "blake3": "cd" * 32})
|
||||
b["result"]["fault"]["module"] = fault_module
|
||||
return f
|
||||
|
||||
def shots(n):
|
||||
def f(b):
|
||||
b["request"]["wasmq"]["run"]["shots"] = b["result"]["shots"] = n
|
||||
return f
|
||||
|
||||
add("wasmq-request-member-added", edited(wrun, at(("request", "x"), 1)), ["wasmq_form"], "a wasmQ request with a member the profile does not write (rule 2)")
|
||||
add("wasmq-contract-member-added", edited(wrun, at(C + ("x",), 1)), ["wasmq_form"], "a wasmQ contract with a member section 2.2 does not list (rule 3)")
|
||||
add("wasmq-contract-profile", edited(wrun, at(C + ("profile",), "wai.quantum.wasmq/2")), ["wasmq_form"], "a wasmQ contract of another profile (rule 4)")
|
||||
add("wasmq-program-empty", edited(wrun, at(C + ("program", "bytes"), 0)), ["wasmq_form"], "a wasmQ contract whose program is 0 bytes long (rule 5)")
|
||||
add("wasmq-module-empty", edited(wrun, lambda b: b["request"]["wasmq"]["modules"][0].update(bytes=0)), ["wasmq_form"], "a wasmQ contract whose module is 0 bytes long (rule 6)")
|
||||
add("wasmq-callouts-twice", edited(wrun, lambda b: b["request"]["wasmq"]["callouts"].append({"extern": "decode64", "module": 0, "export": "x"})), ["wasmq_form"], "a wasmQ contract with two callouts of one extern (rule 7)")
|
||||
add("wasmq-result-seed", edited(wrun, lambda b: b["result"].update(seed=b["result"]["seed"] + 1)), ["wasmq_form"], "a wasmQ result whose seed is not its contract's (rule 11)")
|
||||
add("wasmq-call-past-per-call", edited(wrun, budget("per_call", 21750)), ["wasmq_form"], "a wasmQ run whose largest call used 21751 fuel under a budget of 21750 a call (rule 14)")
|
||||
add("wasmq-calls-of-no-fuel", edited(wrun, lambda b: (b["result"]["fuel"]["callouts"]["decode64"].update(fuel=0, max=0), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"]))), ["wasmq_form"], "32 calls that returned having used no fuel, where entering a function weighs 1 (rule 20)")
|
||||
add("wasmq-priors-unpassed", edited(wrun, lambda b: b["result"]["fuel"].update(instances=32 * 90 - 1, used=32 * 90 - 1 + 588348)), ["wasmq_form"], "32 shots of instances passed a prior of 87 bytes in less fuel than its bytes and its two calls take, cabi_realloc 2 at least and wasmq-prior 1 (rule 21)")
|
||||
add("wasmq-call-fault-other-module", edited(wfault, second_module("m2")), ["wasmq_form"], "a call of a callout in the first module, whose fault names the second (rule 22)")
|
||||
add("wasmq-prior-fault-no-prior", edited(winit, at(R + ("fault", "phase"), "prior")), ["wasmq_form"], "a fault while a prior is passed, in a module with no prior (rule 23)")
|
||||
add("wasmq-bad-result-in-init", edited(winit, each(at(R + ("fault", "reason"), "bad_result"), at(R + ("fault", "fuel"), 2), at(R + ("fuel", "instances"), 2), at(R + ("fuel", "used"), 2))), ["wasmq_form"], "a bad_result from an init, which takes no result (rule 24)")
|
||||
add("wasmq-lifecycle-fuel-past-instances", edited(winit, later_shot(1, instances=1, fuel=2)), ["wasmq_form"], "an init fault in shot 1 that used 2 fuel, where the instances used 1, shot 0's init 1 of it at least (rule 25)")
|
||||
add("wasmq-job-state-later-instance", edited(winit, later_shot(2, state="job", instances=2)), ["wasmq_form"], "a run of one instance for the run whose instance fails in shot 2 (rule 26)")
|
||||
add("wasmq-first-instance-after-call", edited(winit, later_shot(0, callouts=1)), ["wasmq_form"], "the first shot's instance failing after a call was made, where no shot ran its steps (rules 27 and 32)")
|
||||
add("wasmq-fuel-fault-under-limit", edited(wfault, lambda b: (b["result"]["fuel"]["callouts"]["f"].update(fuel=10, max=10), b["result"]["fuel"].update(used=10), b["result"]["fault"].update(fuel=10))), ["wasmq_form"], "a call's fuel fault after 10 fuel, under its limit of 400 (rule 28)")
|
||||
add("wasmq-run-budget-not-spent", edited(wrunf, budget("per_job", 60)), ["wasmq_form"], "a fault of the run's budget with 50 of its 60 used (rule 28)")
|
||||
add("wasmq-results-past-bits", edited(wrunf, each(shots(2 ** 20), lambda b: b["result"].update(counts={"0" * 257: 2}))), ["wasmq_form"], "2^20 shots of 257 bits, past the 2^28 bits a run's results hold (rule 29)")
|
||||
add("wasmq-work-past-bound", edited(wrun, budget("per_job", 2 ** 39)), ["wasmq_form"], "a run given 2^39 fuel beside a module's code, past the 2^42 operations a run asks (rule 30)")
|
||||
add("wasmq-frames-past-envelope", edited(wprior, lambda b: b["request"]["wasmq"]["modules"][0]["priors"][0].update(bytes=2 ** 27)), ["wasmq_form"], "a prior of 2^27 bytes beside a program and a module, more than an envelope holds (rule 31)")
|
||||
add("wasmq-fault-null", edited(wrun, at(R + ("fault",), None)), ["wasmq_form"], "an ok result with a fault member whose value is null: a member is present whatever its value (rule 18)")
|
||||
# Round 5's rules, each broken alone.
|
||||
add("wasmq-no-qubit", edited(wrun, at(R + ("qubits",), 0)), ["wasmq_form"], "a wasmQ result of a program of no qubit, which no program a reader reads is (rule 12)")
|
||||
def calls_at_their_largest(b):
|
||||
b["result"]["fuel"]["callouts"]["decode64"].update(fuel=21751)
|
||||
b["result"]["fuel"]["used"] = b["result"]["fuel"]["instances"] + 21751
|
||||
add("wasmq-calls-under-largest", edited(wrun, calls_at_their_largest), ["wasmq_form"], "32 calls in 21751 fuel, where the most one of them used is 21751 and each other used 1 at least (rule 20)")
|
||||
def calls_past_steps(b):
|
||||
n = 32 * 2 ** 21 + 1
|
||||
b["result"]["callouts"] = n
|
||||
b["result"]["fuel"]["callouts"]["decode64"].update(calls=n, fuel=n, max=1)
|
||||
b["result"]["fuel"]["used"] = b["result"]["fuel"]["instances"] + n
|
||||
add("wasmq-calls-past-steps", edited(wrun, calls_past_steps), ["wasmq_form"], "32 shots that made 2^21 calls each and one more, where a shot runs at most 2^21 steps (rule 32)")
|
||||
add("wasmq-prior-past-instance-budget", edited(wrun, each(budget("per_instance", 89), lambda b: b["result"]["fuel"].update(instances=32 * 90, used=32 * 90 + 588348))), ["wasmq_form"], "a prior of 87 bytes passed whole in one stretch, which takes 90 at least, under a lifecycle call's budget of 89 (rule 33)")
|
||||
add("wasmq-trap-of-no-fuel", edited(winit, at(R + ("fault", "fuel"), 0)), ["wasmq_form"], "an init that trapped after no fuel, where its entry is charged before it runs (rule 34)")
|
||||
add("wasmq-transcript-of-no-call", edited(winit, at(R + ("transcript_blake3",), "ab" * 32)), ["wasmq_form"], "a fault before any call whose transcript is not the run's end alone (rule 35)")
|
||||
respelt = copy.deepcopy(wrun)
|
||||
respelt["request"]["wasmq"]["run"]["shots"] = Raw("32.0", 32)
|
||||
respelt["result"]["shots"] = Raw("3.2e1", 32)
|
||||
add("wasmq-respelt", (dump(respelt) + "\n").replace('"state": ', '"\\u0073tate": ', 1), [], "a wasmQ job with its shots written 32.0 and 3.2e1 and a member of its contract named with an escape: the same sealed content")
|
||||
moved = copy.deepcopy(wfault)
|
||||
moved.update(status="done", method="statevector", id="j-another")
|
||||
add("wasmq-envelope-changed", moved, [], "a wasmQ fault whose unsealed body says done, another method and an id: a note beside the verdict, not a reason")
|
||||
return out
|
||||
|
||||
|
||||
|
|
@ -729,6 +900,12 @@ MADE = {
|
|||
"cli-set-sweep.json": ("the command line: a sweep of an input at three points, sealed as a set", []),
|
||||
"first-form-service-run.json": ("the job service as it was on 18 October 2026, commit 72d18742d, sealing with the first form's own writer: counts", []),
|
||||
"first-form-service-observables.json": ("the same service, the same writer: expectation values, doubles in its own text", []),
|
||||
"cli-wasmq-run.json": ("the command line: a wasmQ run, a surface-code round decoded by WebAssembly between its gates, 32 shots", []),
|
||||
"cli-wasmq-state-job.json": ("the command line: a wasmQ run of one instance for the whole run, its decoder reading a prior", []),
|
||||
"cli-wasmq-fault.json": ("the command line: a wasmQ run that stopped in a call past the call's fuel budget", []),
|
||||
"cli-wasmq-fault-run.json": ("the command line: a wasmQ run that stopped in its third shot when the run's fuel ran out", []),
|
||||
"cli-wasmq-fault-init.json": ("the command line: a wasmQ run that stopped in an instance's init", []),
|
||||
"cli-wasmq-fault-prior.json": ("the command line: a wasmQ run that stopped while a module read its prior", []),
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
{"status":"fault","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"f","extern":"f","module":0}],"modules":[{"blake3":"f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3","bytes":50,"name":"m","priors":[]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319","bytes":128,"inputs":{}},"run":{"fuel":{"per_call":10000000,"per_instance":100000000,"per_job":17179869184},"method":"stabilizer","seed":1,"shots":4,"state":"shot"}},"envelope_blake3":"d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"fault","method":"stabilizer","qubits":8,"shots":4,"shots_run":0,"seed":1,"counts":{},"callouts":0,"fuel":{"used":1,"instances":1,"budget":{"per_call":10000000,"per_job":17179869184,"per_instance":100000000},"callouts":{}},"modules":[{"name":"m","blake3":"f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"}],"transcript_blake3":"1f9cfb398c872903d55e1962f50421060c42968e524e914e04bb0b971e4d0881","accuracy":{"class":"exact"},"fault":{"reason":"unreachable","shot":0,"phase":"init","module":"m","fuel":1},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"ac633eb1fb15f62ad6df9b6b7891dc7ada2dac6c1503e5f4d073dc866b40cd6d","signature":"0c6cdfa74c73a0922c550acef28da9cca21f87eae4310ed81e7365dc85a6076361b11316c21bc0a2db66f103d0f7c2e7c46bd4da68620c1112d3ac80a728c109"}}}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"status":"fault","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"f","extern":"f","module":0}],"modules":[{"blake3":"2bd6df6f77cff04a53312cc69ee9024ae6e445af9dd3a7d410cc5c8a18c0c4d0","bytes":105,"name":"m","priors":[{"blake3":"024f67c0425a3dc02fbaf58cb93de5132e3d75c519faa0bada21491d88c97057","bytes":5,"name":"weights"}]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319","bytes":128,"inputs":{}},"run":{"fuel":{"per_call":10000000,"per_instance":100000000,"per_job":17179869184},"method":"stabilizer","seed":1,"shots":4,"state":"shot"}},"envelope_blake3":"6da2c86da1b3d288df324fa7902e4cb10c9c5b21160921907299402466c5d50c"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"fault","method":"stabilizer","qubits":8,"shots":4,"shots_run":0,"seed":1,"counts":{},"callouts":0,"fuel":{"used":8,"instances":8,"budget":{"per_call":10000000,"per_job":17179869184,"per_instance":100000000},"callouts":{}},"modules":[{"name":"m","blake3":"2bd6df6f77cff04a53312cc69ee9024ae6e445af9dd3a7d410cc5c8a18c0c4d0"}],"transcript_blake3":"3db8f511346d060c257940c086300666c8eb1b27c6083d36066b8d8f38e6408c","accuracy":{"class":"exact"},"fault":{"reason":"unreachable","shot":0,"phase":"prior","module":"m","fuel":8},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"48f6ca3e7cc12a0ac8f277c342bf8098c9ca9d2938f855eb75336a33e0ce29b3","signature":"78b5984d9ce1a89580c32cdd987840b89d357745d23e70ae259bdd66ae0cc128ca10cc0e754e67bf71e1c768c531e340f7b5ea9d654a2508d9fb6f60709ba80a"}}}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"status":"fault","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"f","extern":"f","module":0}],"modules":[{"blake3":"9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43","bytes":68,"name":"m","priors":[]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319","bytes":128,"inputs":{}},"run":{"fuel":{"per_call":10000000,"per_instance":100000000,"per_job":50},"method":"stabilizer","seed":1,"shots":8,"state":"shot"}},"envelope_blake3":"0a19542a6a9178984a93d9863a1d5e9371e00b86c6e9143e04b5f0fb5b0be177"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"fault","method":"stabilizer","qubits":8,"shots":8,"shots_run":2,"seed":1,"counts":{"0101101101011011":1,"1011111010111110":1},"callouts":3,"fuel":{"used":50,"instances":0,"budget":{"per_call":10000000,"per_job":50,"per_instance":100000000},"callouts":{"f":{"calls":3,"fuel":50,"max":23}}},"modules":[{"name":"m","blake3":"9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43"}],"transcript_blake3":"3772395e9bb2f9fba3b1a7ef4f5def3e5f10f76a9ba517d16056e5fd7cb7d413","accuracy":{"class":"exact"},"fault":{"reason":"fuel_exhausted","shot":2,"phase":"call","module":"m","fuel":4,"callout":"f","budget":"run"},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"39102ed51a3b76f36d8fafb5a7f4d9af7c1d2363e74b5c1d6dfe593770b364ad","signature":"7705ba3a31066100c6b9e228716e2359a834eb10b6bffda1bcca5da1483227ae0a4553e113b351e4ae4861060eb73b01343c0e26ec58f7c5bba7d730fc1dc70e"}}}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"status":"fault","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"f","extern":"f","module":0}],"modules":[{"blake3":"a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1","bytes":57,"name":"m","priors":[]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319","bytes":128,"inputs":{}},"run":{"fuel":{"per_call":400,"per_instance":100000000,"per_job":17179869184},"method":"stabilizer","seed":9,"shots":32,"state":"shot"}},"envelope_blake3":"22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"fault","method":"stabilizer","qubits":8,"shots":32,"shots_run":0,"seed":9,"counts":{},"callouts":1,"fuel":{"used":400,"instances":0,"budget":{"per_call":400,"per_job":17179869184,"per_instance":100000000},"callouts":{"f":{"calls":1,"fuel":400,"max":400}}},"modules":[{"name":"m","blake3":"a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"}],"transcript_blake3":"47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7","accuracy":{"class":"exact"},"fault":{"reason":"fuel_exhausted","shot":0,"phase":"call","module":"m","fuel":400,"callout":"f","budget":"call"},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"9cab411ba32a647e5c4b0ce53609a4308c1a07bd26c817fca582e3e04258bff4","signature":"c939aab422b5bf97f2abb4264df90c7aa2c69287570ed177edaa1a2fad8c4ddc9ea3758ee11cea21341c84a9d4eb47da4549431f32c9d8adbfe2721ade007a07"}}}
|
||||
1
wai/quantum-conformance/receipts/jobs/cli-wasmq-run.json
Normal file
1
wai/quantum-conformance/receipts/jobs/cli-wasmq-run.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"status":"done","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"decode64","extern":"decode64","module":0}],"modules":[{"blake3":"005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962","bytes":39442,"name":"qldpc-decoder","priors":[{"blake3":"1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db","bytes":87,"name":"checks"}]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85","bytes":1104,"inputs":{}},"run":{"fuel":{"per_call":10000000,"per_instance":100000000,"per_job":17179869184},"method":"stabilizer","seed":1234,"shots":32,"state":"shot"}},"envelope_blake3":"3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"ok","method":"stabilizer","qubits":17,"shots":32,"shots_run":32,"seed":1234,"counts":{"000000000000000000000000001001":3,"000000000000000000000000001010":2,"000000000000000000000000001011":4,"000000000000000000000000001101":2,"000000000000000000000000001110":2,"000000000000000000000000001111":1,"000000000000000000000100010000":4,"000000000000000000010010000010":2,"000000000000000000100001010011":2,"000000000000000001000000110100":2,"000000000000000010000010100101":2,"000000000000000100000001000110":3,"000000011000000000000100010001":2,"110000000000001000000000101000":1},"callouts":32,"fuel":{"used":836380,"instances":248032,"budget":{"per_call":10000000,"per_job":17179869184,"per_instance":100000000},"callouts":{"decode64":{"calls":32,"fuel":588348,"max":21751}}},"modules":[{"name":"qldpc-decoder","blake3":"005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"}],"transcript_blake3":"037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82","accuracy":{"class":"exact"},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"df6d2e83f44afa7db6d7c6a3d4791443525b1778b794023326296050cb47dcb1","signature":"1ea3250661d07afe9e5f0bac876186cb6fb93ff2c9595e1f4d41c1bb7f9b0674d0146f9329a24d3b22c74d666f3f63329b19970c9ee90eb199f448e7a0e13a01"}}}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"status":"done","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"decode64","extern":"decode64","module":0}],"modules":[{"blake3":"005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962","bytes":39442,"name":"qldpc-decoder","priors":[{"blake3":"a0a28225df247910039d0693ff2dfb69d3b012487e81fc449486dd5b9afc3fd7","bytes":231,"name":"checks"}]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"1c79196a4e25b4f73f53a8327d9ab5d4d1644040f6b5036bb34aa1d456f2ee28","bytes":3346,"inputs":{}},"run":{"fuel":{"per_call":10000000,"per_instance":100000000,"per_job":17179869184},"method":"stabilizer","seed":77,"shots":16,"state":"job"}},"envelope_blake3":"3691fd8cac6fffe58d46a496aeff248a40d654129fe8cd23bae3dd6d3cebf8f4"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"ok","method":"stabilizer","qubits":47,"shots":16,"shots_run":16,"seed":77,"counts":{"000000000000000000000000000000000000000000000000000000000000000000000000001001110011":1,"000000000000000000000000000000000000000000000000000000000000010000000000011110000000":1,"000000000000000000000000000000000000000000000000000001000000010000000010110100000000":1,"000000000000000000000000000000000000000000000000000010001000000101000010010010101001":1,"000000000000000000000000000000000000000000000000010000000100000100001001000110000100":1,"000000000000000000000000000000000000000000000000100000000100000100001010000110100100":1,"000000000000000000000000000000000000000000000001000000000000011000000010010000001110":1,"000000000000000000000000000000000000000000000010100000000000000010001110000110101111":1,"000000000000000000000000000000000000001000000000000000000000000000100000001111010111":1,"000000000000000000000001100000000000000000000010000000000000010010000100010111100001":1,"000000000000011000110000000000000000000000000000000000011000000001000001000101001011":1,"000000000000011000110000000000000000000000000000000100011000010000000101010101100000":1,"000000011000110000000000000000000000000000000100001000000000000000010001000110010001":1,"001010001100000000000000000000000000000001000010000000000000000000000100001000010110":1,"001100000000000000000000000000000000000010100000000000000000001000110000001001110110":1,"110000000000000000000000000000000000001000000000000001000000000000100010100100011000":1},"callouts":16,"fuel":{"used":765610,"instances":24078,"budget":{"per_call":10000000,"per_job":17179869184,"per_instance":100000000},"callouts":{"decode64":{"calls":16,"fuel":741532,"max":57659}}},"modules":[{"name":"qldpc-decoder","blake3":"005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"}],"transcript_blake3":"eb5252076ea8bb4c45ccec714a3cc64b89e833fe0a49c36a28881b63b1c3799e","accuracy":{"class":"exact"},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"5109fd0c11be13f637530e8861ec2d625a2985a9a3ad9340e0d00d36aea2346d","signature":"62f2f505f3a36cf6e94e4113639db0eb64c4efe8ee8a902c4895e11f4de322ffdb6f610e68dbcbf6bdd2698ba7a0e46925a65134b95547d434070e6316cd1e09"}}}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
|
||||
"bytes": 50,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1,
|
||||
"shots": 4,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 4,
|
||||
"shots_run": 0,
|
||||
"seed": 1,
|
||||
"counts": {},
|
||||
"callouts": 0,
|
||||
"fuel": {
|
||||
"used": 2,
|
||||
"instances": 2,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "c48396a6714b39ae0ea80250bf9f0311f615658bffd12ba92f0bb2f59872d7e4",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "bad_result",
|
||||
"shot": 0,
|
||||
"phase": "init",
|
||||
"module": "m",
|
||||
"fuel": 2
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "72f072588513ed965a36a7cd402e9980479d14208d7c51fe865791327e054b91",
|
||||
"signature": "110cc7f0544a210de71a2ea0a54240dfa572ba7719ebf3a258c1fd2121272810a77c88da29e58dfc1b103d7f8f9b957b98aacaed29ac59ca9e63d1358a428c02"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
},
|
||||
{
|
||||
"extern": "g",
|
||||
"module": 1,
|
||||
"export": "g"
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
|
||||
"bytes": 57,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
},
|
||||
{
|
||||
"name": "m2",
|
||||
"blake3": "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
|
||||
"bytes": 57,
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 400,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 9,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 32,
|
||||
"shots_run": 0,
|
||||
"seed": 9,
|
||||
"counts": {},
|
||||
"callouts": 1,
|
||||
"fuel": {
|
||||
"used": 400,
|
||||
"instances": 0,
|
||||
"budget": {
|
||||
"per_call": 400,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 1,
|
||||
"fuel": 400,
|
||||
"max": 400
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
|
||||
},
|
||||
{
|
||||
"name": "m2",
|
||||
"blake3": "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "fuel_exhausted",
|
||||
"shot": 0,
|
||||
"phase": "call",
|
||||
"module": "m2",
|
||||
"fuel": 400,
|
||||
"callout": "f",
|
||||
"budget": "call"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "e4af5b30d391f6049cba79d7d84b0069f659afa8e6215f790314014a4cf53c25",
|
||||
"signature": "ec802b9ff66aa15c36c3cf2d2ae0924d6e2928b7697fa65c612b90e90f72bc2b07102c267304ac89311e1ad8adc78dca0836bb2116fafdd223dab24315d3cb0c"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
|
||||
"bytes": 57,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 400,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 9,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 32,
|
||||
"shots_run": 0,
|
||||
"seed": 9,
|
||||
"counts": {},
|
||||
"callouts": 2,
|
||||
"fuel": {
|
||||
"used": 401,
|
||||
"instances": 0,
|
||||
"budget": {
|
||||
"per_call": 400,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 2,
|
||||
"fuel": 401,
|
||||
"max": 399
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "fuel_exhausted",
|
||||
"shot": 0,
|
||||
"phase": "call",
|
||||
"module": "m",
|
||||
"fuel": 400,
|
||||
"callout": "f",
|
||||
"budget": "call"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "583cc658764532b53630e620ed79cc95ed0cf8d5ef4a54ceafea43b7e9304381",
|
||||
"signature": "9341a9016bf590b7ce944cadbb070a4894b2bbb7083e3f8167109556d989979ee4087aae8de3e70649b5e8908cf9392c9b6d7fc969d1f06dc717fa24a10e730a"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
|
||||
"bytes": 57,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 400,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 9,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 32,
|
||||
"shots_run": 0,
|
||||
"seed": 9,
|
||||
"counts": {},
|
||||
"callouts": 0,
|
||||
"fuel": {
|
||||
"used": 400,
|
||||
"instances": 400,
|
||||
"budget": {
|
||||
"per_call": 400,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "fuel_exhausted",
|
||||
"shot": 0,
|
||||
"phase": "call",
|
||||
"module": "m",
|
||||
"fuel": 400,
|
||||
"callout": "f",
|
||||
"budget": "call"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "64aa39cd10a072bd758f09c0c6b4850d266f6025d2baf16d3e5c2366c74db475",
|
||||
"signature": "ed7b6d1c9603d5a9371c4d59e3355acd3d24247ff1fab0b3fc45f9c7a61d3247286833f642ede8f3cc70fd2e74438eac8ab6664e393cdd909de5233f3fb73909"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 21750,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 21750,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "2b2cf2d827fe92e3a3b2d637fba76aa3b0019b34f9c355639e54a5ccd6b2f45e",
|
||||
"signature": "225ea523d6694ac1679a54299bfaff95df59e844ae46318c3277675aa95ac4c958695315b9a080cf81b7d92c7f08ef22c5e5c6bef59063bc959360d2663a8d09"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
},
|
||||
{
|
||||
"extern": "decode64",
|
||||
"module": 0,
|
||||
"export": "x"
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "bdc1785c22876018049224778e3858b046cfbaad1169317de89bc5e22d1d46cb",
|
||||
"signature": "f88677c1b1e369f68e930b99cf403e6e7d88456dd11ce9d83bde8f88f60b5613eaf057e5530b2356b8ccedf462b2b4e330907ddbdf131f0f1cc5577c75d3b702"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 248032,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 0,
|
||||
"max": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "db162e5b9b78f0eb0ff9988798d5224d2fce210dcd1c64d7f9a297280039beae",
|
||||
"signature": "c4260104d12ba3c0baad5ee973db5c8d4e9f4f2df149fbeaccf4e456e48ed75023611cffc94328e9ea5bbf469c388dd8adecca4206cc186815cb95fc5b25770e"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 67108865,
|
||||
"fuel": {
|
||||
"used": 67356897,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 67108865,
|
||||
"fuel": 67108865,
|
||||
"max": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "4ec0a4e4db7be0d45ce463a896aa9fb3b44c3b465452956adf68e96876e018c0",
|
||||
"signature": "617f9909f5dbd9d25edd7b57bf5262ba0ead27eaf8b2ff06e680527229c8f37edf526a2435d5b9f631eea7b32cc87d886fc51e4f5dc8c251941c87e873801806"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 269783,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 21751,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "a8cccf2ac55c7b38c9d79c39632973d16edf0c30a9562e6e2320925695707c3b",
|
||||
"signature": "e4dc7b3e7b5c5ed75c8656363466e6a39cbe33651c6f06135400f87421f4796c03aec50b280717340d8bb0cab10192a6ad63aa0cf739861233c0f1afdc789505"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
},
|
||||
"x": 1
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "14d0220bed707653f2072608c81f8ff6681cb3ffcf0005b440818fcaa08ba680",
|
||||
"signature": "805417bb8001494fbd5588ae1f4e7012e36fd1a1be0d791c1c02538050d2961de7a8def653a12fd13f737d836d1c279b9090a26ade13dd8fe65c1428de70d60c"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "statevector",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "statevector",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "441385ba757f9a5db8c0299871049c51c39a6650212b33c47ea4622720bc9de2",
|
||||
"signature": "afd53deb5667de62981865b46e768c59629055926c5c0351e5c02ad3062a3d2c560235bd83c0ef289d449c278c05de94f57c47d38b618744f9b214b9f5fb910c"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/2",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "2daf5e56c89d2e829182a0f11eace97ae0e8870f810a1ffe952817d664307a1e",
|
||||
"signature": "3d99bec66c031477ba6427f6191b482a220f058ec1cd3529ea7355f1c2929735a2061e437b6fc8de86442eb77729aaf16e15a2086e0167979a197d0b359aa70d"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 3,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "992a20a6788ae3dade8cdfa90e798fed53867f2d05189cde9cf2a9d4b14706fa",
|
||||
"signature": "65d3cab9ccdbd288f3819c9c5b46bc9e3259148a349a8d0780622b161564f28fac036d94a63d68ebdd72ee6c3f0f151dfa91fbe94f20f644cd2cfd4d5d7ebb0d"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "statevector",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
|
||||
"bytes": 57,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 400,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 9,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 32,
|
||||
"shots_run": 0,
|
||||
"seed": 9,
|
||||
"counts": {},
|
||||
"callouts": 1,
|
||||
"fuel": {
|
||||
"used": 400,
|
||||
"instances": 0,
|
||||
"budget": {
|
||||
"per_call": 400,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 1,
|
||||
"fuel": 400,
|
||||
"max": 400
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "fuel_exhausted",
|
||||
"shot": 0,
|
||||
"phase": "call",
|
||||
"module": "m",
|
||||
"fuel": 400,
|
||||
"callout": "f",
|
||||
"budget": "call"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "9cab411ba32a647e5c4b0ce53609a4308c1a07bd26c817fca582e3e04258bff4",
|
||||
"signature": "c939aab422b5bf97f2abb4264df90c7aa2c69287570ed177edaa1a2fad8c4ddc9ea3758ee11cea21341c84a9d4eb47da4549431f32c9d8adbfe2721ade007a07"
|
||||
}
|
||||
},
|
||||
"id": "j-another"
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"fault": null,
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "354d530ddc5ecbec7050d0d7c398342b5bf4ca203756a6110762059337d9236b",
|
||||
"signature": "464dfe6c951e6260f6dca0c835a798e303b1f2b8d9bda4cf6ef40b59acfc532925f8cd55c22b246b652f2e98f2aaf2096bdbed8c4b14b6dd8638046afab46603"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
|
||||
"bytes": 57,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 400,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 9,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 32,
|
||||
"shots_run": 0,
|
||||
"seed": 9,
|
||||
"counts": {},
|
||||
"callouts": 1,
|
||||
"fuel": {
|
||||
"used": 400,
|
||||
"instances": 0,
|
||||
"budget": {
|
||||
"per_call": 400,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 1,
|
||||
"fuel": 400,
|
||||
"max": 400
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "0101d6548d258cfee420ce019df99a45ba980ec6bb92fded0b69b8a1d514de7f",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "out_of_fuel",
|
||||
"shot": 0,
|
||||
"phase": "call",
|
||||
"module": "m",
|
||||
"fuel": 400,
|
||||
"callout": "f"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "c38a68561b19ab771e54e6c34db5fbe78de3d4b4794cf7eb5a2affd74bd14d6b",
|
||||
"signature": "3b4c8eacc2bd7df3a4d9ecf284d7f333013e0d296cdbc496d09501888c45e9706a77809426b6b88b712e48bbe9fd625ac91b547b800755f2449b1d7ee5b8f405"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "3b1d20813e1400bcb189647a563054d2b7af6c392b4dfc0a94e377d20600137d",
|
||||
"signature": "327b8d73f295ed0a61f5c9352bc194c3a69746dd20f1af4d3aae650bac97076b8d188e9588f6a1dc844a26558e46c7ba18366e097b53ff9d985f2453f826610e"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
|
||||
"bytes": 50,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1,
|
||||
"shots": 4,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 4,
|
||||
"shots_run": 0,
|
||||
"seed": 1,
|
||||
"counts": {},
|
||||
"callouts": 1,
|
||||
"fuel": {
|
||||
"used": 2,
|
||||
"instances": 1,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 1,
|
||||
"fuel": 1,
|
||||
"max": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "1f9cfb398c872903d55e1962f50421060c42968e524e914e04bb0b971e4d0881",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "unreachable",
|
||||
"shot": 0,
|
||||
"phase": "init",
|
||||
"module": "m",
|
||||
"fuel": 1
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "ae7a6dc8dcb90b1060a50adb3bcf335906d9984e08ca0cd36d69bbab150213bd",
|
||||
"signature": "1ae288c8b53b9552f903443c9a2f650cba16dd2ab191b0c024e10276d6bd49e963a40d7b640179c2a0c3fc850df773fac2f52852d0174beca69f8d1d1b02bd0b"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "2bd6df6f77cff04a53312cc69ee9024ae6e445af9dd3a7d410cc5c8a18c0c4d0",
|
||||
"bytes": 105,
|
||||
"name": "m",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "024f67c0425a3dc02fbaf58cb93de5132e3d75c519faa0bada21491d88c97057",
|
||||
"bytes": 134217728,
|
||||
"name": "weights"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1,
|
||||
"shots": 4,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "6da2c86da1b3d288df324fa7902e4cb10c9c5b21160921907299402466c5d50c"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 4,
|
||||
"shots_run": 0,
|
||||
"seed": 1,
|
||||
"counts": {},
|
||||
"callouts": 0,
|
||||
"fuel": {
|
||||
"used": 8,
|
||||
"instances": 8,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "2bd6df6f77cff04a53312cc69ee9024ae6e445af9dd3a7d410cc5c8a18c0c4d0"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "3db8f511346d060c257940c086300666c8eb1b27c6083d36066b8d8f38e6408c",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "unreachable",
|
||||
"shot": 0,
|
||||
"phase": "prior",
|
||||
"module": "m",
|
||||
"fuel": 8
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "5dd5e46465d0286cb9acc026e233131fb1d04963f5d9e4169c31f2d8a1e41f44",
|
||||
"signature": "00636291efa15d23752e5057f5bb8e083867cdc4ae1c229f092eb3ee5636ba9c71d12c582f195f7723dbf3d00f8e1993a8bedb5c4d3964c64c0b27a1c8c74907"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
|
||||
"bytes": 57,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 400,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 9,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 32,
|
||||
"shots_run": 0,
|
||||
"seed": 9,
|
||||
"counts": {},
|
||||
"callouts": 1,
|
||||
"fuel": {
|
||||
"used": 10,
|
||||
"instances": 0,
|
||||
"budget": {
|
||||
"per_call": 400,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 1,
|
||||
"fuel": 10,
|
||||
"max": 10
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "f4cc7113b6c3237834200520bf45efee02d8308e3f23df558d51744f4c3cd176",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "fuel_exhausted",
|
||||
"shot": 0,
|
||||
"phase": "call",
|
||||
"module": "m",
|
||||
"fuel": 10,
|
||||
"callout": "f",
|
||||
"budget": "call"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "73f5e4f2f5432960fd96597f4ebdaab949a42e000e928f46f212a72e1f228cd9",
|
||||
"signature": "26b4495af949987c4e2d94a4dca1d38111414c7bbfe4f04c269abf3f7f71fe1a944aca17345c85fd46f6b05281cab2343df7e44aab53afa59d0ca77c7b6e6801"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
|
||||
"bytes": 57,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 400,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 100
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 9,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 32,
|
||||
"shots_run": 0,
|
||||
"seed": 9,
|
||||
"counts": {},
|
||||
"callouts": 1,
|
||||
"fuel": {
|
||||
"used": 400,
|
||||
"instances": 0,
|
||||
"budget": {
|
||||
"per_call": 400,
|
||||
"per_job": 100,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 1,
|
||||
"fuel": 400,
|
||||
"max": 400
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "fuel_exhausted",
|
||||
"shot": 0,
|
||||
"phase": "call",
|
||||
"module": "m",
|
||||
"fuel": 400,
|
||||
"callout": "f",
|
||||
"budget": "call"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "a52c41a705873742fc38fcbbd2e9c63d7e8afd3afd4a693001dceac368dfc330",
|
||||
"signature": "90784ba730c4a7bf618b2193ec8f215330f65c45b047e5d2da16337a0f5e5c4cb3d3ee82963c429e61bfefb5b218c7d3ba76f322a6b5f169be6226b12906930a"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248033,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "f3ca37425506d722cbad2ee337cdfc0e8c894bc4b75091e680130de1a94a2223",
|
||||
"signature": "3454dfda2f0409e93d6f07404750f54e2809648cc065ce54d676dac5de6a9583099cff05f0c9780b0f83361b61213a1f5187eec93725b3088df35088dcfc8803"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "a0a28225df247910039d0693ff2dfb69d3b012487e81fc449486dd5b9afc3fd7",
|
||||
"bytes": 231,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "1c79196a4e25b4f73f53a8327d9ab5d4d1644040f6b5036bb34aa1d456f2ee28",
|
||||
"bytes": 3346,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 8000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 77,
|
||||
"shots": 16,
|
||||
"state": "job"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3691fd8cac6fffe58d46a496aeff248a40d654129fe8cd23bae3dd6d3cebf8f4"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 47,
|
||||
"shots": 16,
|
||||
"shots_run": 16,
|
||||
"seed": 77,
|
||||
"counts": {
|
||||
"000000000000000000000000000000000000000000000000000000000000000000000000001001110011": 1,
|
||||
"000000000000000000000000000000000000000000000000000000000000010000000000011110000000": 1,
|
||||
"000000000000000000000000000000000000000000000000000001000000010000000010110100000000": 1,
|
||||
"000000000000000000000000000000000000000000000000000010001000000101000010010010101001": 1,
|
||||
"000000000000000000000000000000000000000000000000010000000100000100001001000110000100": 1,
|
||||
"000000000000000000000000000000000000000000000000100000000100000100001010000110100100": 1,
|
||||
"000000000000000000000000000000000000000000000001000000000000011000000010010000001110": 1,
|
||||
"000000000000000000000000000000000000000000000010100000000000000010001110000110101111": 1,
|
||||
"000000000000000000000000000000000000001000000000000000000000000000100000001111010111": 1,
|
||||
"000000000000000000000001100000000000000000000010000000000000010010000100010111100001": 1,
|
||||
"000000000000011000110000000000000000000000000000000000011000000001000001000101001011": 1,
|
||||
"000000000000011000110000000000000000000000000000000100011000010000000101010101100000": 1,
|
||||
"000000011000110000000000000000000000000000000100001000000000000000010001000110010001": 1,
|
||||
"001010001100000000000000000000000000000001000010000000000000000000000100001000010110": 1,
|
||||
"001100000000000000000000000000000000000010100000000000000000001000110000001001110110": 1,
|
||||
"110000000000000000000000000000000000001000000000000001000000000000100010100100011000": 1
|
||||
},
|
||||
"callouts": 16,
|
||||
"fuel": {
|
||||
"used": 765610,
|
||||
"instances": 24078,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 8000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 16,
|
||||
"fuel": 741532,
|
||||
"max": 57659
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "eb5252076ea8bb4c45ccec714a3cc64b89e833fe0a49c36a28881b63b1c3799e",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "1c206e03bf6f101beb5edb5980d56dc39ef1fccc6eceef5f7bcd13b75b497c3b",
|
||||
"signature": "e75ea79d367fddcca67ab5453a84b17dad3806846f038c14c58345cee4dfe73a461302a3c5e89c3216495e9d0f3ca6087c32b20b833e9917249c94c3af77050d"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
|
||||
"bytes": 50,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1,
|
||||
"shots": 4,
|
||||
"state": "job"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 4,
|
||||
"shots_run": 2,
|
||||
"seed": 1,
|
||||
"counts": {
|
||||
"0": 2
|
||||
},
|
||||
"callouts": 2,
|
||||
"fuel": {
|
||||
"used": 4,
|
||||
"instances": 2,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 2,
|
||||
"fuel": 2,
|
||||
"max": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "1f9cfb398c872903d55e1962f50421060c42968e524e914e04bb0b971e4d0881",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "unreachable",
|
||||
"shot": 2,
|
||||
"phase": "init",
|
||||
"module": "m",
|
||||
"fuel": 1
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "cd3556fb381a67b108d6755354fe8d87ad1c42728a0068dd3a6a4bfed05ebf43",
|
||||
"signature": "7e7bb2e459d68477764542d4955ddab660bbf64ea95d2a24bd4ab0bc9b4c64404adf7960192027380711559b42b0e38ac2de6974f02bd030eaa5c80e5d950a0f"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
|
||||
"bytes": 50,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1,
|
||||
"shots": 4,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 4,
|
||||
"shots_run": 1,
|
||||
"seed": 1,
|
||||
"counts": {
|
||||
"0": 1
|
||||
},
|
||||
"callouts": 1,
|
||||
"fuel": {
|
||||
"used": 2,
|
||||
"instances": 1,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 1,
|
||||
"fuel": 1,
|
||||
"max": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "1f9cfb398c872903d55e1962f50421060c42968e524e914e04bb0b971e4d0881",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "unreachable",
|
||||
"shot": 1,
|
||||
"phase": "init",
|
||||
"module": "m",
|
||||
"fuel": 2
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "cfc4ab8a2ac1e68009697a596ef65943ab215d888a1ced72b16bce0770b4d88d",
|
||||
"signature": "94de72874b843958e61c1f79d4274feca3536b6d8cb504be1c22993312d1df540e7bec8a0c919e3c67e34da03c51ffd5c858600a180e68f9d3f0cd6c96248b04"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 0,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "cd573b96d3b69c2044b06d60be8913abb651fdd09a6c71af5c364a0f511a17f7",
|
||||
"signature": "3c91f0be4f76a74b87ae1e4140822462c263e63b9a9b84096731f3260057fe22c76afcba184c53420c3ba00ffa30370ff2b00fdf5949e378adb303110331060a"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "abababababababababababababababababababababababababababababababab"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "d7b11e29fe5bea4e68237efac286ff6c45b52f74118fb179895f91c0528e0f94",
|
||||
"signature": "62cdcd744588c9a569420ad8d075cb579f89e50fd4ab41ea6889a90b4a5d01dec7205245684aafd409823ade469fede4f858436988c813526e80a56e8459d60d"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 0,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "44773b725087f65952c9e578798e1827a0fed4f5169e8e7e5508b6163771797b",
|
||||
"signature": "a4fcebc636f016322d061a0908dfc7c0f79fdfd2aeda2a877a12929616298927c92bd7d0e5548e1b25c6769c40c70cc238d34ee4a2d5f337cad3711678d69602"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 31,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 3,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "9a071896c902c5b761037264068dd5091628d88f908a91009ced24bce3cc6902",
|
||||
"signature": "2be8d8084fa580eae554d50066c7a342ca51685c8836b511140a347484b796742c9ee52fdec69a295f4d089ada18af2d5210f02fd40b7a4c766183d83312410c"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
|
||||
"bytes": 50,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1,
|
||||
"shots": 4,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 4,
|
||||
"shots_run": 0,
|
||||
"seed": 1,
|
||||
"counts": {},
|
||||
"callouts": 0,
|
||||
"fuel": {
|
||||
"used": 1,
|
||||
"instances": 1,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "1f9cfb398c872903d55e1962f50421060c42968e524e914e04bb0b971e4d0881",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "unreachable",
|
||||
"shot": 0,
|
||||
"phase": "prior",
|
||||
"module": "m",
|
||||
"fuel": 1
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "f7ccd98fc1b31bc3ba2a488bb2b96a4ac8387ad99d9f51408d78c5dffe8754ed",
|
||||
"signature": "ea2cddbe43f18b519487586c21bae5ff3ecd5449d2dd699946f95b0c0ee7845662b799cfc52c78be35e625d502afca357a904ae5b2ee1888af28e832764ae70b"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 89,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 591228,
|
||||
"instances": 2880,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 89
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "8992cecec525170cd95d696169802c2c793f40ffe87a9a9cc9dd9e8945a6b36d",
|
||||
"signature": "28d3e413d5b8c57c4ad1767c4eb577794c86441700e3cf1a38a61b03830dae036ec718a6dfbd88749e5b2ff535afa561fc288e473b67aa45b8009153f8f5ea0c"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 591227,
|
||||
"instances": 2879,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "8e6877a12e97c1b014543253c8f4efda9575b8a83677e1ce0eb667aad7d8232e",
|
||||
"signature": "c06e25a6bd6839ce02f19378097867e5c0e44d2cf9b20de2673e4e797d06cd979aed1b8c15c7d43ece78dde6ec55408fa7f95717033bef4f8171db88d853d100"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 0,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "1d897b197a92ccb06456d13ec048db95cb4ef3ff7baf7d8b6af3b9a081998673",
|
||||
"signature": "5978b536b336e3537a11f17ef7e969a50be122e74d7e5d4478840fd4742f821bbc64b491cfb3acb67b262f92629b4d6d7668ed5edcfe9d4d3f982825455bd804"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236",
|
||||
"x": 1
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "d70fdae9305fcc22843ecb996e95e0f2f55d2012575a5f3018885a5db1d0bdf0",
|
||||
"signature": "ff922f40dc484319c3c7565f737bcd821486db77fcecceeb8a6062f18b0eeff76b5f935cc27b65c354c3a07e9ee63bb86d4e764c17de7447e5079bd5df882706"
|
||||
}
|
||||
}
|
||||
}
|
||||
110
wai/quantum-conformance/receipts/jobs/crafted-wasmq-respelt.json
Normal file
110
wai/quantum-conformance/receipts/jobs/crafted-wasmq-respelt.json
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32.0,
|
||||
"\u0073tate": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 3.2e1,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "df6d2e83f44afa7db6d7c6a3d4791443525b1778b794023326296050cb47dcb1",
|
||||
"signature": "1ea3250661d07afe9e5f0bac876186cb6fb93ff2c9595e1f4d41c1bb7f9b0674d0146f9329a24d3b22c74d666f3f63329b19970c9ee90eb199f448e7a0e13a01"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"note": "a member the profile does not write",
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "593a9e2ccb96f59a8b95be3f8193085275245e40c3625923047dcbde34334531",
|
||||
"signature": "71a8617693a99ad90f38e61edcd1dc1f04bfe8090adc19e07f5aa0436f83c63597e7702c2b158140963183b0715b46b0843343825ed93952ac1830ea986dfd0a"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1235,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "f7d44a5e34e72ecfff5410ca0aadc927fbc4fca15eca88db2c4b4d8c845419b3",
|
||||
"signature": "4309cc7a5ef605a8363d663e5bcf669ee7735f29f7f81f3affa6a19a99732cf85bdb9b0b43b1f07cac0110174b47598dd482c1e0048465dd3b16be57fd8dd906"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43",
|
||||
"bytes": 68,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 50
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1,
|
||||
"shots": 1048576,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "0a19542a6a9178984a93d9863a1d5e9371e00b86c6e9143e04b5f0fb5b0be177"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 1048576,
|
||||
"shots_run": 2,
|
||||
"seed": 1,
|
||||
"counts": {
|
||||
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": 2
|
||||
},
|
||||
"callouts": 3,
|
||||
"fuel": {
|
||||
"used": 50,
|
||||
"instances": 0,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 50,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 3,
|
||||
"fuel": 50,
|
||||
"max": 23
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "3772395e9bb2f9fba3b1a7ef4f5def3e5f10f76a9ba517d16056e5fd7cb7d413",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "fuel_exhausted",
|
||||
"shot": 2,
|
||||
"phase": "call",
|
||||
"module": "m",
|
||||
"fuel": 4,
|
||||
"callout": "f",
|
||||
"budget": "run"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "5c0940231cdea3e717c8f4a21dc9b8cb6c5e7a2a05a95daf14ead02e4dba8e21",
|
||||
"signature": "1ecb47df023cab2f4085bb6c6d3a81b8c62f89a94e33496f82fca9065a3cf3e8fd43610750fd3a799c9492ffe30a8c5c72e63f6b7f18d82c064520a8b2ae7307"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43",
|
||||
"bytes": 68,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 60
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1,
|
||||
"shots": 8,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "0a19542a6a9178984a93d9863a1d5e9371e00b86c6e9143e04b5f0fb5b0be177"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 8,
|
||||
"shots_run": 2,
|
||||
"seed": 1,
|
||||
"counts": {
|
||||
"0101101101011011": 1,
|
||||
"1011111010111110": 1
|
||||
},
|
||||
"callouts": 3,
|
||||
"fuel": {
|
||||
"used": 50,
|
||||
"instances": 0,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 60,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"f": {
|
||||
"calls": 3,
|
||||
"fuel": 50,
|
||||
"max": 23
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "3772395e9bb2f9fba3b1a7ef4f5def3e5f10f76a9ba517d16056e5fd7cb7d413",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "fuel_exhausted",
|
||||
"shot": 2,
|
||||
"phase": "call",
|
||||
"module": "m",
|
||||
"fuel": 4,
|
||||
"callout": "f",
|
||||
"budget": "run"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "39a21b49ebb0c7a9e22e2594c4b4afdb06edde9f68de01c275b65075984db36a",
|
||||
"signature": "8b70291f63f1fcd478991416cf2707046db92bac88b3658c1fc240eef45a1001d9549f23bd58211017455e83eb6835605a3148c16bd29997a509637265453a01"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 9007199254740992,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 9007199254740992,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "4db53dce118ecb83ec243bbce84c1ad5fc878cfb0e9ccc751b7bf0a1bdc79bc1",
|
||||
"signature": "d4fc00c7c1f5eaf7139f1e17f1d317406b56aabb3869716ab466078a7104463a68ba46b8f14c12498e57aebc2e9fff7b2e24e45450752ebce499e3ab1968920b"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
|
||||
"bytes": 50,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1,
|
||||
"shots": 4,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 4,
|
||||
"shots_run": 0,
|
||||
"seed": 1,
|
||||
"counts": {},
|
||||
"callouts": 0,
|
||||
"fuel": {
|
||||
"used": 1,
|
||||
"instances": 1,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "abababababababababababababababababababababababababababababababab",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "unreachable",
|
||||
"shot": 0,
|
||||
"phase": "init",
|
||||
"module": "m",
|
||||
"fuel": 1
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "061b0aec47ca7e32a6d1c05b4e965e8ca686230ec5ccd4334b369b5a20391584",
|
||||
"signature": "20846be21c6b161ebfda94b759e9cfaf45b2e2c5b80a55ec86a1e6d89815dd0139852aa20538d22e71322ec93453bbd51213cdc79ddd69d9ba514a3471b7ad0f"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069C26AC0BEBA900FEFB241E021DEC52C77356506CAD8FF39D3240C090D82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "630fd56edc1fbecb0936c3cfd47a2624b8fcc96a5dbae4c9226129f83a23e144",
|
||||
"signature": "a2311d8ae5cc18d25a0012a737b783e0dabf1cd3a1c3bcd5552dfb28ea8450ee9d56fbdea688c274b186732457c521b1f103ecc9b80814803ccf301fbcfb1300"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "f",
|
||||
"extern": "f",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
|
||||
"bytes": 50,
|
||||
"name": "m",
|
||||
"priors": []
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
|
||||
"bytes": 128,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 17179869184
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1,
|
||||
"shots": 4,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "fault",
|
||||
"method": "stabilizer",
|
||||
"qubits": 8,
|
||||
"shots": 4,
|
||||
"shots_run": 0,
|
||||
"seed": 1,
|
||||
"counts": {},
|
||||
"callouts": 0,
|
||||
"fuel": {
|
||||
"used": 1,
|
||||
"instances": 1,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 17179869184,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "m",
|
||||
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "f4af8469005fcf8eeefc686a9394562530230ccb29bbfaae324cb7cb9343a4e4",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"fault": {
|
||||
"reason": "unreachable",
|
||||
"shot": 0,
|
||||
"phase": "init",
|
||||
"module": "m",
|
||||
"fuel": 0
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "56763e6f0af29fe7abaa4776dc1c76b0e6f33dbf911bbeefce8d7d92b888fd34",
|
||||
"signature": "9a83c80f27c98966065f554c176977cc11b1372773bc6560ec4b8b0a7a9ef377e14b2828d7691fa0819f8c3f0307a3926fb989f4e325705c5bf5d7f6d04b020a"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"status": "done",
|
||||
"method": "stabilizer",
|
||||
"request": {
|
||||
"wasmq": {
|
||||
"callouts": [
|
||||
{
|
||||
"export": "decode64",
|
||||
"extern": "decode64",
|
||||
"module": 0
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
|
||||
"bytes": 39442,
|
||||
"name": "qldpc-decoder",
|
||||
"priors": [
|
||||
{
|
||||
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
|
||||
"bytes": 87,
|
||||
"name": "checks"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"program": {
|
||||
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
|
||||
"bytes": 1104,
|
||||
"inputs": {}
|
||||
},
|
||||
"run": {
|
||||
"fuel": {
|
||||
"per_call": 10000000,
|
||||
"per_instance": 100000000,
|
||||
"per_job": 549755813888
|
||||
},
|
||||
"method": "stabilizer",
|
||||
"seed": 1234,
|
||||
"shots": 32,
|
||||
"state": "shot"
|
||||
}
|
||||
},
|
||||
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
|
||||
},
|
||||
"result": {
|
||||
"format": "wai.quantum.wasmq.result/1",
|
||||
"profile": "wai.quantum.wasmq/1",
|
||||
"status": "ok",
|
||||
"method": "stabilizer",
|
||||
"qubits": 17,
|
||||
"shots": 32,
|
||||
"shots_run": 32,
|
||||
"seed": 1234,
|
||||
"counts": {
|
||||
"000000000000000000000000001001": 3,
|
||||
"000000000000000000000000001010": 2,
|
||||
"000000000000000000000000001011": 4,
|
||||
"000000000000000000000000001101": 2,
|
||||
"000000000000000000000000001110": 2,
|
||||
"000000000000000000000000001111": 1,
|
||||
"000000000000000000000100010000": 4,
|
||||
"000000000000000000010010000010": 2,
|
||||
"000000000000000000100001010011": 2,
|
||||
"000000000000000001000000110100": 2,
|
||||
"000000000000000010000010100101": 2,
|
||||
"000000000000000100000001000110": 3,
|
||||
"000000011000000000000100010001": 2,
|
||||
"110000000000001000000000101000": 1
|
||||
},
|
||||
"callouts": 32,
|
||||
"fuel": {
|
||||
"used": 836380,
|
||||
"instances": 248032,
|
||||
"budget": {
|
||||
"per_call": 10000000,
|
||||
"per_job": 549755813888,
|
||||
"per_instance": 100000000
|
||||
},
|
||||
"callouts": {
|
||||
"decode64": {
|
||||
"calls": 32,
|
||||
"fuel": 588348,
|
||||
"max": 21751
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "qldpc-decoder",
|
||||
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
|
||||
}
|
||||
],
|
||||
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
|
||||
"accuracy": {
|
||||
"class": "exact"
|
||||
},
|
||||
"energy": {
|
||||
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
|
||||
},
|
||||
"receipt": {
|
||||
"alg": "ed25519",
|
||||
"canon": "rfc8785",
|
||||
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
|
||||
"digest": "eed9dde93614e853b2944351ff11bb3f0e5707493f82fcc901f8db7ced11ae5f",
|
||||
"signature": "25dbf3e5c4672c479054261b06bb76028fa023712eef2618e859e518e8026da763e9c349049a4b4945ffa92fcbc616dec0b97d2c8effd0f29c1553e6c7617105"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,12 @@
|
|||
"cli-run-trajectories.json": "c41c35bb5384d3582d83450f7b3d38225be2d353e4e3ad71e49a82c306656ede",
|
||||
"cli-set-programs.json": "81059f216b449468ac4ab6803de72a0a5f894458cb178eae15f2abf42bfd2437",
|
||||
"cli-set-sweep.json": "2b9af76474074a522ac5404c2de07a2b307620ce56e413b2319523b26fd168e1",
|
||||
"cli-wasmq-fault-init.json": "be0c62291b21d35cdf10955dc3611913b6fdc824561d14ce509fecceeee98465",
|
||||
"cli-wasmq-fault-prior.json": "47e497cf002051e090161a4eaa70933d46f2ecb56dbacdf05f83ecf74f67a065",
|
||||
"cli-wasmq-fault-run.json": "00367bd6ff66f4d8f354dbb1f5c8e3519687924ab0e871800815a9d7e4943b8d",
|
||||
"cli-wasmq-fault.json": "f86dc76d54591e765f4609adfe2e817e775421094c0b4d23284c54d9fc9a0122",
|
||||
"cli-wasmq-run.json": "09c757a4739e448945cad383391d4c8cae140c678293a95af72d1d334cef214f",
|
||||
"cli-wasmq-state-job.json": "cc2820d766d8b90f4e7fa3dc7b5d8528e500fc58555834ac870f83844f06b280",
|
||||
"first-form-service-observables.json": "098a720239f1757bb7ae7ceb8e35f7e0c30c91bb5fa7c977aef9aec02b855fa9",
|
||||
"first-form-service-run.json": "f21a23fd33df0ec4c540bbc341c4296aeb4612bc4b9e58044604cbd19521a535",
|
||||
"fixture-compile-legacy.json": "04c53ef2b350a4cdbd5f42deb8c44a91a1616a05c498a30f2f9cecd9c7402bca",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
# the ones it was given, and never makes them again to pass a test.
|
||||
set -euo pipefail
|
||||
B=$(cd "$(dirname "$1")" && pwd -P)/$(basename "$1")
|
||||
ENVELOPES=$(cd "$(dirname "$0")/../wasmq/envelopes" && pwd -P)
|
||||
OUT=$(mkdir -p "$2" && cd "$2" && pwd -P)
|
||||
W=$(mktemp -d)
|
||||
trap 'rm -rf "$W"' EXIT
|
||||
|
|
@ -33,6 +34,9 @@ printf 'OPENQASM 3.0;\ninclude "stdgates.inc";\nqubit[1] q;\nrx(0.4) q[0];\n' >
|
|||
printf 'OPENQASM 3.0;\ninclude "stdgates.inc";\ninput float theta;\nqubit[1] q;\nbit[1] c;\nrx(theta) q[0];\nc = measure q;\n' > theta.qasm
|
||||
"$B" run bell.qasm --program three.qasm --shots 64 --seed 3 --demo-key --json > "$OUT/cli-set-programs.json"
|
||||
"$B" run theta.qasm --sweep theta=0.25,0.5,1.5 --shots 64 --seed 9 --demo-key --json > "$OUT/cli-set-sweep.json"
|
||||
for pair in run:surface3-decode64 state-job:surface5-decode64-job fault:fault-fuel fault-run:fault-fuel-run fault-init:fault-in-init fault-prior:fault-in-prior; do
|
||||
"$B" run "$ENVELOPES/${pair#*:}.wai" --demo-key --json > "$OUT/cli-wasmq-${pair%%:*}.json"
|
||||
done
|
||||
"$B" submit bell.qasm --shots 200 --seed 11 --json > "$OUT/service-run.json"
|
||||
"$B" submit bell.qasm --shots 200 -o "Z0 Z1" --json > "$OUT/service-run-stabilizer.json"
|
||||
for f in "$OUT"/cli-*.json "$OUT"/service-*.json; do "$B" verify "$f" > /dev/null || { echo "make.sh: $f does not verify" >&2; exit 1; }; done
|
||||
|
|
|
|||
|
|
@ -55,6 +55,42 @@
|
|||
"made_by": "made",
|
||||
"what": "the command line: a sweep of an input at three points, sealed as a set"
|
||||
},
|
||||
{
|
||||
"file": "jobs/cli-wasmq-fault-init.json",
|
||||
"reasons": [],
|
||||
"made_by": "made",
|
||||
"what": "the command line: a wasmQ run that stopped in an instance's init"
|
||||
},
|
||||
{
|
||||
"file": "jobs/cli-wasmq-fault-prior.json",
|
||||
"reasons": [],
|
||||
"made_by": "made",
|
||||
"what": "the command line: a wasmQ run that stopped while a module read its prior"
|
||||
},
|
||||
{
|
||||
"file": "jobs/cli-wasmq-fault-run.json",
|
||||
"reasons": [],
|
||||
"made_by": "made",
|
||||
"what": "the command line: a wasmQ run that stopped in its third shot when the run's fuel ran out"
|
||||
},
|
||||
{
|
||||
"file": "jobs/cli-wasmq-fault.json",
|
||||
"reasons": [],
|
||||
"made_by": "made",
|
||||
"what": "the command line: a wasmQ run that stopped in a call past the call's fuel budget"
|
||||
},
|
||||
{
|
||||
"file": "jobs/cli-wasmq-run.json",
|
||||
"reasons": [],
|
||||
"made_by": "made",
|
||||
"what": "the command line: a wasmQ run, a surface-code round decoded by WebAssembly between its gates, 32 shots"
|
||||
},
|
||||
{
|
||||
"file": "jobs/cli-wasmq-state-job.json",
|
||||
"reasons": [],
|
||||
"made_by": "made",
|
||||
"what": "the command line: a wasmQ run of one instance for the whole run, its decoder reading a prior"
|
||||
},
|
||||
{
|
||||
"file": "jobs/first-form-service-observables.json",
|
||||
"reasons": [],
|
||||
|
|
@ -1162,6 +1198,354 @@
|
|||
"reasons": [],
|
||||
"made_by": "crafted",
|
||||
"what": "a class a verifier does not know: not a reason, since a later version may add one"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-counts-short.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ run whose counts add up to one shot fewer than it ran (rule 19)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-ok-before-all-shots.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ run that is ok after 31 of its 32 shots (rule 18)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-fuel-unaccounted.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ run whose instances and calls do not add up to the fuel it used (rule 15)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-fuel-past-job-budget.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ fault that used 400 fuel under a run's budget of 100 (rule 13)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-instances-past-budget.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "one instance for the whole run, given more fuel for its seed, init and prior than three stretches of 8000 (rule 17)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-fault-unnamed.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ fault of a reason the profile does not name (rule 18)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-result-member-added.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ result with a member the profile does not write (rule 9)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-contract-method.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ contract and result of a method the profile does not have (rule 8)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-seed-past-exact.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ seed of 2^53: a double holds it, so it is no inexact number, and the profile allows at most 2^53 - 1 (rules 1, 8)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-modules-other.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ result naming a module the contract does not pin (rule 16)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-transcript-upper.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ transcript digest in upper case (rule 12)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-first-form.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ job sealed in the first form, older than the profile: the seal holds, and no host wrote it (rule 10)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-call-fault-uncounted.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a call that stopped the run, which the fuel counts no call of: the stopped call is one of the calls made (rule 18)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-call-fault-past-largest.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a call that stopped after 400 fuel, where the most one call of it used is 399 (rule 18)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-request-member-added.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ request with a member the profile does not write (rule 2)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-contract-member-added.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ contract with a member section 2.2 does not list (rule 3)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-contract-profile.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ contract of another profile (rule 4)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-program-empty.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ contract whose program is 0 bytes long (rule 5)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-module-empty.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ contract whose module is 0 bytes long (rule 6)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-callouts-twice.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ contract with two callouts of one extern (rule 7)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-result-seed.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ result whose seed is not its contract's (rule 11)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-call-past-per-call.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ run whose largest call used 21751 fuel under a budget of 21750 a call (rule 14)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-calls-of-no-fuel.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "32 calls that returned having used no fuel, where entering a function weighs 1 (rule 20)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-priors-unpassed.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "32 shots of instances passed a prior of 87 bytes in less fuel than its bytes and its two calls take, cabi_realloc 2 at least and wasmq-prior 1 (rule 21)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-call-fault-other-module.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a call of a callout in the first module, whose fault names the second (rule 22)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-prior-fault-no-prior.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a fault while a prior is passed, in a module with no prior (rule 23)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-bad-result-in-init.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a bad_result from an init, which takes no result (rule 24)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-lifecycle-fuel-past-instances.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "an init fault in shot 1 that used 2 fuel, where the instances used 1, shot 0's init 1 of it at least (rule 25)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-job-state-later-instance.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a run of one instance for the run whose instance fails in shot 2 (rule 26)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-first-instance-after-call.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "the first shot's instance failing after a call was made, where no shot ran its steps (rules 27 and 32)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-fuel-fault-under-limit.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a call's fuel fault after 10 fuel, under its limit of 400 (rule 28)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-run-budget-not-spent.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a fault of the run's budget with 50 of its 60 used (rule 28)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-results-past-bits.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "2^20 shots of 257 bits, past the 2^28 bits a run's results hold (rule 29)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-work-past-bound.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a run given 2^39 fuel beside a module's code, past the 2^42 operations a run asks (rule 30)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-frames-past-envelope.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a prior of 2^27 bytes beside a program and a module, more than an envelope holds (rule 31)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-fault-null.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "an ok result with a fault member whose value is null: a member is present whatever its value (rule 18)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-no-qubit.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ result of a program of no qubit, which no program a reader reads is (rule 12)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-calls-under-largest.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "32 calls in 21751 fuel, where the most one of them used is 21751 and each other used 1 at least (rule 20)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-calls-past-steps.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "32 shots that made 2^21 calls each and one more, where a shot runs at most 2^21 steps (rule 32)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-prior-past-instance-budget.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a prior of 87 bytes passed whole in one stretch, which takes 90 at least, under a lifecycle call's budget of 89 (rule 33)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-trap-of-no-fuel.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "an init that trapped after no fuel, where its entry is charged before it runs (rule 34)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-transcript-of-no-call.json",
|
||||
"reasons": [
|
||||
"wasmq_form"
|
||||
],
|
||||
"made_by": "crafted",
|
||||
"what": "a fault before any call whose transcript is not the run's end alone (rule 35)"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-respelt.json",
|
||||
"reasons": [],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ job with its shots written 32.0 and 3.2e1 and a member of its contract named with an escape: the same sealed content"
|
||||
},
|
||||
{
|
||||
"file": "jobs/crafted-wasmq-envelope-changed.json",
|
||||
"reasons": [],
|
||||
"made_by": "crafted",
|
||||
"what": "a wasmQ fault whose unsealed body says done, another method and an id: a note beside the verdict, not a reason"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,14 +27,23 @@ of the reference, and changes nothing.
|
|||
(`receipt_verify.py --plant`), and succeeds only when the differential catches
|
||||
it: the proof that the check can fail.
|
||||
|
||||
`--second FILE` holds another second verifier (a mutant of receipt_verify.py) to the
|
||||
same stages; `--wasmq-only` keeps to what holds a wasmQ job (its receipts, their
|
||||
one-member changes, the rules stage and the labelled cases); `--first` stops at the
|
||||
first stage that disagrees; and `RD_CACHE=DIR` keeps each verifier's answers, so that a
|
||||
run over many mutants of one verifier asks the other once (`wasmq_mutants.py`).
|
||||
|
||||
Exit status 0 only when everything agrees (or, with --plant, when the plant is
|
||||
caught). Standard library only, Python 3.9+.
|
||||
"""
|
||||
import argparse
|
||||
import base64
|
||||
import copy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
|
@ -43,12 +52,24 @@ from collections import Counter
|
|||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
CORPUS = os.path.join(HERE, "..", "receipts")
|
||||
SECOND = os.path.join(HERE, "receipt_verify.py")
|
||||
ORIGINAL_SECOND = SECOND
|
||||
|
||||
|
||||
def compact(v):
|
||||
return json.dumps(v, ensure_ascii=False, separators=(",", ":"))
|
||||
|
||||
|
||||
def spelt(v, raw):
|
||||
"""A line of v's text, each `raw` literal as it is written."""
|
||||
if isinstance(v, raw):
|
||||
return v.literal
|
||||
if isinstance(v, dict):
|
||||
return "{" + ",".join(json.dumps(k, ensure_ascii=False) + ":" + spelt(x, raw) for k, x in v.items()) + "}"
|
||||
if isinstance(v, list):
|
||||
return "[" + ",".join(spelt(x, raw) for x in v) + "]"
|
||||
return compact(v)
|
||||
|
||||
|
||||
def verdicts(lines_text, json_lines):
|
||||
out = []
|
||||
for line in lines_text.splitlines():
|
||||
|
|
@ -60,29 +81,110 @@ def verdicts(lines_text, json_lines):
|
|||
return out
|
||||
|
||||
|
||||
def run_reference_files(ref, files):
|
||||
out = []
|
||||
for f in files:
|
||||
p = subprocess.run([ref, "verify", "--json", f], capture_output=True, text=True)
|
||||
if p.returncode not in (0, 1) or not p.stdout.strip():
|
||||
raise SystemExit("the reference failed on %s (status %d): %s" % (f, p.returncode, p.stderr.strip()[:400]))
|
||||
out.append(json.loads(p.stdout.strip().splitlines()[-1]))
|
||||
def _who(cmd):
|
||||
"""What decides a verifier's answers, for the cache: the reference binary (its path, size
|
||||
and time) and the mutant it is asked to be, or the second verifier's text and its plant."""
|
||||
h = hashlib.sha256()
|
||||
script = any(part.endswith(".py") for part in cmd)
|
||||
for part in cmd:
|
||||
h.update(part.encode() + b"\0")
|
||||
if part.endswith(".py") and os.path.isfile(part):
|
||||
with open(part, "rb") as f:
|
||||
h.update(f.read())
|
||||
elif os.path.isfile(part) and os.access(part, os.X_OK):
|
||||
st = os.stat(part)
|
||||
h.update(("%d %d" % (st.st_size, st.st_mtime_ns)).encode())
|
||||
if not script:
|
||||
h.update(os.environ.get("WQ_MUTANT", "").encode())
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def cached(cmd, inputs, compute):
|
||||
"""compute(), or what it gave before for the same verifier and the same inputs when
|
||||
RD_CACHE names a directory: a run of many mutants of one verifier asks the other the
|
||||
same questions each time."""
|
||||
d = os.environ.get("RD_CACHE")
|
||||
if not d:
|
||||
return compute()
|
||||
h = hashlib.sha256(_who(cmd).encode())
|
||||
for b in inputs:
|
||||
h.update(hashlib.sha256(b).digest())
|
||||
path = os.path.join(d, h.hexdigest() + ".json")
|
||||
try:
|
||||
with open(path, encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
except (OSError, ValueError):
|
||||
pass
|
||||
out = compute()
|
||||
os.makedirs(d, exist_ok=True)
|
||||
with open(path + ".tmp%d" % os.getpid(), "w", encoding="utf-8") as f:
|
||||
json.dump(out, f)
|
||||
os.replace(path + ".tmp%d" % os.getpid(), path)
|
||||
return out
|
||||
|
||||
|
||||
def _contents(files):
|
||||
out = []
|
||||
for f in files:
|
||||
with open(f, "rb") as h:
|
||||
out.append(h.read())
|
||||
return out
|
||||
|
||||
|
||||
def run_reference_files(ref, files):
|
||||
def compute():
|
||||
out = []
|
||||
for f in files:
|
||||
p = subprocess.run([ref, "verify", "--json", f], capture_output=True, text=True)
|
||||
if p.returncode not in (0, 1) or not p.stdout.strip():
|
||||
raise SystemExit("the reference failed on %s (status %d): %s" % (f, p.returncode, p.stderr.strip()[:400]))
|
||||
out.append(json.loads(p.stdout.strip().splitlines()[-1]))
|
||||
return out
|
||||
return cached([ref, "verify", "--json"], _contents(files), compute)
|
||||
|
||||
|
||||
def run_second_files(files, plant):
|
||||
cmd = [sys.executable, "-I", SECOND] + (["--plant", plant] if plant else []) + files
|
||||
p = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if p.returncode not in (0, 1):
|
||||
raise SystemExit("the second verifier failed (status %d): %s" % (p.returncode, p.stderr.strip()[:400]))
|
||||
return verdicts(p.stdout, len(files))
|
||||
cmd = [sys.executable, "-I", SECOND] + (["--plant", plant] if plant else [])
|
||||
|
||||
def compute():
|
||||
p = subprocess.run(cmd + files, capture_output=True, text=True)
|
||||
if p.returncode not in (0, 1):
|
||||
raise SystemExit("the second verifier failed (status %d): %s" % (p.returncode, p.stderr.strip()[:400]))
|
||||
return verdicts(p.stdout, len(files))
|
||||
return cached(cmd, _contents(files), compute)
|
||||
|
||||
|
||||
def run_lines(cmd, path, n):
|
||||
p = subprocess.run(cmd + [path], capture_output=True, text=True)
|
||||
if p.returncode not in (0, 1):
|
||||
raise SystemExit("%s failed (status %d): %s" % (cmd[0], p.returncode, p.stderr.strip()[:400]))
|
||||
return verdicts(p.stdout, n)
|
||||
def compute():
|
||||
p = subprocess.run(cmd + [path], capture_output=True, text=True)
|
||||
if p.returncode not in (0, 1):
|
||||
raise SystemExit("%s failed (status %d): %s" % (cmd[0], p.returncode, p.stderr.strip()[:400]))
|
||||
return verdicts(p.stdout, n)
|
||||
return cached(cmd, _contents([path]), compute)
|
||||
|
||||
|
||||
def rules_of(v):
|
||||
"""The numbers of the rules of a wasmQ job's form a verdict states as broken (each
|
||||
problem names its rule first), or None when it states none or only the first of many."""
|
||||
w = v.get("wasmq")
|
||||
if not isinstance(w, dict) or not isinstance(w.get("problems"), list):
|
||||
return None
|
||||
out = set()
|
||||
for p in w["problems"]:
|
||||
if not isinstance(p, str) or p.startswith("and "):
|
||||
return None
|
||||
m = re.match(r"rule (\d+): ", p)
|
||||
if not m:
|
||||
return None
|
||||
out.add(int(m.group(1)))
|
||||
return out
|
||||
|
||||
|
||||
def same_rules(what, x, y, problems):
|
||||
"""Both verifiers state the same rules broken, where both state them in full."""
|
||||
rx, ry = rules_of(x), rules_of(y)
|
||||
if rx is not None and ry is not None and rx != ry:
|
||||
problems.append("%s: the reference states rules %s broken; the second verifier %s" % (what, sorted(rx), sorted(ry)))
|
||||
|
||||
|
||||
def said(v):
|
||||
|
|
@ -217,6 +319,461 @@ def edges(body, seal):
|
|||
return out
|
||||
|
||||
|
||||
# ------------------------------------------------- the rules of a wasmQ job's form
|
||||
|
||||
def rule_cases(corpus, seal):
|
||||
"""(what, body, expected reasons): for each rule of quantum-wasmq section 6.5, the
|
||||
genuine wasmQ jobs of the corpus changed at the rule's bound, on both sides of it where
|
||||
it has two, and sealed again with the demo key, so that the rule alone decides. Each
|
||||
expected verdict is written here by hand from the text, as the manifest's are: none is
|
||||
copied from a verifier. A verifier with a rule dropped, or a bound moved, gives some
|
||||
case here another verdict."""
|
||||
def load(name):
|
||||
with open(os.path.join(corpus, "jobs", name), encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
run, fault, init, job, frun, prior = (load("cli-wasmq-%s.json" % n) for n in ("run", "fault", "fault-init", "state-job", "fault-run", "fault-prior"))
|
||||
out = []
|
||||
g = generator()
|
||||
|
||||
def case(rule, what, base, edit, valid, respell=None):
|
||||
b = copy.deepcopy(base)
|
||||
edit(b)
|
||||
# With no call returned, the transcript the writer gives the result as changed
|
||||
# (rule 35), unless the change was to the transcript.
|
||||
sealed = seal(g.retranscribed(base, b))
|
||||
if respell:
|
||||
# After the seal: another spelling of a number, not another value, so it holds.
|
||||
respell(sealed)
|
||||
sealed = spelt(sealed, g.Raw)
|
||||
out.append(("rule %s, %s" % (rule, what), sealed, [] if valid else ["wasmq_form"]))
|
||||
|
||||
def contract(b):
|
||||
return b["request"]["wasmq"]
|
||||
|
||||
def budget(name, value):
|
||||
def f(b):
|
||||
contract(b)["run"]["fuel"][name] = value
|
||||
b["result"]["fuel"]["budget"][name] = value
|
||||
return f
|
||||
|
||||
def stretches(b):
|
||||
return sum(2 + len(m["priors"]) for m in contract(b)["modules"])
|
||||
|
||||
def second_module(bytes0, bytes1, named=True):
|
||||
def f(b):
|
||||
c = contract(b)
|
||||
c["modules"][0]["bytes"] = bytes0
|
||||
c["modules"].append({"name": "second", "blake3": "cd" * 32, "bytes": bytes1, "priors": []})
|
||||
b["result"]["modules"].append({"name": "second", "blake3": "cd" * 32})
|
||||
if named:
|
||||
c["callouts"].append({"extern": "g", "module": 1, "export": "g"})
|
||||
return f
|
||||
|
||||
def each(*edits):
|
||||
def f(b):
|
||||
for e in edits:
|
||||
e(b)
|
||||
return f
|
||||
|
||||
def at(path, value):
|
||||
def f(b):
|
||||
o = b
|
||||
for k in path[:-1]:
|
||||
o = o[k]
|
||||
o[path[-1]] = value
|
||||
return f
|
||||
|
||||
def calls(b):
|
||||
(name, e), = b["result"]["fuel"]["callouts"].items()
|
||||
return e
|
||||
|
||||
def passed(b):
|
||||
# What passing every prior to one shot's instances takes at the least (rule 21):
|
||||
# cabi_realloc, 2 at least, its bytes, and wasmq-prior, 1 at least.
|
||||
return sum(p["bytes"] + 3 for m in contract(b)["modules"] for p in m["priors"])
|
||||
|
||||
def shots(n):
|
||||
def f(b):
|
||||
width = len(next(iter(b["result"]["counts"])))
|
||||
contract(b)["run"]["shots"] = b["result"]["shots"] = b["result"]["shots_run"] = n
|
||||
b["result"]["counts"] = {"1" * width: n}
|
||||
fuel = b["result"]["fuel"]
|
||||
more = max(0, n * passed(b) - fuel["instances"])
|
||||
fuel.update(instances=fuel["instances"] + more, used=fuel["used"] + more)
|
||||
return f
|
||||
|
||||
def later_shot(shot, state=None, instances=1, fuel=1, calls=None):
|
||||
# The init fault moved to `shot`, after that many shots of one call each.
|
||||
def f(b):
|
||||
n = shot if calls is None else calls
|
||||
if state:
|
||||
contract(b)["run"]["state"] = state
|
||||
b["result"].update(shots_run=shot, counts={"0": shot} if shot else {}, callouts=n)
|
||||
b["result"]["fuel"].update(instances=instances, callouts={"f": {"calls": n, "fuel": n, "max": 1}} if n else {}, used=instances + n)
|
||||
b["result"]["fault"].update(shot=shot, fuel=fuel)
|
||||
return f
|
||||
|
||||
def fault_module(name):
|
||||
def f(b):
|
||||
second_module(57, 57)(b)
|
||||
b["result"]["fault"]["module"] = name
|
||||
return f
|
||||
|
||||
def counts(width, n):
|
||||
return lambda b: b["result"].update(counts={"0" * width: n})
|
||||
|
||||
def work_left(b):
|
||||
# The most per_job the rest of rule 30's work leaves room for.
|
||||
c, r = contract(b), b["result"]
|
||||
n, s = r["qubits"], c["run"]["shots"]
|
||||
inst = 1 if c["run"]["state"] == "job" else s
|
||||
rest = s * 2 * n * max(1, -(-n // 32)) + inst * sum(4096 * (1 + 2 * len(m["priors"])) + m["bytes"] for m in c["modules"]) + 131072 * sum(m["bytes"] for m in c["modules"]) + 4097 * r["callouts"]
|
||||
return (2 ** 42 - rest) // 8
|
||||
|
||||
def frames(b):
|
||||
c = contract(b)
|
||||
return c["program"]["bytes"] + sum(m["bytes"] + sum(p["bytes"] for p in m["priors"]) for m in c["modules"])
|
||||
|
||||
def most_prior(b):
|
||||
# The most bytes the first prior may have: 2^27 less the envelope's other bytes, its
|
||||
# magic and lengths, its manifest, its contract and its other frames (rule 31).
|
||||
c, r = contract(b), b["result"]
|
||||
c["modules"][0]["priors"][0]["bytes"] = 10 ** 8
|
||||
manifest = 192 + sum(len(str(x)) for x in (r["qubits"], c["run"]["shots"], c["run"]["seed"]))
|
||||
rest = 20 + manifest + len(g.text(c).encode("utf-8")) + frames(b) - 10 ** 8
|
||||
return 2 ** 27 - rest
|
||||
|
||||
def calls_of(n, max_fuel=1):
|
||||
# n calls of the run's one callout, each of 1 but the most.
|
||||
def f(b):
|
||||
b["result"]["callouts"] = n
|
||||
calls(b).update(calls=n, fuel=n - 1 + max_fuel, max=max_fuel)
|
||||
b["result"]["fuel"]["used"] = b["result"]["fuel"]["instances"] + calls(b)["fuel"]
|
||||
return f
|
||||
|
||||
def own_prior(nbytes):
|
||||
# The first module given a prior of nbytes.
|
||||
return lambda b: contract(b)["modules"][0].update(priors=[{"name": "p", "blake3": "ef" * 32, "bytes": nbytes}])
|
||||
|
||||
def fault_of(reason, fuel):
|
||||
# The call's fault of `fault`, stopped for reason after fuel.
|
||||
def f(b):
|
||||
b["result"]["fault"].update(reason=reason, fuel=fuel)
|
||||
b["result"]["fault"].pop("budget", None)
|
||||
calls(b).update(calls=1, fuel=fuel, max=fuel)
|
||||
b["result"]["fuel"]["used"] = fuel
|
||||
return f
|
||||
|
||||
def own_fuel(delta):
|
||||
def f(b):
|
||||
e = calls(b)
|
||||
e["fuel"] = e["max"] + delta
|
||||
b["result"]["fuel"]["used"] = b["result"]["fuel"]["instances"] + e["fuel"]
|
||||
return f
|
||||
|
||||
R, F = ("result",), ("result", "fuel")
|
||||
# 1: no number past 2^53 - 1 (it breaks another rule too: each place a number may be holds it)
|
||||
case(1, "an input of 2^53", run, lambda b: contract(b)["program"].update(inputs={"n": 2 ** 53}), False)
|
||||
# 2: the request
|
||||
case(2, "a member the request does not define", run, at(("request", "x"), 1), False)
|
||||
case(2, "envelope_blake3 not a digest", run, lambda b: b["request"].update(envelope_blake3=b["request"]["envelope_blake3"].upper()), False)
|
||||
# 3, 4: the contract's members and profile
|
||||
case(3, "a member the contract does not define", run, lambda b: contract(b).update(x=1), False)
|
||||
case(3, "a member the run does not define", run, lambda b: contract(b)["run"].update(x=1), False)
|
||||
case(4, "another profile", run, lambda b: contract(b).update(profile="wai.quantum.wasmq/2"), False)
|
||||
# 5: the program
|
||||
case(5, "a program of 2^20 bytes", run, lambda b: contract(b)["program"].update(bytes=2 ** 20), True)
|
||||
case(5, "a program of 2^20 + 1 bytes", run, lambda b: contract(b)["program"].update(bytes=2 ** 20 + 1), False)
|
||||
case(5, "a program of 0 bytes", run, lambda b: contract(b)["program"].update(bytes=0), False)
|
||||
case(5, "a program of 1 byte", run, lambda b: contract(b)["program"].update(bytes=1), True)
|
||||
case(5, "an input of 2^53 - 1", run, lambda b: contract(b)["program"].update(inputs={"n": 2 ** 53 - 1}), True)
|
||||
case(5, "an input of -(2^53 - 1)", run, lambda b: contract(b)["program"].update(inputs={"n": -(2 ** 53 - 1)}), True)
|
||||
case(5, "an input of 0.5", run, lambda b: contract(b)["program"].update(inputs={"n": 0.5}), False)
|
||||
# 6: the modules and their priors
|
||||
case(6, "a module of 1 byte", run, lambda b: contract(b)["modules"][0].update(bytes=1), True)
|
||||
case(6, "a module of 0 bytes", run, lambda b: contract(b)["modules"][0].update(bytes=0), False)
|
||||
case(6, "a prior of 0 bytes", run, lambda b: contract(b)["modules"][0]["priors"][0].update(bytes=0), True)
|
||||
case(6, "a prior of 0.5 bytes", prior, lambda b: contract(b)["modules"][0]["priors"][0].update(bytes=0.5), False)
|
||||
case(6, "a module of 2^19 bytes", run, lambda b: contract(b)["modules"][0].update(bytes=2 ** 19), True)
|
||||
case(6, "a module of 2^19 + 1 bytes", run, lambda b: contract(b)["modules"][0].update(bytes=2 ** 19 + 1), False)
|
||||
case(6, "a module's priors null", run, lambda b: contract(b)["modules"][0].update(priors=None), False)
|
||||
case(6, "a prior's name null", run, lambda b: contract(b)["modules"][0]["priors"][0].update(name=None), False)
|
||||
case(6, "a module's name null, alike in the result", run, lambda b: (contract(b)["modules"][0].update(name=None), b["result"]["modules"][0].update(name=None)), False)
|
||||
case(6, "modules of 2^19 bytes together", run, second_module(2 ** 18, 2 ** 18), True)
|
||||
case(6, "modules of 2^19 + 1 bytes together", run, second_module(2 ** 18, 2 ** 18 + 1), False)
|
||||
# 7: the callouts
|
||||
case(7, "a module no callout names", run, second_module(39442, 1, named=False), False)
|
||||
case(7, "two callouts of one extern", run, lambda b: contract(b)["callouts"].append({"extern": "decode64", "module": 0, "export": "x"}), False)
|
||||
case(7, "a callout of a module the contract does not hold", run, lambda b: contract(b)["callouts"][0].update(module=1), False)
|
||||
case(7, "a callout of the module past the last, beside one of each module", run, lambda b: contract(b)["callouts"].append({"extern": "g", "module": 1, "export": "g"}), False)
|
||||
case(7, "a callout of the last module, beside one of each module", run, second_module(39442, 57), True)
|
||||
# No module and no callout: rule 7's first clause alone holds it, its others vacuous.
|
||||
def nothing(b):
|
||||
contract(b).update(modules=[], callouts=[])
|
||||
b["result"].update(modules=[], callouts=0)
|
||||
b["result"]["fuel"].update(callouts={}, instances=0, used=0)
|
||||
case(7, "no module and no callout", run, nothing, False)
|
||||
case(7, "no module, null for the modules, and no callout", run, each(nothing, lambda b: contract(b).update(modules=None)), False)
|
||||
# 8: the run
|
||||
case(8, "2^20 shots", run, shots(2 ** 20), True)
|
||||
case(8, "2^20 + 1 shots", run, shots(2 ** 20 + 1), False)
|
||||
for name in ("per_call", "per_instance", "per_job"):
|
||||
# per_job at 2^39 is past rule 30's work beside any module: it is held there.
|
||||
case(30 if name == "per_job" else 8, "the budget %s at 2^39" % name, run, budget(name, 2 ** 39), name != "per_job")
|
||||
case(30 if name == "per_job" else 8, "the budget %s at 2^39 + 1" % name, run, budget(name, 2 ** 39 + 1), False)
|
||||
case(8, "a seed of 0, alike in the result", run, lambda b: (contract(b)["run"].update(seed=0), b["result"].update(seed=0)), True)
|
||||
case(8, "a seed below 0, alike in the result", run, lambda b: (contract(b)["run"].update(seed=-1), b["result"].update(seed=-1)), False)
|
||||
case(8, "a seed of 2^53 - 1, alike in the result", run, lambda b: (contract(b)["run"].update(seed=2 ** 53 - 1), b["result"].update(seed=2 ** 53 - 1)), True)
|
||||
case(8, "1 shot", run, shots(1), True)
|
||||
case(8, "0 shots", job, lambda b: (contract(b)["run"].update(shots=0), b["result"].update(shots=0, shots_run=0, counts={}, callouts=0), b["result"]["fuel"].update(callouts={}, used=b["result"]["fuel"]["instances"])), False)
|
||||
case(8, "a budget of 0", fault, budget("per_instance", 0), True)
|
||||
case(8, "a call's budget of 0, its one call stopped at once", fault, each(budget("per_call", 0), lambda b: (calls(b).update(fuel=0, max=0), b["result"]["fuel"].update(used=0), b["result"]["fault"].update(fuel=0))), True)
|
||||
case(8, "another state", run, at(("request", "wasmq", "run", "state"), "call"), False)
|
||||
# 9, 10: the result's members, and the form of its seal
|
||||
case(9, "a member the result does not define", run, at(R + ("x",), 1), False)
|
||||
first = copy.deepcopy(run)
|
||||
out.append(("rule 10, sealed in the first form", seal(first, form="first"), ["wasmq_form"]))
|
||||
# 11: what the result repeats
|
||||
case(11, "another seed in the result", run, lambda b: b["result"].update(seed=b["result"]["seed"] + 1), False)
|
||||
case(11, "another shots in the result", run, lambda b: b["result"].update(shots=b["result"]["shots"] + 1), False)
|
||||
case(11, "another accuracy", run, at(R + ("accuracy",), {"class": "exact", "x": 1}), False)
|
||||
case(11, "another energy", run, at(R + ("energy",), {"unmetered": "a meter"}), False)
|
||||
# 12: qubits
|
||||
case(12, "2^15 qubits", run, at(R + ("qubits",), 2 ** 15), True)
|
||||
case(12, "1 qubit", run, at(R + ("qubits",), 1), True)
|
||||
case(12, "0 qubits", run, at(R + ("qubits",), 0), False)
|
||||
case(12, "qubits null", run, at(R + ("qubits",), None), False)
|
||||
case(12, "2^15 + 1 qubits", run, at(R + ("qubits",), 2 ** 15 + 1), False)
|
||||
# 13: the fuel's budget and what it used
|
||||
case(13, "used equal to per_job", run, lambda b: budget("per_job", b["result"]["fuel"]["used"])(b), True)
|
||||
case(13, "used past per_job", run, lambda b: budget("per_job", b["result"]["fuel"]["used"] - 1)(b), False)
|
||||
case(13, "a budget the contract does not give", run, lambda b: b["result"]["fuel"]["budget"].update(per_call=b["result"]["fuel"]["budget"]["per_call"] + 1), False)
|
||||
# 14: each callout's fuel
|
||||
case(14, "a call's largest equal to per_call", run, lambda b: budget("per_call", calls(b)["max"])(b), True)
|
||||
case(14, "a call's largest past per_call", run, lambda b: budget("per_call", calls(b)["max"] - 1)(b), False)
|
||||
case(14, "a call's largest equal to its fuel", fault, own_fuel(0), True)
|
||||
case(14, "a call's largest past its fuel", run, own_fuel(-1), False)
|
||||
case(14, "a callout with no call", run, lambda b: (calls(b).update(calls=0, fuel=0, max=0), b["result"].update(callouts=0), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"])), False)
|
||||
case(20, "fuel past its calls of their largest", run, lambda b: (calls(b).update(fuel=calls(b)["calls"] * calls(b)["max"] + 1), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"] + calls(b)["fuel"])), False)
|
||||
# 15: what adds up
|
||||
case(15, "a call more than the fuel counts", run, lambda b: b["result"].update(callouts=b["result"]["callouts"] + 1), False)
|
||||
# 16: the result's modules
|
||||
case(16, "a module of the result named otherwise", run, lambda b: b["result"]["modules"][0].update(name="other"), False)
|
||||
# 17: what the instances could be given
|
||||
case(17, "a fault's instance counted: one, given 1 each stretch", init, budget("per_instance", 1), True)
|
||||
case(17, "one instance for the run, at its bound", job, lambda b: budget("per_instance", -(-b["result"]["fuel"]["instances"] // stretches(b)))(b), True)
|
||||
case(17, "one instance for the run, past its bound", job, lambda b: budget("per_instance", (b["result"]["fuel"]["instances"] - 1) // stretches(b))(b), False)
|
||||
# 18: how it ended
|
||||
case(18, "a fault in init within its phase's budget", init, each(budget("per_instance", 2), at(F + ("instances",), 2), at(F + ("used",), 2), at(R + ("fault", "fuel"), 2)), True)
|
||||
case(18, "a fault in init past its phase's budget", init, each(budget("per_instance", 1), at(F + ("instances",), 2), at(F + ("used",), 2), at(R + ("fault", "fuel"), 2)), False)
|
||||
case(18, "a fault after every shot", fault, lambda b: (b["result"].update(shots_run=32, counts={"0": 32}), b["result"]["fault"].update(shot=32)), False)
|
||||
case(18, "a fault in another shot than the next", fault, at(R + ("fault", "shot"), 1), False)
|
||||
case(28, "a call's fuel fault of the run's budget, with the run's budget not spent", fault, at(R + ("fault", "budget"), "run"), False)
|
||||
case(18, "a call's fuel fault of the instance's budget", fault, at(R + ("fault", "budget"), "instance"), False)
|
||||
case(18, "a fault in init that names a callout", init, at(R + ("fault", "callout"), "f"), False)
|
||||
case(18, "a call's fault the fuel counts no call of", fault, lambda b: (b["result"].update(callouts=0), b["result"]["fuel"].update(callouts={}, instances=400)), False)
|
||||
case(18, "a call that stopped at its callout's largest", fault, lambda b: (b["result"].update(callouts=2), b["result"]["fuel"]["callouts"]["f"].update(calls=2, fuel=401, max=400), b["result"]["fuel"].update(used=401)), True)
|
||||
case(18, "a call that stopped past its callout's largest", fault, lambda b: (b["result"].update(callouts=2), b["result"]["fuel"]["callouts"]["f"].update(calls=2, fuel=401, max=399), b["result"]["fuel"].update(used=401)), False)
|
||||
case(18, "a lifecycle fault whose callout is null", init, at(R + ("fault", "callout"), None), False)
|
||||
case(18, "a trap whose budget is null", init, at(R + ("fault", "budget"), None), False)
|
||||
case(18, "a trap in seed", init, at(R + ("fault", "phase"), "seed"), True)
|
||||
case(18, "a fault in another phase", init, at(R + ("fault", "phase"), "start"), False)
|
||||
case(18, "a trap of another reason the profile names", init, at(R + ("fault", "reason"), "invalid_conversion_to_integer"), True)
|
||||
case(18, "a fault in a shot after shots_run", frun, at(R + ("fault", "shot"), 1), False)
|
||||
case(18, "a fault in a module named null", init, at(R + ("fault", "module"), None), False)
|
||||
case(18, "a trap that names a budget", init, at(R + ("fault", "budget"), "instance"), False)
|
||||
case(18, "an ok result whose fault is null", run, at(R + ("fault",), None), False)
|
||||
case(18, "a call's fault whose callout is null", fault, at(R + ("fault", "callout"), None), False)
|
||||
case(18, "a fuel fault whose budget is null", fault, at(R + ("fault", "budget"), None), False)
|
||||
# 19: the counts
|
||||
case(19, "outcomes of two widths", run, lambda b: (b["result"]["counts"].update({next(iter(b["result"]["counts"])): b["result"]["counts"][next(iter(b["result"]["counts"]))] - 1}), b["result"]["counts"].update({"0": 1})), False)
|
||||
case(19, "a count of 0", run, lambda b: b["result"]["counts"].update({"0" * len(next(iter(b["result"]["counts"]))): 0}), False)
|
||||
case(19, "an outcome of no bits", run, counts(0, 32), True)
|
||||
case(19, "an outcome holding a 2", run, lambda b: b["result"].update(counts={"012": 32}), False)
|
||||
case(19, "counts null", fault, at(R + ("counts",), None), False)
|
||||
# Round 4's labelled cases, each where a weakening of one rule moves a verdict.
|
||||
case(2, "envelope_blake3 of 65 digits", run, lambda b: b["request"].update(envelope_blake3=b["request"]["envelope_blake3"] + "0"), False)
|
||||
case(12, "transcript_blake3 of 63 digits", run, lambda b: b["result"].update(transcript_blake3=b["result"]["transcript_blake3"][:63]), False)
|
||||
case(3, "run's fuel a member more, the budget alike", run, budget("z", 1), False)
|
||||
case(3, "the program a member more", run, lambda b: contract(b)["program"].update(z=1), False)
|
||||
case(4, "a profile one letter longer", run, lambda b: contract(b).update(profile="wai.quantum.wasmq/1x"), False)
|
||||
case(5, "inputs null", run, lambda b: contract(b)["program"].update(inputs=None), False)
|
||||
case(5, "the program's bytes 1104.5", run, lambda b: contract(b)["program"].update(bytes=1104.5), False)
|
||||
case(5, "an input that is true", run, lambda b: contract(b)["program"].update(inputs={"n": True}), False)
|
||||
case(6, "a module's bytes 39442.5", run, lambda b: contract(b)["modules"][0].update(bytes=39442.5), False)
|
||||
case(7, "an export null", run, lambda b: contract(b)["callouts"][0].update(export=None), False)
|
||||
case(7, "an extern null, with no call made", init, lambda b: contract(b)["callouts"][0].update(extern=None), False)
|
||||
case(7, "a callout of module 0.5", run, lambda b: contract(b)["callouts"].append({"extern": "g", "module": 0.5, "export": "g"}), False)
|
||||
|
||||
def respell(path, text, value):
|
||||
def f(s):
|
||||
o = s
|
||||
for k in path[:-1]:
|
||||
o = o[k]
|
||||
o[path[-1]] = g.Raw(text, value)
|
||||
return f
|
||||
case(11, "the result's seed written 1234.0", run, lambda b: None, True, respell(R + ("seed",), "1234.0", run["result"]["seed"]))
|
||||
case(12, "qubits written 17.0", run, lambda b: None, True, respell(R + ("qubits",), "17.0", 17))
|
||||
case(13, "a budget written 1e7", run, lambda b: None, True, respell(F + ("budget", "per_call"), "1e7", 10000000))
|
||||
case(14, "the callouts' fuel null", init, at(F + ("callouts",), None), False)
|
||||
case(14, "the callouts' fuel an array", init, at(F + ("callouts",), []), False)
|
||||
case(15, "a call fewer than the fuel counts", run, lambda b: b["result"].update(callouts=b["result"]["callouts"] - 1), False)
|
||||
case(16, "the result's modules in another order", run, lambda b: (second_module(39442, 1)(b), b["result"].update(modules=b["result"]["modules"][::-1])), False)
|
||||
case(17, "the instances' fuel past 32 x S x per_instance", run, budget("per_instance", 2583), False)
|
||||
case(17, "one instance for the run, a fault, past 1 x S x per_instance", init, each(at(("request", "wasmq", "run", "state"), "job"), budget("per_instance", 1), at(F + ("instances",), 3), at(F + ("used",), 3)), False)
|
||||
case(25, "an init fault's fuel past what was used", init, at(R + ("fault", "fuel"), 2), False)
|
||||
case(18, "a call's fault past its callout's max", frun, at(R + ("fault", "fuel"), 24), False)
|
||||
case(18, "an ok result one shot past its shots", run, lambda b: (b["result"]["counts"].update({next(iter(b["result"]["counts"])): b["result"]["counts"][next(iter(b["result"]["counts"]))] + 1}), b["result"].update(shots_run=33)), False)
|
||||
# 20: the fuel of the calls that returned, each 1 to the most one used
|
||||
case(20, "calls that returned using 1 each", run, lambda b: (calls(b).update(fuel=32, max=1), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"] + 32)), True)
|
||||
case(20, "calls that returned using nothing", run, lambda b: (calls(b).update(fuel=0, max=0), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"])), False)
|
||||
case(20, "two calls that returned and one that stopped, in 6", frun, each(budget("per_job", 6), lambda b: (calls(b).update(fuel=6, max=4), b["result"]["fuel"].update(used=6))), True)
|
||||
case(20, "two calls that returned and one that stopped, in 5", frun, each(budget("per_job", 5), lambda b: (calls(b).update(fuel=5, max=4), b["result"]["fuel"].update(used=5))), False)
|
||||
case(20, "calls that returned at the most one used", frun, lambda b: calls(b).update(max=23), True)
|
||||
case(20, "calls that returned past the most one used", frun, lambda b: calls(b).update(max=21), False)
|
||||
case(20, "the one call, the one that stopped, its fuel more than the fault's", fault, lambda b: (b["result"]["fault"].update(reason="unreachable", fuel=10), b["result"]["fault"].pop("budget")), False)
|
||||
case(20, "the one call, the one that stopped, its fuel the fault's", fault, lambda b: (b["result"]["fault"].update(reason="unreachable", fuel=10), b["result"]["fault"].pop("budget"), calls(b).update(fuel=10, max=10), b["result"]["fuel"].update(used=10)), True)
|
||||
# 21: the priors passed to each shot's instances
|
||||
case(21, "instances that passed each prior at the least", run, lambda b: b["result"]["fuel"].update(instances=32 * passed(b), used=32 * passed(b) + calls(b)["fuel"]), True)
|
||||
case(21, "instances that passed the priors in less", run, lambda b: b["result"]["fuel"].update(instances=32 * passed(b) - 1, used=32 * passed(b) - 1 + calls(b)["fuel"]), False)
|
||||
case(21, "one instance for the run, its prior in less", job, lambda b: b["result"]["fuel"].update(instances=passed(b) - 1, used=passed(b) - 1 + calls(b)["fuel"]), False)
|
||||
case(21, "a prior's fault: no prior passed whole", prior, lambda b: None, True)
|
||||
# 22: a call's fault in its callout's module
|
||||
case(22, "a call's fault in its callout's module, beside another", fault, fault_module("m"), True)
|
||||
case(22, "a call's fault in the other module", fault, fault_module("second"), False)
|
||||
# 23, 24: a phase against the module's priors, a reason against its phase
|
||||
case(23, "a prior's fault in a module with none", init, at(R + ("fault", "phase"), "prior"), False)
|
||||
case(24, "a bad_result while a prior is passed", prior, at(R + ("fault", "reason"), "bad_result"), True)
|
||||
case(24, "a bad_result in a call", fault, each(at(R + ("fault", "reason"), "bad_result"), lambda b: b["result"]["fault"].pop("budget")), True)
|
||||
case(24, "a bad_result in init", init, at(R + ("fault", "reason"), "bad_result"), False)
|
||||
case(24, "a bad_result in seed", init, each(at(R + ("fault", "reason"), "bad_result"), at(R + ("fault", "phase"), "seed")), False)
|
||||
# 25, 26, 27: a lifecycle fault against the instances, the state and the calls
|
||||
case(25, "an init fault in shot 1 within the instances' fuel", init, later_shot(1, instances=3, fuel=2), True)
|
||||
case(25, "an init fault in shot 1, shot 0's init uncounted", init, later_shot(1, instances=2, fuel=2), False)
|
||||
case(25, "an init fault in shot 1 past the instances' fuel", init, later_shot(1, instances=1, fuel=2), False)
|
||||
case(26, "one instance for the run, failing in shot 0", init, at(("request", "wasmq", "run", "state"), "job"), True)
|
||||
case(26, "one instance for the run, failing in shot 2", init, later_shot(2, state="job"), False)
|
||||
case(26, "a fresh instance each shot, failing in shot 2", init, later_shot(2, instances=3), True)
|
||||
case(27, "the first shot's instances failing after a call", init, later_shot(0, calls=1), False)
|
||||
# 28: a fuel fault used its whole limit
|
||||
case(28, "a call's fuel fault at its limit", fault, each(budget("per_call", 10), lambda b: (calls(b).update(fuel=10, max=10), b["result"]["fuel"].update(used=10), b["result"]["fault"].update(fuel=10))), True)
|
||||
case(28, "a call's fuel fault under its limit", fault, lambda b: (calls(b).update(fuel=10, max=10), b["result"]["fuel"].update(used=10), b["result"]["fault"].update(fuel=10)), False)
|
||||
case(28, "an instance's fuel fault at its limit", init, each(budget("per_instance", 1), at(R + ("fault", "reason"), "fuel_exhausted"), at(R + ("fault", "budget"), "instance")), True)
|
||||
case(28, "an instance's fuel fault under its limit", init, each(at(R + ("fault", "reason"), "fuel_exhausted"), at(R + ("fault", "budget"), "instance")), False)
|
||||
case(28, "the run's budget run out, not all used", frun, budget("per_job", 51), False)
|
||||
case(28, "the run's budget the limit, under the call's own", frun, each(budget("per_call", 24), at(R + ("fault", "fuel"), 23), lambda b: calls(b).update(max=23)), True)
|
||||
case(28, "the run's budget the limit, at the call's own", frun, each(budget("per_call", 23), at(R + ("fault", "fuel"), 23)), False)
|
||||
case(28, "an instance's run budget, at the instance's own", init, each(budget("per_job", 1), budget("per_instance", 1), at(R + ("fault", "reason"), "fuel_exhausted"), at(R + ("fault", "budget"), "run")), False)
|
||||
case(28, "an instance's run budget, under the instance's own", init, each(budget("per_job", 1), budget("per_instance", 2), at(R + ("fault", "reason"), "fuel_exhausted"), at(R + ("fault", "budget"), "run")), True)
|
||||
# 29: the bits of a shot, and of the shots
|
||||
case(29, "outcomes of 2^20 bits", run, counts(2 ** 20, 32), True)
|
||||
case(29, "outcomes of 2^20 + 1 bits", run, counts(2 ** 20 + 1, 32), False)
|
||||
case(29, "2^20 shots of 256 bits", frun, each(lambda b: (contract(b)["run"].update(shots=2 ** 20), b["result"].update(shots=2 ** 20)), counts(256, 2)), True)
|
||||
case(29, "2^20 shots of 257 bits", frun, each(lambda b: (contract(b)["run"].update(shots=2 ** 20), b["result"].update(shots=2 ** 20)), counts(257, 2)), False)
|
||||
# 30: the work a receipt shows
|
||||
case(30, "per_job at the most the rest leaves", run, lambda b: budget("per_job", work_left(b))(b), True)
|
||||
case(30, "per_job one past it", run, lambda b: budget("per_job", work_left(b) + 1)(b), False)
|
||||
case(30, "2^15 qubits over 2^20 shots", frun, each(lambda b: (contract(b)["run"].update(shots=2 ** 20), b["result"].update(shots=2 ** 20, qubits=2 ** 15))), False)
|
||||
case(30, "one instance for the run: its instance counted once", job, lambda b: budget("per_job", work_left(b))(b), True)
|
||||
# 31: the envelope
|
||||
case(31, "an envelope of 2^27 bytes", prior, lambda b: contract(b)["modules"][0]["priors"][0].update(bytes=most_prior(b)), True)
|
||||
case(31, "an envelope of 2^27 + 1 bytes", prior, lambda b: contract(b)["modules"][0]["priors"][0].update(bytes=most_prior(b) + 1), False)
|
||||
case(31, "frames one short of 2^27, the envelope past it", prior, lambda b: contract(b)["modules"][0]["priors"][0].update(bytes=2 ** 27 - 1 - (frames(b) - contract(b)["modules"][0]["priors"][0]["bytes"])), False)
|
||||
# 20: the most one call used, a returned call's, and each other 1 at least
|
||||
case(20, "32 calls, the most 21751, in 21751 + 31", run, calls_of(32, 21751), True)
|
||||
case(20, "32 calls, the most 21751, in 21751 + 30", run, each(calls_of(32, 21751), lambda b: (calls(b).update(fuel=21751 + 30), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"] + 21751 + 30))), False)
|
||||
case(20, "two returned, the most 23, beside a stopped call of 4, in 28", frun, each(budget("per_job", 28), lambda b: (calls(b).update(fuel=28, max=23), b["result"]["fuel"].update(used=28))), True)
|
||||
case(20, "two returned, the most 23, beside a stopped call of 4, in 27", frun, each(budget("per_job", 27), lambda b: (calls(b).update(fuel=27, max=23), b["result"]["fuel"].update(used=27))), False)
|
||||
case(20, "one returned in 5, then one stopped at 0, the run's budget spent", frun, each(budget("per_job", 5), lambda b: (b["result"].update(callouts=2), calls(b).update(calls=2, fuel=5, max=5), b["result"]["fuel"].update(used=5), b["result"]["fault"].update(fuel=0))), True)
|
||||
case(20, "two returned in 11, the most 10, then one stopped at 0", frun, each(budget("per_job", 11), lambda b: (calls(b).update(fuel=11, max=10), b["result"]["fuel"].update(used=11), b["result"]["fault"].update(fuel=0))), True)
|
||||
case(20, "two returned in 10, the most 10, then one stopped at 0", frun, each(budget("per_job", 10), lambda b: (calls(b).update(fuel=10, max=10), b["result"]["fuel"].update(used=10), b["result"]["fault"].update(fuel=0))), False)
|
||||
# 21, 25: what a lifecycle fault shows of the set it stopped
|
||||
case(25, "an init stopped after its 100-byte prior, in 104", init, each(own_prior(100), at(F + ("instances",), 104), at(F + ("used",), 104)), True)
|
||||
case(25, "an init stopped after its 100-byte prior, in 103", init, each(own_prior(100), at(F + ("instances",), 103), at(F + ("used",), 103)), False)
|
||||
case(21, "an init stopped after its 100-byte prior, in 102", init, each(own_prior(100), at(F + ("instances",), 102), at(F + ("used",), 102)), False)
|
||||
case(25, "a seed stopped after its 100-byte prior's module, passed none", init, each(own_prior(100), at(R + ("fault", "phase"), "seed")), True)
|
||||
case(25, "the second module's init stopped after the first's prior, in 104", init, each(second_module(50, 57), own_prior(100), at(R + ("fault", "module"), "second"), at(F + ("instances",), 104), at(F + ("used",), 104)), True)
|
||||
case(25, "the second module's init stopped after the first's prior, in 103", init, each(second_module(50, 57), own_prior(100), at(R + ("fault", "module"), "second"), at(F + ("instances",), 103), at(F + ("used",), 103)), False)
|
||||
case(25, "a seed stopped in shot 1, shot 0's seed shown", init, each(later_shot(1, instances=2, fuel=1), at(R + ("fault", "phase"), "seed")), True)
|
||||
case(25, "a seed stopped in shot 1, shot 0's seed uncounted", init, each(later_shot(1, instances=1, fuel=1), at(R + ("fault", "phase"), "seed")), False)
|
||||
# 29: the longest name, in characters
|
||||
case(29, "two widths, the longer past 2^20", run, lambda b: b["result"].update(counts={next(iter(b["result"]["counts"])): 31, "0" * (2 ** 20 + 1): 1}), False)
|
||||
case(19, "2^20 shots of a name of 256 characters in 257 bytes", frun, each(lambda b: (contract(b)["run"].update(shots=2 ** 20), b["result"].update(shots=2 ** 20)), lambda b: b["result"].update(counts={"\u00e9" + "0" * 255: 2})), False)
|
||||
case(29, "2^20 shots of a name of 257 characters", frun, each(lambda b: (contract(b)["run"].update(shots=2 ** 20), b["result"].update(shots=2 ** 20)), lambda b: b["result"].update(counts={"\u00e9" + "0" * 256: 2})), False)
|
||||
# 32: the calls a shot can make
|
||||
case(32, "32 shots of 2^21 calls", run, calls_of(32 * 2 ** 21), True)
|
||||
case(32, "32 shots of 2^21 calls and one more", run, calls_of(32 * 2 ** 21 + 1), False)
|
||||
case(32, "a call's fault in the first shot, after 2^21 - 1 calls", fault, lambda b: (b["result"].update(callouts=2 ** 21), calls(b).update(calls=2 ** 21, fuel=2 ** 21 - 1 + 400), b["result"]["fuel"].update(used=2 ** 21 - 1 + 400)), True)
|
||||
case(32, "a call's fault in the first shot, after 2^21 calls", fault, lambda b: (b["result"].update(callouts=2 ** 21 + 1), calls(b).update(calls=2 ** 21 + 1, fuel=2 ** 21 + 400), b["result"]["fuel"].update(used=2 ** 21 + 400)), False)
|
||||
# 33: a prior passed whole within one lifecycle call's limit
|
||||
case(33, "a prior of 87 bytes under 90 a lifecycle call", run, each(budget("per_instance", 90), at(F + ("instances",), 32 * 90), at(F + ("used",), 32 * 90 + 588348)), True)
|
||||
case(33, "a prior of 87 bytes under 89 a lifecycle call", run, each(budget("per_instance", 89), at(F + ("instances",), 32 * 90), at(F + ("used",), 32 * 90 + 588348)), False)
|
||||
case(33, "an init stopped after its 100-byte prior, under 103", init, each(own_prior(100), budget("per_instance", 103), at(F + ("instances",), 104), at(F + ("used",), 104)), True)
|
||||
case(33, "an init stopped after its 100-byte prior, under 102", init, each(own_prior(100), budget("per_instance", 102), at(F + ("instances",), 104), at(F + ("used",), 104)), False)
|
||||
# 34: what a fault's reason shows was charged
|
||||
case(34, "a trap after nothing charged", init, each(at(R + ("fault", "fuel"), 0)), False)
|
||||
case(34, "a result that is not one, after 2", fault, fault_of("bad_result", 2), True)
|
||||
case(34, "a result that is not one, after 1", fault, fault_of("bad_result", 1), False)
|
||||
case(34, "the stack past 2^23 after 788", fault, each(budget("per_call", 1000), fault_of("stack_exhausted", 788)), True)
|
||||
case(34, "the stack past 2^23 after 787", fault, each(budget("per_call", 1000), fault_of("stack_exhausted", 787)), False)
|
||||
# 35: the transcript of no returned call
|
||||
case(35, "an ok run of no call, its transcript the prefix's", run, lambda b: (b["result"].update(callouts=0), b["result"]["fuel"].update(callouts={}, used=b["result"]["fuel"]["instances"])), True)
|
||||
case(35, "an ok run of no call, its transcript the calls'", run, lambda b: (b["result"].update(callouts=0, transcript_blake3=b["result"]["transcript_blake3"][::-1]), b["result"]["fuel"].update(callouts={}, used=b["result"]["fuel"]["instances"])), False)
|
||||
case(35, "a call's fault of no returned call, another transcript", fault, at(R + ("transcript_blake3",), "ab" * 32), False)
|
||||
case(35, "a lifecycle fault, another transcript", init, at(R + ("transcript_blake3",), "ab" * 32), False)
|
||||
# Places where a member's own rule and another's both read it: each verifier must state
|
||||
# every rule it breaks, so that one reading it otherwise in one rule shows.
|
||||
case(13, "per_job 2^53, alike in the result", run, budget("per_job", 2 ** 53), False)
|
||||
case(6, "a module's blake3 in upper case, alike in the result", run, lambda b: (contract(b)["modules"][0].update(blake3=contract(b)["modules"][0]["blake3"].upper()), b["result"]["modules"][0].update(blake3=b["result"]["modules"][0]["blake3"].upper())), False)
|
||||
|
||||
def named_one(b):
|
||||
contract(b)["modules"][0]["name"] = 1
|
||||
b["result"]["modules"][0]["name"] = 1
|
||||
if "fault" in b["result"]:
|
||||
b["result"]["fault"]["module"] = 1
|
||||
case(6, "a module named 1, the result's module 1.0", run, named_one, False, respell(R + ("modules", 0, "name"), "1.0", 1))
|
||||
case(6, "a module named 1, an init's fault in 1.0", init, named_one, False, respell(R + ("fault", "module"), "1.0", 1))
|
||||
case(6, "a module named 1, a prior's fault in 1.0", prior, named_one, False, respell(R + ("fault", "module"), "1.0", 1))
|
||||
case(26, "one instance for the run, a fault in shot 0.5", init, each(at(("request", "wasmq", "run", "state"), "job"), at(R + ("fault", "shot"), 0.5)), False)
|
||||
case(18, "a fault in shot 0.5, after a call", init, each(at(R + ("fault", "shot"), 0.5), at(R + ("callouts",), 1)), False)
|
||||
|
||||
# A lifecycle fault is one that has a phase: null among them, absent not.
|
||||
case(26, "a fault whose phase is null, in shot 2 of one instance for the run", init, each(later_shot(2, state="job"), at(R + ("fault", "phase"), None)), False)
|
||||
case(18, "a fault with no phase, in shot 2 of one instance for the run", init, each(later_shot(2, state="job"), lambda b: b["result"]["fault"].pop("phase")), False)
|
||||
|
||||
# Every member of each genuine job given a value of another kind (half a unit off, below
|
||||
# 0, past 2^53 - 1, null, a digest in upper case), sealed again. No member of a wasmQ job
|
||||
# holds such a value: each verifier must refuse each, and both must state the same rules
|
||||
# broken (the differential holds them to that), so that a rule's check read loosely in
|
||||
# one, or a null read as absent, shows wherever another rule's check also refuses it.
|
||||
def leaves(v, path):
|
||||
if isinstance(v, dict):
|
||||
for k, x in v.items():
|
||||
yield path + (k,), x
|
||||
for y in leaves(x, path + (k,)):
|
||||
yield y
|
||||
elif isinstance(v, list):
|
||||
for i, x in enumerate(v[:1]):
|
||||
yield path + (i,), x
|
||||
for y in leaves(x, path + (i,)):
|
||||
yield y
|
||||
for name, base in (("run", run), ("fault", fault), ("init", init), ("fault-run", frun), ("prior", prior), ("state-job", job)):
|
||||
for part in ("request", "result"):
|
||||
for path, v in leaves(base[part], (part,)):
|
||||
# The receipt is the seal's; the format says what kind of job it is.
|
||||
if "receipt" in path or path == ("result", "format"):
|
||||
continue
|
||||
where = "%s %s" % (name, "/".join(map(str, path)))
|
||||
if isinstance(v, (int, float)) and not isinstance(v, bool):
|
||||
case("kinds", "%s + 0.5" % where, base, at(path, v + 0.5), False)
|
||||
case("kinds", "%s at -1" % where, base, at(path, -1), False)
|
||||
case("kinds", "%s at 2^53" % where, base, at(path, 2 ** 53), False)
|
||||
if isinstance(v, str) and re.fullmatch("[0-9a-f]{64}", v):
|
||||
case("kinds", "%s in upper case" % where, base, at(path, v.upper()), False)
|
||||
case("kinds", "%s null" % where, base, at(path, None), False)
|
||||
return out
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--reference", help="the wai-quantum binary")
|
||||
|
|
@ -224,7 +781,13 @@ def main():
|
|||
ap.add_argument("--corpus", default=CORPUS)
|
||||
ap.add_argument("--extra", action="append", default=[], help="a directory of receipts both must find valid")
|
||||
ap.add_argument("--plant", help="run the second verifier with this planted defect; succeed only if it is caught")
|
||||
ap.add_argument("--second", help="another second verifier's file in place of receipt_verify.py (a mutant of it)")
|
||||
ap.add_argument("--wasmq-only", action="store_true", help="only what holds a wasmQ job: its receipts, their changes, the rules and the labelled cases")
|
||||
ap.add_argument("--first", action="store_true", help="stop at the first stage that finds a disagreement")
|
||||
a = ap.parse_args()
|
||||
global SECOND
|
||||
if a.second:
|
||||
SECOND = os.path.abspath(a.second)
|
||||
if not a.second_only and not a.reference:
|
||||
ap.error("--reference is required, unless --second-only")
|
||||
ref = os.path.abspath(a.reference) if a.reference else None
|
||||
|
|
@ -239,20 +802,48 @@ def main():
|
|||
problems.append("%s is in the manifest and not in the corpus" % f)
|
||||
|
||||
# The corpus: both verifiers and the manifest, receipt by receipt.
|
||||
files = [os.path.join(a.corpus, e["file"]) for e in manifest if e["file"] in present]
|
||||
entries = [e for e in manifest if e["file"] in present]
|
||||
entries = [e for e in manifest if e["file"] in present and (not a.wasmq_only or "wasmq" in e["file"])]
|
||||
files = [os.path.join(a.corpus, e["file"]) for e in entries]
|
||||
r2 = run_second_files(files, a.plant)
|
||||
r1 = r2 if a.second_only else run_reference_files(ref, files)
|
||||
agree = 0
|
||||
for e, x, y in zip(entries, r1, r2):
|
||||
if not a.second_only:
|
||||
same_rules(e["file"], x, y, problems)
|
||||
want = tuple(sorted(e["reasons"]))
|
||||
if said(x) != said(y) or said(x)[0] != want:
|
||||
problems.append("%s: the manifest says %s; the reference %s; the second verifier %s" % (e["file"], list(want), list(said(x)), list(said(y))))
|
||||
else:
|
||||
agree += 1
|
||||
# A crafted wasmQ receipt that names one rule breaks that rule alone: one problem from the
|
||||
# reference, and that rule alone from the second verifier, which numbers its rules.
|
||||
alone = 0
|
||||
for e, x, y in zip(entries, r1, r2):
|
||||
m = re.search(r"\(rule (\d+)\)$", e.get("what", ""))
|
||||
if not m or not e["file"].startswith("jobs/crafted-wasmq-"):
|
||||
continue
|
||||
alone += 1
|
||||
for who, v in ((None if a.second_only else "the reference", x), ("the second verifier", y)):
|
||||
if who and rules_of(v) != {int(m.group(1))}:
|
||||
problems.append("%s breaks rule %s alone, but %s states %s" % (e["file"], m.group(1), who, (v.get("wasmq") or {}).get("problems")))
|
||||
print("corpus: %d crafted wasmQ receipts each break the one rule they name, and no other" % alone)
|
||||
valid = sum(1 for e in entries if not e["reasons"])
|
||||
print("corpus: %d receipts (%d valid, %d not), %d agree %s" % (len(entries), valid, len(entries) - valid, agree, "with the manifest (second verifier only)" if a.second_only else "three ways (manifest, reference, second)"))
|
||||
if a.second_only:
|
||||
g = generator()
|
||||
problems += rules_stage(None, a.plant, (g.seal, g.public_key(g.DEMO).hex()))
|
||||
problems += labelled_stage(None, a.plant)
|
||||
return finish(a, problems)
|
||||
if a.first and problems:
|
||||
return finish(a, problems)
|
||||
# The rules and the labelled cases first: each is short, and each has its verdict written.
|
||||
g = generator()
|
||||
seal = (g.seal, g.public_key(g.DEMO).hex())
|
||||
problems += rules_stage(ref, a.plant, seal)
|
||||
if a.first and problems:
|
||||
return finish(a, problems)
|
||||
problems += labelled_stage(ref, a.plant)
|
||||
if a.first and problems:
|
||||
return finish(a, problems)
|
||||
|
||||
# Receipts a person holds: both must find them valid.
|
||||
|
|
@ -268,8 +859,6 @@ def main():
|
|||
|
||||
# Every valid receipt, one member changed at a time.
|
||||
lines, meta = [], []
|
||||
g = generator()
|
||||
seal = (g.seal, g.public_key(g.DEMO).hex())
|
||||
for e in entries:
|
||||
if e["reasons"]:
|
||||
continue
|
||||
|
|
@ -293,6 +882,7 @@ def main():
|
|||
reasons = Counter()
|
||||
for (fname, what, expected), x, y in zip(meta, m1, m2):
|
||||
sx, sy = said(x), said(y)
|
||||
same_rules("%s, %s" % (fname, what), x, y, problems)
|
||||
if sx != sy:
|
||||
problems.append("%s, %s: the reference %s; the second verifier %s" % (fname, what, list(sx), list(sy)))
|
||||
continue
|
||||
|
|
@ -310,10 +900,67 @@ def main():
|
|||
held += 1
|
||||
print("changed: %d receipts from %d valid ones; %d agree (%d refused, as every change inside the seal must be; %d valid, as every change outside it must be; %d at the edges of a number, judged only by the other verifier)" % (len(lines), valid, agree, caught, held, compared))
|
||||
print("reasons given to the changed receipts: " + ", ".join("%s %d" % kv for kv in sorted(reasons.items())))
|
||||
|
||||
return finish(a, problems)
|
||||
|
||||
|
||||
def rules_stage(ref, plant, seal):
|
||||
"""Each verifier given every case of rule_cases: each must give the reasons written for
|
||||
it (the second alone with --second-only)."""
|
||||
cases = rule_cases(CORPUS, seal[0])
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
path = os.path.join(tmp, "rules.jsonl")
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write("\n".join(b if isinstance(b, str) else compact(b) for _, b, _ in cases) + "\n")
|
||||
second = run_lines([sys.executable, "-I", SECOND] + (["--plant", plant] if plant else []) + ["--lines"], path, len(cases))
|
||||
first = run_lines([ref, "verify", "--lines"], path, len(cases)) if ref else second
|
||||
problems = []
|
||||
for (what, _, want), x, y in zip(cases, first, second):
|
||||
if ref:
|
||||
same_rules(what, x, y, problems)
|
||||
rule = re.match(r"rule (\d+), ", what)
|
||||
for who, v in (("the reference", x), ("the second verifier", y)):
|
||||
if tuple(sorted(v.get("reasons", []))) != tuple(want):
|
||||
problems.append("%s: written %s; %s %s" % (what, want, who, sorted(v.get("reasons", []))))
|
||||
elif want and rule and rules_of(v) is not None and int(rule.group(1)) not in rules_of(v):
|
||||
problems.append("%s: %s finds it breaks rules %s, not the rule it is written for" % (what, who, sorted(rules_of(v))))
|
||||
rules = len({w.split(",")[0] for w, _, _ in cases if re.match(r"rule \d+,", w)})
|
||||
kinds = sum(1 for w, _, _ in cases if w.startswith("rule kinds,"))
|
||||
print("rules: %d cases, %d at the bounds of %d rules of a wasmQ job's form and %d of members of another kind, sealed again; %d as written, the same rules broken by both" % (len(cases), len(cases) - kinds, rules, kinds, len(cases) - len({p.split(":")[0] for p in problems})))
|
||||
return problems
|
||||
|
||||
|
||||
def labelled_stage(ref, plant):
|
||||
"""The second verifier's own hand-labelled wasmQ cases (`receipt_verify.py --wasmq-cases`),
|
||||
each as its exact text, given to both verifiers: each must give the reasons its author
|
||||
wrote, so that one labelled corpus binds both. The labels come from receipt_verify.py as
|
||||
written, whichever second verifier is under test."""
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
out = os.path.join(tmp, "cases.jsonl")
|
||||
p = subprocess.run([sys.executable, "-I", ORIGINAL_SECOND, "--wasmq-cases", out], capture_output=True, text=True)
|
||||
if p.returncode != 0:
|
||||
raise SystemExit("receipt_verify.py --wasmq-cases failed: %s" % p.stderr.strip()[:400])
|
||||
with open(out, encoding="utf-8") as f:
|
||||
cases = [json.loads(line) for line in f if line.strip()]
|
||||
files = []
|
||||
for i, c in enumerate(cases):
|
||||
path = os.path.join(tmp, "case-%04d.json" % i)
|
||||
with open(path, "wb") as f:
|
||||
f.write(base64.b64decode(c["raw"]))
|
||||
files.append(path)
|
||||
second = run_second_files(files, plant)
|
||||
first = run_reference_files(ref, files) if ref else second
|
||||
problems = []
|
||||
for c, x, y in zip(cases, first, second):
|
||||
if ref:
|
||||
same_rules("labelled %s" % c["name"], x, y, problems)
|
||||
want = sorted(c["reasons"])
|
||||
for who, v in (("the reference", x), ("the second verifier", y)):
|
||||
if sorted(v.get("reasons", [])) != want:
|
||||
problems.append("labelled %s: written %s; %s %s" % (c["name"], want, who, sorted(v.get("reasons", []))))
|
||||
print("labelled: %d of the second verifier's hand-labelled wasmQ cases, given to both; %d as written" % (len(cases), len(cases) - len({p.split(":")[0] for p in problems})))
|
||||
return problems
|
||||
|
||||
|
||||
def finish(a, problems):
|
||||
if a.plant:
|
||||
if problems:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
561
wai/quantum-conformance/tools/wasmq_mutants.py
Normal file
561
wai/quantum-conformance/tools/wasmq_mutants.py
Normal file
|
|
@ -0,0 +1,561 @@
|
|||
#!/usr/bin/env python3
|
||||
"""wasmq_mutants.py: each rule of a wasmQ job's form (quantum-wasmq section 6.5), weakened in
|
||||
each verifier, and held to the receipts differential: every weakening must be caught.
|
||||
|
||||
python3 -I wasmq_mutants.py python --reference PATH/wai-quantum [--jobs N] [--rule N]
|
||||
python3 -I wasmq_mutants.py rust-schemata ENGINE_RS OUT.json
|
||||
python3 -I wasmq_mutants.py rust --reference PATH/wai-quantum --mutants OUT.json [--jobs N]
|
||||
|
||||
The weakenings are made from the code, not written by hand: at each place a rule is checked,
|
||||
|
||||
drop the check never fails;
|
||||
bound a comparison moved by one (`<` for `<=`, `>` for `>=`, and back), or a whole
|
||||
number in it one more;
|
||||
type a count read as any number (0.5, -1, a number past 2^53), a digest as any string of
|
||||
its length, two values compared as written rather than as JSON values;
|
||||
null a member that is `null` read as absent;
|
||||
absent a member that is absent read as `null`;
|
||||
extreme the most of many read as the least, and back (a `max` over a list for a `min`).
|
||||
|
||||
Each is assigned the rule whose check it is (the second verifier numbers its checks; the
|
||||
engine marks each rule's code `// Rule N.` or `// N:`). The second verifier's mutants are
|
||||
whole files; the engine's are one build (`rust-schemata` writes every mutant into the engine
|
||||
behind the environment variable WQ_MUTANT, each off unless it is named), run once a mutant.
|
||||
|
||||
A mutant is caught when `receipt_differential.py --wasmq-only --first` fails with it: the
|
||||
corpus, the rules stage, the labelled cases and the one-member changes. A mutant no input
|
||||
can tell from the text (one that only changes how a verdict already refused is worded, say)
|
||||
is listed in EQUIVALENT with the reason; any other survivor fails the run. Counts are
|
||||
reported per rule. Standard library only, Python 3.9+.
|
||||
"""
|
||||
import argparse
|
||||
import ast
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from collections import defaultdict
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
SECOND = os.path.join(HERE, "receipt_verify.py")
|
||||
DIFFERENTIAL = os.path.join(HERE, "receipt_differential.py")
|
||||
|
||||
# Mutants that no input can tell from the text, each by its rule, kind and what it does
|
||||
# ("RULES|KIND|WHAT"), with the reason no input tells it from the text.
|
||||
EQUIVALENT = {
|
||||
# The engine's.
|
||||
'6|bound|whole\'s upper bound one more in `!m["name"].is_string() || !is_digest(&m["blake3"]) || !whole(&m["bytes"], 1, MAX_EXACT)`': "a count is at most 2^53 - 1 by its own reading (count), so a bound one past that bounds nothing more",
|
||||
'6|bound|whole\'s upper bound one more in `!pr["name"].is_string() || !is_digest(&pr["blake3"]) || !whole(&pr["bytes"], 0, MAX_EXACT)`': "the same, for a prior's bytes",
|
||||
'8|bound|whole\'s upper bound one more in `!whole(&run["seed"], 0, MAX_EXACT)`': "the same, for the seed",
|
||||
"14|drop|the check never fails: `all.is_none()`": "rule 14's check of a call's largest against its fuel refuses a fuel that is no count already",
|
||||
'16|type|same read loosely in `mods.len() != got.len() || mods.iter().zip(got).any(|(a, b)| !same(&a["blake3"], &b["blake3"]) || !same(&a["name"], &b["name"]))`#blake3': "a blake3 that is no string breaks rule 16's own check that the result's is a digest, so comparing it as written changes no rule",
|
||||
'18|null|a null member read as absent: fuel["callouts"].get(name) in `fuel["callouts"].get(name)`': "both ways the stopped call is found missing are rule 18's",
|
||||
'18|absent|an absent member read as null: fuel["callouts"].get(name) in `fuel["callouts"].get(name)`': "the same",
|
||||
"19|type|count read loosely in `count(n).is_none_or(|n| n == 0)`": "rule 19's sum of the counts refuses a count that is no count already",
|
||||
'20-35|null|a null member read as absent: r.get("fault") in `if r["status"] == "fault" { r.get("fault").filter(|f| f.is_object()) } else { None }`': "the fault is read only as an object: null and absent are both none",
|
||||
'20-35|absent|an absent member read as null: r.get("fault") in `if r["status"] == "fault" { r.get("fault").filter(|f| f.is_object()) } else { None }`': "the same",
|
||||
'35|null|a null member read as absent: r.get("fault") in `if r["status"] == "fault" { r.get("fault").filter(|f| f.is_object()) } else { None }`': "the same, where rule 35 reads the fault",
|
||||
'35|absent|an absent member read as null: r.get("fault") in `if r["status"] == "fault" { r.get("fault").filter(|f| f.is_object()) } else { None }`': "the same",
|
||||
}
|
||||
|
||||
|
||||
def _equivalent(rules, kind, what):
|
||||
return "%s|%s|%s" % (",".join(map(str, rules)), kind, what) in EQUIVALENT
|
||||
|
||||
# ------------------------------------------------------------------ the second verifier
|
||||
|
||||
# The type-check helpers: a value read through one of them is read the same whether it is
|
||||
# absent or null (each refuses both), so a null-or-absent weakening under one changes nothing.
|
||||
_CHECKERS = {"_count", "_count_in", "_text_is", "_lower_hex", "_obj", "_arr", "_or_zero", "_exactly", "isinstance", "_n"}
|
||||
_LOOSE = {"_count": "_mut_count", "_count_in": "_mut_count_in", "_lower_hex": "_mut_lower_hex"}
|
||||
_HELPERS_SOURCE = '''
|
||||
|
||||
def _mut_count(v):
|
||||
"""A weakening: any number is a count."""
|
||||
return isinstance(v, Num) and v.value >= -1e300
|
||||
|
||||
|
||||
def _mut_count_in(v, low, high):
|
||||
return _mut_count(v) and low <= int(v.value) <= high
|
||||
|
||||
|
||||
def _mut_lower_hex(v, n):
|
||||
return isinstance(v, str) and len(v) == n
|
||||
|
||||
|
||||
def _mut_get_null(v, name):
|
||||
"""A weakening: a member that is null is read as absent."""
|
||||
x = _get(v, name)
|
||||
return _ABSENT if x is None else x
|
||||
|
||||
|
||||
def _mut_get_absent(v, name):
|
||||
"""A weakening: a member that is absent is read as null."""
|
||||
x = _get(v, name)
|
||||
return None if x is _ABSENT else x
|
||||
|
||||
|
||||
def _mut_in_null(name, v):
|
||||
return isinstance(v, dict) and v.get(name) is not None
|
||||
|
||||
|
||||
def _mut_in_absent(name, v):
|
||||
return isinstance(v, dict)
|
||||
'''
|
||||
|
||||
|
||||
def _wasmq_functions(tree):
|
||||
"""The second verifier's functions that check a wasmQ job's form: wasmq_broken and each
|
||||
module-level function it calls that is no shared helper."""
|
||||
funcs = {n.name: n for n in tree.body if isinstance(n, ast.FunctionDef)}
|
||||
root = funcs["wasmq_broken"]
|
||||
called = {n.func.id for n in ast.walk(root) if isinstance(n, ast.Call) and isinstance(n.func, ast.Name)}
|
||||
shared = _CHECKERS | {"_get", "rule", "all", "any", "len", "set", "sorted", "sum", "min", "max", "abs", "int", "str", "list", "range", "isinstance", "_numbers", "_text_is"}
|
||||
out = [root]
|
||||
for name in sorted(called - shared):
|
||||
f = funcs.get(name)
|
||||
if f is not None and f.lineno > funcs.get("is_wasmq", root).lineno:
|
||||
out.append(f)
|
||||
return out
|
||||
|
||||
|
||||
def _rule_calls(fn):
|
||||
"""(line, number, the call) for each rule(N, ...) in fn, in order."""
|
||||
out = []
|
||||
for n in ast.walk(fn):
|
||||
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id == "rule" and n.args and isinstance(n.args[0], ast.Constant):
|
||||
out.append((n.lineno, n.args[0].value, n))
|
||||
return sorted(out, key=lambda x: x[0])
|
||||
|
||||
|
||||
def _rule_of(node, root_calls, helper_rules, fn):
|
||||
"""The rule a node's check belongs to: the rule(N, ...) call around it; else, in
|
||||
wasmq_broken, for a value assigned, every rule whose own code (from the rule before it to
|
||||
its call) reads that name, or else the first rule called at or after its line; in a
|
||||
helper, the rules whose checks call it."""
|
||||
for line, number, call in root_calls:
|
||||
if any(x is node for x in ast.walk(call)):
|
||||
return [number]
|
||||
if fn.name != "wasmq_broken":
|
||||
return helper_rules.get(fn.name, ["?"])
|
||||
top = next((st for st in fn.body if any(x is node for x in ast.walk(st))), None)
|
||||
if isinstance(top, ast.Assign):
|
||||
names = {t.id for target in top.targets for t in ast.walk(target) if isinstance(t, ast.Name)}
|
||||
readers = []
|
||||
bounds = [0] + [line for line, _, _ in root_calls]
|
||||
for (line, number, _), start in zip(root_calls, bounds):
|
||||
block = [st for st in fn.body if start < st.lineno <= line and st is not top]
|
||||
if any(isinstance(x, ast.Name) and x.id in names for st in block for x in ast.walk(st)):
|
||||
readers.append(number)
|
||||
if readers:
|
||||
return sorted(set(readers))
|
||||
after = [number for line, number, _ in root_calls if line >= node.lineno]
|
||||
return after[:1] or ["?"]
|
||||
|
||||
|
||||
def python_mutants(path=SECOND):
|
||||
"""Every weakening of the second verifier's form check: (id, rules, what, the file's text)."""
|
||||
with open(path, encoding="utf-8") as f:
|
||||
source = f.read()
|
||||
tree = ast.parse(source)
|
||||
fns = _wasmq_functions(tree)
|
||||
root = fns[0]
|
||||
root_calls = _rule_calls(root)
|
||||
helper_rules = defaultdict(list)
|
||||
for line, number, call in root_calls:
|
||||
for n in ast.walk(call):
|
||||
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and any(n.func.id == f.name for f in fns[1:]):
|
||||
helper_rules[n.func.id].append(number)
|
||||
# A helper called from code before a rule(N, ...) is that rule's.
|
||||
for f in fns[1:]:
|
||||
if f.name not in helper_rules:
|
||||
for n in ast.walk(root):
|
||||
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id == f.name:
|
||||
helper_rules[f.name] = _rule_of(n, root_calls, {}, root)
|
||||
|
||||
parents = {}
|
||||
for fn in fns:
|
||||
for p in ast.walk(fn):
|
||||
for c in ast.iter_child_nodes(p):
|
||||
parents[c] = p
|
||||
sites = [] # (node, kind, what, transform)
|
||||
|
||||
flip = {ast.Lt: ast.LtE, ast.LtE: ast.Lt, ast.Gt: ast.GtE, ast.GtE: ast.Gt}
|
||||
for fn in fns:
|
||||
for n in ast.walk(fn):
|
||||
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id == "rule" and n.args and isinstance(n.args[0], ast.Constant):
|
||||
sites.append((n, "drop", "rule %s never fails" % n.args[0].value, lambda m: ast.Call(func=m.func, args=[m.args[0], ast.Constant(True)], keywords=[])))
|
||||
if isinstance(n, ast.Compare):
|
||||
for i, op in enumerate(n.ops):
|
||||
if type(op) in flip:
|
||||
def t(m, i=i):
|
||||
m.ops[i] = flip[type(m.ops[i])]()
|
||||
return m
|
||||
sites.append((n, "bound", "%s for %s in %s" % (flip[type(op)].__name__, type(op).__name__, ast.unparse(n)), t))
|
||||
for c in ast.walk(n):
|
||||
if isinstance(c, ast.Constant) and type(c.value) is int:
|
||||
sites.append((c, "bound", "%d for %d in %s" % (c.value + 1, c.value, ast.unparse(n)), lambda m: ast.Constant(m.value + 1)))
|
||||
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id in ("max", "min") and len(n.args) == 1:
|
||||
other = "min" if n.func.id == "max" else "max"
|
||||
sites.append((n, "extreme", "%s for %s in %s" % (other, n.func.id, ast.unparse(n)), lambda m, other=other: ast.Call(func=ast.Name(other, ast.Load()), args=m.args, keywords=m.keywords)))
|
||||
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name):
|
||||
if n.func.id == "_count_in":
|
||||
for c in n.args[1:]:
|
||||
if isinstance(c, ast.Constant) and type(c.value) is int:
|
||||
sites.append((c, "bound", "%d for %d in %s" % (c.value + 1, c.value, ast.unparse(n)), lambda m: ast.Constant(m.value + 1)))
|
||||
if n.func.id in _LOOSE:
|
||||
sites.append((n, "type", "%s read loosely" % ast.unparse(n), lambda m: ast.Call(func=ast.Name(_LOOSE[m.func.id], ast.Load()), args=m.args, keywords=m.keywords)))
|
||||
if n.func.id == "_get":
|
||||
p = parents.get(n)
|
||||
checked = isinstance(p, ast.Call) and isinstance(p.func, ast.Name) and p.func.id in _CHECKERS
|
||||
if not checked:
|
||||
sites.append((n, "null", "a null member read as absent: %s" % ast.unparse(n), lambda m: ast.Call(func=ast.Name("_mut_get_null", ast.Load()), args=m.args, keywords=[])))
|
||||
sites.append((n, "absent", "an absent member read as null: %s" % ast.unparse(n), lambda m: ast.Call(func=ast.Name("_mut_get_absent", ast.Load()), args=m.args, keywords=[])))
|
||||
if isinstance(n, ast.Compare) and len(n.ops) == 1 and isinstance(n.ops[0], (ast.In, ast.NotIn)) and isinstance(n.left, ast.Constant) and isinstance(n.left.value, str):
|
||||
for kind, helper in (("null", "_mut_in_null"), ("absent", "_mut_in_absent")):
|
||||
def t(m, helper=helper):
|
||||
call = ast.Call(func=ast.Name(helper, ast.Load()), args=[m.left, m.comparators[0]], keywords=[])
|
||||
return ast.UnaryOp(ast.Not(), call) if isinstance(m.ops[0], ast.NotIn) else call
|
||||
sites.append((n, kind, "`%s` in: %s" % (n.left.value, "null read as absent" if kind == "null" else "absent read as null"), t))
|
||||
|
||||
out = []
|
||||
for k, (node, kind, what, transform) in enumerate(sites):
|
||||
fn = next(f for f in fns if any(x is node for x in ast.walk(f)))
|
||||
rules = _rule_of(node, root_calls, helper_rules, fn)
|
||||
mutant_tree = copy.deepcopy(tree)
|
||||
# The same node in the copy: by its place in a walk of the same function.
|
||||
index = [i for i, x in enumerate(ast.walk(fn)) if x is node][0]
|
||||
mfn = next(f for f in mutant_tree.body if isinstance(f, ast.FunctionDef) and f.name == fn.name)
|
||||
target = list(ast.walk(mfn))[index]
|
||||
replaced = transform(copy.deepcopy(target))
|
||||
_replace(mfn, target, replaced)
|
||||
ast.fix_missing_locations(mutant_tree)
|
||||
text = ast.unparse(mutant_tree) + _HELPERS_SOURCE
|
||||
ident = "P%04d %s:%d %s" % (k, fn.name, node.lineno, kind)
|
||||
out.append((ident, rules, what, text))
|
||||
return out
|
||||
|
||||
|
||||
def _replace(tree, old, new):
|
||||
for p in ast.walk(tree):
|
||||
for field, value in ast.iter_fields(p):
|
||||
if value is old:
|
||||
setattr(p, field, new)
|
||||
return
|
||||
if isinstance(value, list):
|
||||
for i, x in enumerate(value):
|
||||
if x is old:
|
||||
value[i] = new
|
||||
return
|
||||
raise ValueError("no place to replace")
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ the engine
|
||||
|
||||
_FUNCS = ("fn contract_form(", "pub fn problems(", "fn across(", "fn members(", "pub fn envelope_bytes(", "pub fn bare_transcript(")
|
||||
_MARK = re.compile(r"^\s*// (?:Rule )?(\d+)[.:]")
|
||||
_CMP = re.compile(r"(?<=[\w\)\]]) (>=|<=|>|<) (?=[\w\(&!*-])")
|
||||
_FLIP = {">=": ">", ">": ">=", "<=": "<", "<": "<="}
|
||||
_HELPERS_RS = '''
|
||||
|
||||
/// The weakening this build is, when wasmq_mutants.py made it: none otherwise.
|
||||
fn mutant(k: u32) -> bool {
|
||||
static WHICH: std::sync::OnceLock<u32> = std::sync::OnceLock::new();
|
||||
*WHICH.get_or_init(|| std::env::var("WQ_MUTANT").ok().and_then(|v| v.parse().ok()).unwrap_or(u32::MAX)) == k
|
||||
}
|
||||
|
||||
/// A weakening: any number is a count.
|
||||
fn loose_count(v: &Value) -> Option<u64> {
|
||||
v.as_f64().map(|x| x.abs() as u64)
|
||||
}
|
||||
|
||||
fn loose_whole(v: &Value, lo: u64, hi: u64) -> bool {
|
||||
loose_count(v).is_some_and(|n| lo <= n && n <= hi)
|
||||
}
|
||||
|
||||
fn loose_digest(v: &Value) -> bool {
|
||||
v.as_str().is_some_and(|s| s.len() == 64)
|
||||
}
|
||||
|
||||
fn raw_same(a: &Value, b: &Value) -> bool {
|
||||
a == b
|
||||
}
|
||||
'''
|
||||
|
||||
|
||||
def _calls(expr, name):
|
||||
"""Each place `name(` is called in expr: (start, end) of the call, its parentheses matched."""
|
||||
out = []
|
||||
for m in re.finditer(r"(?<![\w.])" + re.escape(name) + r"\(", expr):
|
||||
depth, i = 0, m.end() - 1
|
||||
while i < len(expr):
|
||||
if expr[i] == "(":
|
||||
depth += 1
|
||||
elif expr[i] == ")":
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
out.append((m.start(), i + 1))
|
||||
break
|
||||
i += 1
|
||||
return out
|
||||
|
||||
|
||||
def _args(call):
|
||||
"""A call's arguments, split at its top-level commas."""
|
||||
inner = call[call.index("(") + 1:-1]
|
||||
out, depth, start = [], 0, 0
|
||||
for i, ch in enumerate(inner):
|
||||
if ch in "([{":
|
||||
depth += 1
|
||||
elif ch in ")]}":
|
||||
depth -= 1
|
||||
elif ch == "," and depth == 0:
|
||||
out.append(inner[start:i].strip())
|
||||
start = i + 1
|
||||
out.append(inner[start:].strip())
|
||||
return out
|
||||
|
||||
|
||||
def _expr_mutants(expr):
|
||||
"""(kind, what, the expression weakened) for each weakening of one expression, `what`
|
||||
naming the expression it weakens."""
|
||||
return [(kind, "%s in `%s`" % (what, expr), mut) for kind, what, mut in _expr_mutants_bare(expr)]
|
||||
|
||||
|
||||
def _expr_mutants_bare(expr):
|
||||
out = []
|
||||
for m in _CMP.finditer(expr):
|
||||
out.append(("bound", "%s for %s" % (_FLIP[m.group(1)], m.group(1)), expr[:m.start(1)] + _FLIP[m.group(1)] + expr[m.end(1):]))
|
||||
for m in re.finditer(r"(?<![\w.<])Some\((\d+)\)", expr):
|
||||
out.append(("bound", "Some(%d) for Some(%s)" % (int(m.group(1)) + 1, m.group(1)), expr[:m.start(1)] + str(int(m.group(1)) + 1) + expr[m.end(1):]))
|
||||
for a, b in _calls(expr, "whole"):
|
||||
args = _args(expr[a:b])
|
||||
if len(args) == 3:
|
||||
out.append(("bound", "whole's upper bound one more", expr[:a] + "whole(%s, %s, (%s).saturating_add(1))" % (args[0], args[1], args[2]) + expr[b:]))
|
||||
if args[1].isdigit() and int(args[1]) > 0:
|
||||
out.append(("bound", "whole's lower bound one less", expr[:a] + "whole(%s, %d, %s)" % (args[0], int(args[1]) - 1, args[2]) + expr[b:]))
|
||||
out.append(("type", "whole read loosely", expr[:a] + "loose_whole(" + expr[a + len("whole("):]))
|
||||
for name, loose in (("count", "loose_count"), ("is_digest", "loose_digest"), ("same", "raw_same")):
|
||||
for a, b in _calls(expr, name):
|
||||
out.append(("type", "%s read loosely" % name, expr[:a] + loose + expr[a + len(name):]))
|
||||
for m in re.finditer(r"(?<![\w.])(\w+(?:\[[^\[\]]*\])*)\.get\(([^()]*)\)", expr):
|
||||
whole_get = m.group(0)
|
||||
recv, key = whole_get[: whole_get.rindex(".get(")], m.group(2)
|
||||
out.append(("null", "a null member read as absent: %s" % whole_get, expr[:m.start()] + "%s.get(%s).filter(|v| !v.is_null())" % (recv, key) + expr[m.end():]))
|
||||
out.append(("absent", "an absent member read as null: %s" % whole_get, expr[:m.start()] + "Some(%s.get(%s).unwrap_or(&Value::Null))" % (recv, key) + expr[m.end():]))
|
||||
for m in re.finditer(r"\.(max|min)\(\)", expr):
|
||||
other = "min" if m.group(1) == "max" else "max"
|
||||
out.append(("extreme", "%s() for %s()" % (other, m.group(1)), expr[:m.start(1)] + other + expr[m.end(1):]))
|
||||
for m in re.finditer(r"(\w+)\.contains_key\(([^()]*)\)", expr):
|
||||
out.append(("null", "a null member read as absent: contains_key", expr[:m.start()] + "%s.get(%s).is_some_and(|v| !v.is_null())" % (m.group(1), m.group(2)) + expr[m.end():]))
|
||||
return out
|
||||
|
||||
|
||||
def rust_schemata(engine_rs, out_json):
|
||||
"""Writes every weakening of the engine's form check into engine_rs, each behind
|
||||
mutant(K), and the list of them to out_json."""
|
||||
with open(engine_rs, encoding="utf-8") as f:
|
||||
lines = f.read().split("\n")
|
||||
mutants, rule, inside, depth = [], "?", False, 0
|
||||
new = []
|
||||
for no, line in enumerate(lines, 1):
|
||||
if not inside and any(line.startswith(f) or line.startswith(" " + f) or line.startswith("pub(crate) " + f) for f in _FUNCS):
|
||||
# What across reads before rule 20's mark is the fault, which rules 20 to 35 share.
|
||||
inside, depth, rule = True, 0, ("members" if "fn members(" in line else "20-35" if "fn across(" in line else "?")
|
||||
new.append(line)
|
||||
depth += line.count("{") - line.count("}")
|
||||
continue
|
||||
if inside:
|
||||
m = _MARK.match(line)
|
||||
if m:
|
||||
rule = m.group(1)
|
||||
if line.strip().startswith("fn ") and "fn priors(" in line:
|
||||
new.append(line)
|
||||
depth += line.count("{") - line.count("}")
|
||||
continue
|
||||
done = _mutate_line(line, lines[no] if no < len(lines) else "", rule, no, mutants)
|
||||
new.append(done)
|
||||
depth += line.count("{") - line.count("}")
|
||||
if depth <= 0:
|
||||
inside = False
|
||||
continue
|
||||
new.append(line)
|
||||
text = "\n".join(new)
|
||||
test_at = text.find("\n#[cfg(test)]")
|
||||
text = text[:test_at] + _HELPERS_RS + text[test_at:] if test_at >= 0 else text + _HELPERS_RS
|
||||
with open(engine_rs, "w", encoding="utf-8") as f:
|
||||
f.write(text)
|
||||
with open(out_json, "w", encoding="utf-8") as f:
|
||||
json.dump(mutants, f, indent=1)
|
||||
print("rust-schemata: %d weakenings written into %s" % (len(mutants), engine_rs))
|
||||
|
||||
|
||||
def _mutate_line(line, following, rule, no, mutants):
|
||||
"""The line with each weakening of its check behind mutant(K)."""
|
||||
def chain(expr, extra=()):
|
||||
variants = list(extra) + _expr_mutants(expr)
|
||||
if not variants:
|
||||
return None
|
||||
arms = []
|
||||
seen = defaultdict(int)
|
||||
for kind, what, mut in variants:
|
||||
k = len(mutants)
|
||||
seen[what] += 1
|
||||
if seen[what] > 1 or sum(1 for _, w, _ in variants if w == what) > 1:
|
||||
# The same weakening at two places of one expression: named by what it weakens.
|
||||
at = re.search(r'&\w\["(\w+)"\], &\w\["\1"\]', mut[mut.find("raw_same(") if "raw_same(" in mut else 0:])
|
||||
what = "%s#%s" % (what, at.group(1) if at else seen[what])
|
||||
mutants.append({"id": k, "rule": rule, "kind": kind, "what": what, "line": no})
|
||||
arms.append("if mutant(%d) { %s }" % (k, mut))
|
||||
if kind == "drop":
|
||||
mutants[-1]["what"] = "the check never fails: `%s`" % expr
|
||||
return "(" + " else ".join(arms) + " else { %s })" % expr
|
||||
pushes = following.strip().startswith(("out.push(", "problem("))
|
||||
m = re.match(r"^(\s*)if let (.+) = (.+) \{$", line)
|
||||
if m and not pushes and re.search(r"\.(max|min)\(\)", m.group(3)):
|
||||
# What a check after it reads, found as the most or the least of many.
|
||||
c = chain(m.group(3))
|
||||
return "%sif let %s = %s {" % (m.group(1), m.group(2), c) if c else line
|
||||
if m and pushes:
|
||||
# A check of what is found, as rule 1's: never found.
|
||||
k = len(mutants)
|
||||
mutants.append({"id": k, "rule": rule, "kind": "drop", "what": "the check never fails: `%s`" % m.group(3), "line": no})
|
||||
return "%sif let %s = (%s).filter(|_| !mutant(%d)) {" % (m.group(1), m.group(2), m.group(3), k)
|
||||
m = re.match(r"^(\s*)&& (.+)$", line)
|
||||
if m and following.strip() == "{":
|
||||
c = chain(m.group(2), [("drop", "the check never fails", "false")])
|
||||
return "%s&& %s" % (m.group(1), c) if c else line
|
||||
m = re.match(r"^(\s*)if (?!let )(.+) \{$", line)
|
||||
if m and pushes and " let " not in m.group(2):
|
||||
c = chain(m.group(2), [("drop", "the check never fails", "false")])
|
||||
return "%sif %s {" % (m.group(1), c) if c else line
|
||||
m = re.match(r"^(\s*)((?:Some\(.*?\)|None)) if (.+?) => (.*)$", line)
|
||||
if m:
|
||||
c = chain(m.group(3), [("drop", "the check never fails", "false")])
|
||||
return "%s%s if %s => %s" % (m.group(1), m.group(2), c, m.group(4)) if c else line
|
||||
m = re.match(r"^(\s*)match (.+) \{$", line)
|
||||
if m and ".get(" in m.group(2):
|
||||
c = chain(m.group(2))
|
||||
return "%smatch %s {" % (m.group(1), c) if c else line
|
||||
m = re.match(r"^(\s*)let (mut )?([\w(), ]+?)(: [^=]+)? = (.+);$", line)
|
||||
if m and not m.group(5).lstrip().startswith(("|", "move |")) and any(x in m.group(5) for x in ("count(", "whole(", ".get(", " > ", " < ", " >= ", " <= ", "Some(")):
|
||||
c = chain(m.group(5))
|
||||
return "%slet %s%s%s = %s;" % (m.group(1), m.group(2) or "", m.group(3), m.group(4) or "", c) if c else line
|
||||
return line
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ running them
|
||||
|
||||
def caught(env_extra, reference, second=None):
|
||||
cmd = [sys.executable, "-I", DIFFERENTIAL, "--reference", reference, "--wasmq-only", "--first"]
|
||||
if second:
|
||||
cmd += ["--second", second]
|
||||
env = dict(os.environ)
|
||||
env.update(env_extra)
|
||||
p = subprocess.run(cmd, capture_output=True, text=True, env=env)
|
||||
first = next((l for l in p.stdout.splitlines() if l.startswith("DISAGREE")), "")
|
||||
if p.returncode not in (0, 1):
|
||||
return None, (p.stderr.strip().splitlines() or ["status %d" % p.returncode])[-1]
|
||||
return p.returncode == 1, first
|
||||
|
||||
|
||||
def report(results):
|
||||
"""results: (id, rules, kind, what, caught, why). Prints counts per rule; returns the
|
||||
survivors not listed as equivalent."""
|
||||
per = defaultdict(lambda: defaultdict(int))
|
||||
survivors = []
|
||||
for ident, rules, kind, what, got, why in results:
|
||||
for r in rules:
|
||||
per[str(r)]["generated"] += 1
|
||||
per[str(r)]["caught" if got else "equivalent" if _equivalent(rules, kind, what) else "survived"] += 1
|
||||
if not got and not _equivalent(rules, kind, what):
|
||||
survivors.append((ident, rules, kind, what, why))
|
||||
def key(r):
|
||||
return (0, int(r)) if r.isdigit() else (1, r)
|
||||
print("%-10s %9s %7s %10s %8s" % ("rule", "generated", "caught", "equivalent", "survived"))
|
||||
for r in sorted(per, key=key):
|
||||
c = per[r]
|
||||
print("%-10s %9d %7d %10d %8d" % (r, c["generated"], c["caught"], c["equivalent"], c["survived"]))
|
||||
for s in survivors:
|
||||
print("SURVIVED %s (rules %s) %s: %s %s" % (s[0], ",".join(map(str, s[1])), s[2], s[3], s[4]))
|
||||
return survivors
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("what", choices=["python", "rust", "rust-schemata"])
|
||||
ap.add_argument("paths", nargs="*")
|
||||
ap.add_argument("--reference")
|
||||
ap.add_argument("--mutants")
|
||||
ap.add_argument("--jobs", type=int, default=4)
|
||||
ap.add_argument("--rule", help="only the weakenings of this rule")
|
||||
ap.add_argument("--list", action="store_true", help="list the weakenings, run none")
|
||||
a = ap.parse_args()
|
||||
if a.what == "rust-schemata":
|
||||
engine_rs, out_json = a.paths
|
||||
return rust_schemata(engine_rs, out_json)
|
||||
if a.what == "python" and a.list:
|
||||
ms = [m for m in python_mutants() if not a.rule or a.rule in map(str, m[1])]
|
||||
counts = defaultdict(lambda: defaultdict(int))
|
||||
for ident, rules, what, _ in ms:
|
||||
print(ident, rules, what)
|
||||
for r in rules:
|
||||
counts[str(r)][ident.split()[-1]] += 1
|
||||
for r in sorted(counts, key=lambda r: (0, int(r)) if r.isdigit() else (1, r)):
|
||||
print("rule %s: %s" % (r, dict(counts[r])))
|
||||
print("%d weakenings" % len(ms))
|
||||
return 0
|
||||
if not a.reference:
|
||||
ap.error("--reference is required")
|
||||
cache = tempfile.mkdtemp(prefix="wasmq-mutants-cache-")
|
||||
base = {"RD_CACHE": cache}
|
||||
# The unweakened pair agrees: else nothing below means anything.
|
||||
ok, why = caught(base, a.reference)
|
||||
if ok is not False:
|
||||
print("the unweakened verifiers do not agree, or the differential failed: %s" % why)
|
||||
return 2
|
||||
results = []
|
||||
if a.what == "python":
|
||||
ms = [m for m in python_mutants() if not a.rule or a.rule in map(str, m[1])]
|
||||
if a.list:
|
||||
for ident, rules, what, _ in ms:
|
||||
print(ident, rules, what)
|
||||
return 0
|
||||
tmp = tempfile.mkdtemp(prefix="wasmq-mutants-py-")
|
||||
|
||||
def one(m):
|
||||
ident, rules, what, text = m
|
||||
path = os.path.join(tmp, "m%s.py" % ident.split()[0])
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(text)
|
||||
got, why = caught(base, a.reference, second=path)
|
||||
os.remove(path)
|
||||
return (ident, rules, ident.split()[-1], what, bool(got), why)
|
||||
with ThreadPoolExecutor(a.jobs) as pool:
|
||||
for r in pool.map(one, ms):
|
||||
results.append(r)
|
||||
print("%s %-8s %s %s" % ("caught " if r[4] else "SURVIVED", r[2], r[0], r[3]), flush=True)
|
||||
else:
|
||||
with open(a.mutants, encoding="utf-8") as f:
|
||||
ms = [m for m in json.load(f) if not a.rule or m["rule"] == a.rule]
|
||||
|
||||
def one(m):
|
||||
env = dict(base, WQ_MUTANT=str(m["id"]))
|
||||
got, why = caught(env, a.reference)
|
||||
ident = "R%04d line %d %s" % (m["id"], m["line"], m["kind"])
|
||||
return (ident, [m["rule"]], m["kind"], m["what"], bool(got), why)
|
||||
with ThreadPoolExecutor(a.jobs) as pool:
|
||||
for r in pool.map(one, ms):
|
||||
results.append(r)
|
||||
print("%s %-8s %s %s" % ("caught " if r[4] else "SURVIVED", r[2], r[0], r[3]), flush=True)
|
||||
survivors = report(results)
|
||||
print("%s: %d weakenings, %d caught, %d survived" % (a.what, len(results), sum(1 for r in results if r[4]), len(survivors)))
|
||||
return 1 if survivors else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
2
wai/quantum-conformance/wasmq/.gitattributes
vendored
Normal file
2
wai/quantum-conformance/wasmq/.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# The modules of record, the envelopes and the WebAssembly vectors are compared byte for byte: never converted.
|
||||
* -text
|
||||
27
wai/quantum-conformance/wasmq/README.md
Normal file
27
wai/quantum-conformance/wasmq/README.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# wasmQ conformance
|
||||
|
||||
Vectors for [`../../extensions/quantum-wasmq.md`](../../extensions/quantum-wasmq.md) §9.
|
||||
|
||||
**Provenance.** Generated here by `wai-wasmq`'s `tests/vectors.rs` (`WASMQ_BLESS=1`) from the
|
||||
reference programs (`wai-wasmq/src/reference.rs`) and modules written as WebAssembly text or
|
||||
bytes in that file, which also holds every committed file to the bytes it makes. No media.
|
||||
|
||||
| path | what |
|
||||
|---|---|
|
||||
| `modules/` | the reference modules of record, built on x86_64 Linux by `wai-wasmq/modules/build.sh`, with `modules.json`: their digests and the SHA-256 of every source that made them |
|
||||
| `envelopes/` | envelopes; `vectors.json` `runs` pins what each gives on every engine and host: status, fault, fuel, the transcript's digest, the result's digest, the receipt's digest and, under the vectors' key (32 bytes of 7), the whole job's digest |
|
||||
| `envelopes/surface3-decode64.*` | one run in the open: its program, the prior its decoder reads (the code's parity checks) and its sealed job |
|
||||
| `refuse/` | modules (also as WebAssembly text, where they have one) and envelopes a runner refuses; `vectors.json` `refuse` gives each one's code. There is at least one for every code, and each is one defect away from a module or an envelope that is accepted, which the test that makes them checks |
|
||||
|
||||
```sh
|
||||
cargo run --release --manifest-path wai/wai-wasmq/Cargo.toml --bin wasmq_vectors -- verify wai/quantum-conformance/wasmq
|
||||
```
|
||||
|
||||
prints a line for each vector and a digest of all of them: the same on every host and
|
||||
every engine that conforms. Under wasm32 it runs with the interpreter alone:
|
||||
|
||||
```sh
|
||||
cargo build --release --target wasm32-wasip2 --manifest-path wai/wai-wasmq/Cargo.toml --no-default-features --bin wasmq_vectors
|
||||
wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y --dir wai/quantum-conformance/wasmq::/v \
|
||||
wai/wai-wasmq/target/wasm32-wasip2/release/wasmq_vectors.wasm verify /v
|
||||
```
|
||||
BIN
wai/quantum-conformance/wasmq/envelopes/atoms4x4-plan64.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/atoms4x4-plan64.wai
Normal file
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/atoms9x9-plan.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/atoms9x9-plan.wai
Normal file
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/bits-nothing-writes.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/bits-nothing-writes.wai
Normal file
Binary file not shown.
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-bad-result.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-bad-result.wai
Normal file
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-fuel-instance.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-fuel-instance.wai
Normal file
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-fuel-run.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-fuel-run.wai
Normal file
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-fuel.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-fuel.wai
Normal file
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-in-init.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-in-init.wai
Normal file
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-in-prior.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-in-prior.wai
Normal file
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-in-seed.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-in-seed.wai
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-list-length.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-list-length.wai
Normal file
Binary file not shown.
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-list-outside.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-list-outside.wai
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-stack.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-stack.wai
Normal file
Binary file not shown.
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-trap.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-trap.wai
Normal file
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/fault-unreachable.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/fault-unreachable.wai
Normal file
Binary file not shown.
BIN
wai/quantum-conformance/wasmq/envelopes/gross-decode.wai
Normal file
BIN
wai/quantum-conformance/wasmq/envelopes/gross-decode.wai
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue