Some checks failed
wai-quantum command line / does this change touch it (push) Successful in 30s
joule-moq-room room service / joule-moq-room · does this change touch it (push) Successful in 49s
wai-quantum OpenQASM reader / does this change touch it (push) Failing after 1m21s
wai-quantum other formats / does this change touch it (push) Successful in 1m31s
wai-quantum resource estimation / does this change touch it (push) Successful in 1m31s
WAI operation catalogue / does this change touch it (push) Successful in 1m45s
wai-quantum editors / does this change touch it (push) Successful in 1m33s
wai-quantum contract / does this change touch it (push) Successful in 1m36s
wai-quantum OpenQASM reader / reader and corpus · linux (push) Has been skipped
wai-quantum OpenQASM reader / corpus under wasm32-wasip2 (wasmtime) (push) Has been skipped
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Failing after 3m0s
wai-quantum for JavaScript / does this change touch it (push) Successful in 1m1s
wai-audit collector and player integration / does this change touch it (push) Successful in 1m38s
wai-quantum docs, course and locales / does this change touch it (push) Successful in 1m23s
wai-quantum clippy / does this change touch it (push) Successful in 1m25s
wai-quantum extension points / does this change touch it (push) Successful in 1m30s
wai-quantum service / does this change touch it (push) Successful in 1m37s
wai-quantum for Python / does this change touch it (push) Successful in 1m39s
wai-sink-android native sink library / does this change touch it (push) Successful in 38s
wai-quantum pulse and dynamics / does this change touch it (push) Successful in 1m40s
wai-quantum verdicts and repairs / does this change touch it (push) Successful in 38s
wai-quantum views in agent hosts / does this change touch it (push) Successful in 38s
wai-quantum studio and desktop / does this change touch it (push) Successful in 1m39s
wai-quantum error correction and mitigation / does this change touch it (push) Successful in 1m41s
wai-sink-swift native sink package / does this change touch it (push) Successful in 39s
wai-quantum variational and algorithm library / does this change touch it (push) Successful in 1m40s
wai-quantum qudit jobs / does this change touch it (push) Successful in 1m40s
wai-quantum service / service energy · linux packages (push) Failing after 7s
WAI Studio / does this change touch it (push) Successful in 1m5s
wai-quantum command line / command line · macos (push) Successful in 2m34s
wai-quantum editors / editors · macos (push) Successful in 2m13s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 2m7s
wai-quantum pulse and dynamics / the same bits · macos (push) Successful in 1m12s
wai-quantum for Python / python · macos (push) Successful in 3m46s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 4m17s
wai-quantum qudit jobs / the same bits · macos (push) Successful in 2m53s
joule-moq-room room service / joule-moq-room, every target (push) Successful in 13m2s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 13s
wai-quantum service / service · macos (push) Successful in 8m44s
WAI examples / WAI examples · does this change touch them (push) Successful in 14s
wai-quantum landscape energy to solution / does this change touch it (push) Successful in 10s
wai-quantum energy-landscape jobs / does this change touch it (push) Successful in 14s
wai-quantum pulse and dynamics / the same bits · linux-arm64 (push) Successful in 3m26s
wai-quantum wasmQ / does this change touch it (push) Successful in 11s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 10m41s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux-arm64, release (push) Successful in 3m12s
wai-quantum extension points / the registry and the example · linux-arm64 (push) Successful in 8m17s
wai-quantum landscape energy to solution / the small tier, to the byte · macos (push) Successful in 1m48s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 9m19s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · macos (push) Successful in 2m28s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Successful in 16m22s
wai-quantum other formats / the set under wasm32-wasip2 (wasmtime) (push) Successful in 3m2s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 11m28s
wai-quantum energy-landscape jobs / the same bits · macos (push) Successful in 7m41s
wai-quantum resource estimation / estimation and calibration · linux, release (push) Successful in 7m29s
wai-quantum other formats / readers, writers and the set · linux (push) Successful in 8m5s
wai-quantum contract / the policy is linked, and the deprecations page reads (push) Successful in 10s
wai-quantum editors / editors · linux (push) Successful in 5m22s
wai-quantum docs, course and locales / the Studio's words in every locale · linux (push) Successful in 17s
wai-quantum contract / API compatibility · linux (push) Successful in 10m39s
wai-audit collector and player integration / collector · linux (push) Successful in 4m3s
wai-quantum contract / schemas and the committed tool lists · linux (push) Successful in 11m56s
WAI operation catalogue / the catalogue and every door · linux (push) Successful in 15m32s
wai-quantum docs, course and locales / the course and the command line's languages · linux (push) Successful in 7m39s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (push) Successful in 23m22s
WAI examples / WAI examples · android-app · linux-arm64 (push) Successful in 13m10s
wai-quantum energy-landscape jobs / the same bits · linux-arm64 (push) Successful in 14m4s
wai-quantum clippy / clippy, warnings denied, every feature set · linux (push) Successful in 6m46s
wai-quantum extension points / the registry under wasm32-wasip2 (wasmtime) (push) Successful in 5m10s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs · linux, release (push) Successful in 3m37s
wai-quantum command line / command line · linux (push) Successful in 26m45s
wai-quantum for Python / python · linux (push) Successful in 5m50s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs under wasm32-wasip2 (wasmtime) (push) Successful in 1m42s
wai-quantum verdicts and repairs / the intent set and the verdict under wasm32-wasip2 (wasmtime) (push) Successful in 2m46s
wai-quantum for JavaScript / javascript · linux (push) Successful in 10m8s
wai-quantum verdicts and repairs / verdicts, repairs and the intent set · linux (push) Successful in 4m40s
wai-quantum extension points / the registry and the example · linux (push) Successful in 10m53s
wai-quantum studio and desktop / studio · browser (push) Successful in 4m37s
wai-quantum qudit jobs / the module and the conformance set under wasm32-wasip2 (wasmtime) (push) Successful in 2m20s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 1m25s
wai-quantum error correction and mitigation / codes, decoders, texts and mitigation · linux, release (push) Successful in 6m55s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux, release (push) Successful in 4m3s
wai-quantum views in agent hosts / views · a scripted host (push) Successful in 8m36s
wai-quantum views in agent hosts / views · the page and its engine (push) Successful in 9m8s
wai-quantum service / service · linux (push) Successful in 17m4s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 11m50s
wai-quantum qudit jobs / the module, the job, the conformance set, the referee and the verb · linux (push) Successful in 10m48s
WAI Studio / Studio in WebKit · linux (push) Successful in 14m41s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 3m47s
wai-quantum landscape energy to solution / the small tier, to the byte · linux (push) Successful in 3m42s
wai-quantum docs, course and locales / every command and snippet in the docs · linux (push) Successful in 42m41s
wai-quantum wasmQ / the reference modules rebuild to their modules of record · linux (push) Successful in 49s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 8m49s
wai-quantum wasmQ / interpreter and vectors under wasm32-wasip2 (wasmtime) (push) Successful in 6m27s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · linux (push) Successful in 8m21s
WAI examples / WAI examples · portable · linux (push) Successful in 19m7s
wai-quantum energy-landscape jobs / reader, kernels, answers and the stated result · linux, release (push) Successful in 19m35s
wai-quantum energy-landscape jobs / native against WebAssembly, over many seeds (push) Successful in 18m55s
wai-quantum energy-landscape jobs / the module under wasm32-wasip2 (wasmtime) (push) Successful in 19m48s
wai-quantum studio and desktop / desktop app · windows (push) Successful in 14m44s
The four legs of wai-quantum-windows.yml had never passed. Run 32449 (8617d9d02) failed in
each; what each leg's failure was, and what this changes:
- engine · windows. Two engine::energy tests failed with os error 267: their fixture makes
the powercap interface's own zone directories, `intel-rapl:0`, and NTFS reads the colon as
the start of a stream's name, so no Windows file system can hold that name (checked on the
runner: 267 for `intel-rapl:0`, 123 for `intel-rapl:0:0`). The reader is Linux's interface
and every caller opens it on Linux alone, so the fixture, `tree()` and the two tests are
cfg(unix), with a note saying why; a cfg(windows) test pins what Windows has instead: the
name cannot be made a directory, `access_in` answers NoInterface, and `Packages::open`
fails with that reason. No line outside the tests changes.
- command line · windows. Its test binary did not compile (E0433, E0599): the ceiling test
used std::os::unix's PermissionsExt and Permissions::from_mode with no gate. Its runs are
shell scripts held to Linux's and macOS's counters, so it is cfg(unix), and a cfg(windows)
test asserts what Windows does: a run under a ceiling is refused, for want of a package
counter, before any process starts. Two more tests of that module, which now compile on
Windows, would have failed there: the package-counter test (the same 267 fixture, now
cfg(unix)), and the timings-path test, whose `/x` is not absolute on Windows (it now names
`C:\x` there; path_from is unchanged). die_with_parent says what Windows does: it starts
no run in a process of its own, as it reads no counter there.
- job service · windows. The binary and its tests did not compile: open_files() raised
RLIMIT_NOFILE through libc, a cfg(unix) dependency, with no gate (six E0433). It is
cfg(unix); on Windows, which sets a process no open-file limit, a twin logs that and
returns the 2^24 handles a process may hold, so connections are held under
WAI_QSVC_CONNECTIONS alone. Built, the service would then have failed every job and held
none to its budget, so each Unix-only step it takes has its Windows form:
- workers and the writer were started through `nice`, which Windows has not; they are
started directly, in BELOW_NORMAL_PRIORITY_CLASS;
- a process's memory, read through `ps` off Linux and macOS, and the host's, through
sysctl and memory_pressure, read nothing there, which turned off the per-job cap, the
reader's cap and the queue's wait for free memory; src/win32.rs asks the system
(K32GetProcessMemoryInfo, the commit charge, which counts pages paged out as Linux's
VmSwap does; GlobalMemoryStatusEx);
- a worker, a reader or the writer whose service has died ran on, as watch_parent is
Unix's; on Windows it waits on the service's process (OpenProcess, WaitForSingleObject)
and exits when it ends, the reader now told the service's pid as workers are;
- write_private wrote over an existing key on Windows; it now makes a new file only, as
on Unix, and says the file is as private as its folder's inherited access list.
The tests that would have failed there: the binary-replacement test moves the running
binary aside and puts the new one at its name (Windows refuses a copy over it, 32, and a
rename onto it, 5); mem_kib reads the working set through PowerShell, as there is no `ps`;
the writer tests' script reaches the writer late through a named pipe the test serves
(Late), as through a FIFO on Unix, where mkfifo is unchanged. The depth.rs connection
helpers are cfg(unix) with the connection tests, which hold the service to `ulimit -n`.
- python · windows. test_a_set_s_text_is_judged_as_a_set found cli-set-sweep.json invalid
(items_sealed and root false): Path.read_text() with no encoding decodes in the ANSI code
page (1252 on the runner), which turned the receipt's `π` and `≤` into other characters,
so the items' sealed texts no longer hashed to their seals; cli-set-programs.json, all
ASCII, passed. The package's own path readers (_source, _job_of, _job_text, _document,
landscape) did the same, so every Windows user's receipts and programs given as a path were
read wrong. Every read_text in the package and its tests now names UTF-8, as the command
line and the service read; the verifier is unchanged. In the tests, the command line's and
node's output are decoded as UTF-8, and test_cli's fixtures are written as UTF-8 bytes,
without the CR LF text mode writes on Windows. Key.save writes its bytes in binary mode, so
a key file is the command line's `<64 hex>\n` on every system, and the test compares the
bytes everywhere and exempts only the mode bits on Windows; user_key_path follows the
command line's order, XDG_CONFIG_HOME, then HOME's .config, then APPDATA, which it
lacked, so the two found different keys on Windows. Tests for each, one of them run against
the command line with only APPDATA set.
Unix behaves as before: every change there is a cfg attribute, a branch that is false on
Unix (cfg!(windows)), test code, or Python that decodes as the UTF-8 locales on Linux and
macOS already did; the FIFO tests run as they did.
Verified, toolchain 1.99.1. Build host (macOS): `cargo check --target x86_64-pc-windows-msvc
--all-targets` exits 0 for wai-quantum (full), the command line and the service, and clippy for
that target warns of nothing in these files (ring's C, which needs MSVC headers, was compiled
from an empty file for the check; nothing is linked); a type error put in five of the new
Windows-only pieces (win32.rs, rss_bytes, watch_parent, the pipe's give, the command line's
Windows test) fails that check at each. On macOS and on Linux (x86_64): clippy -D warnings in
wai-quantum (default, full, wasm32-wasip2 full), the command line (default, none) and the
service; engine::energy 15 and 14 passed; the command line's tests and the service's tests
all passed; on macOS the Python package's ci/check.sh (103 passed, nothing skipped, the
notebooks, Python 3.9) and the suite again under LC_ALL=en_US.ISO8859-1 (103 passed). Text
checks: comparative prose, public names (maintainer products), vanity metrics, quantum names,
changelog entries, tests in CI. On the Windows runner, a probe compiled from src/win32.rs and
the test's Late as they are: a process's commit charge and the host's memory read, a watch on
a process that ends exits 3 when it ends, the below-normal start runs, a killed first reader
leaves the script to the second, which reads all 100,004 bytes, and a running binary is moved
aside and replaced. Not run on Windows: the crates' own tests, which the nightly Windows run
will show.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
137 lines
13 KiB
Markdown
137 lines
13 KiB
Markdown
<!-- 机器辅助翻译(machine-assisted translation):在对外推广之前,须由熟练的读者审校。 -->
|
||
|
||
# Python 版 wai-quantum
|
||
|
||
> 本文为机器辅助翻译,尚待熟练的读者审校。英文原文:[README.md](README.md)。
|
||
|
||
在 Python 和笔记本中以进程内方式使用 WAI Quantum。这个包内含 WAI Quantum 作业引擎(Rust crate `wai-quantum` 的 `engine`,通过一个 pyo3 扩展模块提供),因此在这里规划、运行并封存的作业,与 `wai-quantum` 命令行、作业服务、MCP 服务器、Studio 和桌面应用给出相同的计划、相同的结果和相同的回执。
|
||
|
||
- **引擎**:`run`、`plan`、`lint`、`draw`(文本和 SVG)、`layout`、`critique`、`improve`、`shortcuts`、`equivalent`、`verify`、`seal`、`canonical`、`digest`、`methods`、`accuracy_classes`、`bloch`、`history`、`estimate` 和 `verify_estimate`。
|
||
- **回执**:每个结果都用你传入的密钥(`wai_quantum.Key`)封存;任何回执(无论是在这里、由命令行、由作业服务还是在浏览器标签页中生成的)都可以在这里离线检查。
|
||
- **作业服务**:`wai_quantum.Service`,一个只用标准库实现的客户端,用于 `https://wai.transaction.science/quantum-jobs/v1`。
|
||
- **笔记本小组件**:`Circuit`、`Result`、`Receipt` 和 `Bloch`,附有可在任何笔记本中渲染的静态 HTML 和 SVG 后备显示。
|
||
|
||
## 安装
|
||
|
||
从 Python 包索引安装。每个平台一个 wheel,适用于 3.9 及以后的所有 Python 版本(稳定 ABI,`abi3`):macOS arm64 和 x86_64、Linux x86_64 和 arm64(manylinux 2.17)、Windows x86_64。
|
||
|
||
```sh norun=install
|
||
pip install wai-quantum # 引擎和作业服务客户端:没有其他依赖
|
||
pip install "wai-quantum[widgets]" # 另加笔记本小组件(anywidget)
|
||
```
|
||
|
||
同样的 wheel 也附在代码托管平台(forge)上包含它们的 `wai-quantum-cli-v<version>` 发布版中,每个都附有 SHA-256:
|
||
|
||
```sh norun=install
|
||
pip install wai_quantum-0.1.4-cp39-abi3-<platform>.whl
|
||
```
|
||
|
||
要自己构建 wheel,需要 Rust 1.98 和 maturin 1.15.0:
|
||
|
||
```sh norun=install
|
||
cd wai/wai-quantum-py
|
||
maturin build --release --locked -o dist
|
||
pip install dist/wai_quantum-*.whl
|
||
```
|
||
|
||
## 使用
|
||
|
||
```python runnable
|
||
import wai_quantum as wq
|
||
|
||
bell = "OPENQASM 3.0; qubit[2] q; bit[2] c; h q[0]; cx q[0], q[1]; c = measure q;"
|
||
key = wq.Key.generate() # 或 Key.from_file(...)、Key.demo();默认使用这个用户的密钥
|
||
job = wq.run(bell, shots=1000, key=key)
|
||
|
||
job.method, job.accuracy # ('stabilizer', 'exact')
|
||
job.counts # {'00': 522, '11': 478}
|
||
job.probabilities() # 每个计数除以测量次数:采样得到的频率
|
||
wq.verify(job).valid # True:回执封存了这个请求和这个结果
|
||
```
|
||
|
||
作业就是作业服务所用的形式,表示为一个普通的 `dict`(`status`、`method`、`why`、`estimate`、`request`,以及带有 `receipt` 的 `result`),因此 `json.dumps(job)` 写出的就是作业服务会发送的内容。它的辅助方法读取最常用的部分:`counts`、`shots`、`probabilities()`、`expectations`、`amplitudes`、`method`、`accuracy`、`receipt`、`verify()`。
|
||
|
||
`run` 接受 OpenQASM 3(或 2)文本、此类文件的路径或一个作业 dict,并以关键字参数接受作业的各字段:`shots`、`seed`、`method`(默认为 `auto`)、`observables`(`"Z0 Z1"` 或 `{"pauli": "X3 Y4", "coeff": 0.5}`)、`amplitudes`(比特串,量子比特 n − 1 在前)、`noise`(`depolarizing_1q`、`depolarizing_2q`、`amplitude_damping`、`dephasing`、`readout`)以及 `options`(因方法而异;`wq.methods()` 会列出它们)。`memory_gb`(16,即命令行的默认值)限定作业在这里可以占用的内存,因此作业在两者上会规划到同一种方法。
|
||
|
||
```python runnable
|
||
src = "OPENQASM 3.0; qubit[2] q; h q[0]; t q[0]; t q[0]; cx q[0], q[1];"
|
||
a, b = "qubit[1] q; h q[0]; x q[0]; h q[0];", "qubit[1] q; z q[0];"
|
||
job = wq.run(bell, shots=100, intent={"distribution": {"00": 0.5, "11": 0.5}}, key=key)
|
||
job.verdict["level"], job.verdict["holds"] # ('proof', True):引擎检查到了哪一级,已封存
|
||
job.verdict["layer"], job.verdict["limits"] # 由什么判定('exact_simulation'),以及它不能说明什么
|
||
wq.verify(job).answer["again"] # 'reproduced':已封存的裁定在此处重新得出
|
||
wq.verdict(job, {"distribution": {"00": 1.0}}) # 另一个意图,在这里得出:注明未经封存
|
||
wq.signoff(job, {"outcomes": ["00", "11"]}, key=key).verdict["holds"] # 为已封存的作业签核:其摘要、意图和裁定封存于同一回执之下
|
||
fair = {"distribution": {"00": 0.5, "11": 0.5}}
|
||
wq.check(bell, fair)["next"] # 签核循环:每个用例由最强的层判定,并说明下一步;不封存任何内容
|
||
g = wq.grade(bell, {"title": "A Bell pair", "intent": fair}, key=key) # 评分作为作业封存,任何人都可以重新运行
|
||
wq.verify(g).answer["again"] # 'reproduced':评分在这里重新得出
|
||
wq.attest(job, {"outcomes": ["00", "11"]}, key=key)["attested"]["held_to"] # 作业先像 verify 那样核验,然后签核
|
||
wq.repair("OPENQASM 3.0;\nqubit[1] q\nh q[0];\n") # 对被标出的行的修正,以及需要人来处理的部分
|
||
wq.plan(bell) # 方法及其原因,不运行
|
||
wq.lint("qubit[1] q;\nfoo q[0];") # {'ok': False, 'error': 'line 2: unknown gate foo', 'line': 2}
|
||
print(wq.draw(bell)) # 文本线路图,与 `wai-quantum draw` 打印的相同
|
||
svg = wq.draw(bell, format="svg") # Studio 中的图,作为一个 SVG 文档
|
||
wq.critique(src); wq.improve(src) # 度量与问题模式;经证明等价的变体
|
||
wq.equivalent(a, b) # {'verdict': 'equivalent', 'how': 'tableau', 'why': ...}
|
||
wq.bloch("OPENQASM 3.0; qubit[1] q; ry(0.3) q[0];", key=key) # 每个量子比特的约化态,来自引擎
|
||
e = wq.estimate(src, qubit="ns-e4", budget=1e-3, key=key) # 容错量子计算机需要什么,每个估算都已封存
|
||
wq.verify_estimate(e) # 封存签名、每一份回执,以及在这里重新运行的请求
|
||
wq.estimate(counts={"numQubits": 100, "cczCount": 5000}) # 或者一份逻辑计数(或 routine=)文档
|
||
```
|
||
|
||
`estimate` 给出程序的逻辑计数(逻辑量子比特,包括多控制门所需的辅助量子比特;测量;T 门;Toffoli 门;旋转门及其合成所得门序列中的 T 门;T 深度和深度)、错误预算中分给合成的份额及每个旋转门所占的部分、根据引擎自己的解码器对码模型所做的校准、在该物理量子比特上的估算,以及物理量子比特数与运行时间之间的前沿,每个估算都在资源估算回执族中封存。`export="counts"` 或 `"routine"` 会把计数另外作为一份文档给出。每个数字的含义和假设,见[估算页面](../wai-quantum/docs/estimate.md)。
|
||
|
||
```python runnable
|
||
c = wq.qec_code("color:7", key=key) # 它的校验、k、可用的解码器,以及经过认证的距离
|
||
wq.qec_code("color:7", certificate=c) # 重新运行证书的见证和搜索
|
||
wq.qec_decode("surface:5", error=[3, 12]) # 解码其校验子,并判定残差
|
||
wq.qec_decode(memory=(5, 5, 0.003), shots=20000, decoder="correlated") # 线路层面的失败率
|
||
wq.qec_threshold(distances=[3, 5, 7], p=[0.002, 0.004], shots=20000) # 失败率及其误差
|
||
job = wq.run(src, observables=["Z0 Z1"], noise={"depolarizing_2q": 0.02}, mitigate="zne", key=key)
|
||
job["result"]["mitigation"] # 每个值的原始值和缓解后的值及其误差棒,以及该方法的假设
|
||
```
|
||
|
||
`qec_code`、`qec_decode` 和 `qec_threshold` 是引擎的纠错功能,与命令行的 `wai-quantum qec` 以及两个 MCP 服务器的 `qec_*` 工具给出的回答相同,每个回答都以作业的形式封存(`wq.verify` 检查它)。距离证书在每个扇区中给出找到的逻辑算符的最小权重、该权重的一个见证,以及经穷举搜索排除的每个更轻的支撑;被 `bound` 截止的搜索对其之外的情况不作结论。每个解码器保证什么,以及每种缓解方法的偏差和方差,见[纠错页面](../wai-quantum/docs/qec.md)。
|
||
|
||
### 密钥与回执
|
||
|
||
`Key.demo()` 是公开的演示密钥(即命令行的 `--demo-key`):用它签名的回执在任何地方都逐字节重现,只能证明结果未被篡改。`Key.generate()` 生成一个密钥;`key.save(path)` 以命令行所用的格式(64 位十六进制数字)把它写出,且仅其所有者可读,因此 `wai-quantum run --key path` 会用同一个密钥签名。未给出密钥时,`run` 用这个用户的密钥签名,也就是命令行自己用的那个(`$WAI_QUANTUM_KEY`,否则为 `$XDG_CONFIG_HOME/wai/quantum-key` 或 `~/.config/wai/quantum-key`,在 Unix 类 shell 之外的 Windows 上为 `%APPDATA%\wai\quantum-key`,首次使用时生成)。
|
||
|
||
回执是对请求和结果的 RFC 8785 规范化 JSON 所求 BLAKE3 摘要的 Ed25519 签名。`wq.canonical(value)` 给出这些字节,`wq.digest(request, result)` 给出摘要;`wq.seal(request, result, key=...)` 可封存任何结果。拒绝会引发 `wq.EngineError`,附带引擎自身的消息、消息指明了行号时的 `line`,以及其 `code`:读取器的(`Q103`)或作业层的(`J011`),与消息末尾所附的相同。对于改动了没有任何诊断标出的行的建议,`wq.repair(program, proposed=...)` 会引发一个带 `J021` 的此类错误。[判定页面](../wai-quantum/docs/verdicts.md)列出了各个级别和规则。
|
||
|
||
### 作业服务
|
||
|
||
```python runnable
|
||
svc = wq.Service() # $WAI_QUANTUM_SERVICE,或 https://wai.transaction.science/quantum-jobs/v1
|
||
job = svc.run(bell, shots=1000) # 提交并等待
|
||
rec = svc.submit(bell, shots=1000) # 或者:先提交,再 status / result / cancel
|
||
job = svc.result(rec["id"])
|
||
svc.verify(job) # 在这里离线检查;把它的密钥与 svc.describe()["receipt_key"] 对比
|
||
```
|
||
|
||
客户端使用 `urllib`,并在每个请求的 `User-Agent` 中自称 `wai-quantum-python/<version>`:作业服务的边缘节点会拒绝带有通用库默认用户代理的请求。拒绝、失败或被取消的作业,或无法连通的作业服务,都会引发 `wq.ServiceError`,附带 HTTP `status` 和作业服务的原话。
|
||
|
||
### 笔记本
|
||
|
||
```python runnable
|
||
h = wq.history("start", {"source": src, "by": {"kind": "person"}, "at": 1}, key=key)["history"]
|
||
program = "OPENQASM 3.0; qubit[2] q; ry(0.3) q[0]; h q[1];"
|
||
wq.Circuit(bell) # 引擎的线路图;点击一个门:.selected 就是它的操作
|
||
wq.Circuit(src, history=h) # 每个门都标出出自谁之手(wq.history)
|
||
wq.Result(job) # 以条形(或频率)显示的计数、方法、精度类别、回执的检查结果
|
||
wq.Receipt(job) # 签名者、摘要,以及引擎在这里计算出的 verified / INVALID 徽章
|
||
wq.Bloch(program, key=key) # 每个量子比特的 Bloch 矢量;拖动可旋转视角
|
||
```
|
||
|
||
每个小组件的前端都是一个小巧的普通 ES 模块(`python/wai_quantum/static/`)。若未安装 `widgets` 附加依赖,或前端没有小组件扩展,每个小组件都渲染为静态 HTML(`Circuit` 渲染为 SVG);`Job` 显示为其结果的卡片。每个小组件只显示引擎给出的内容,自己不计算任何东西:它的 `data` 就是引擎的回答。
|
||
|
||
`notebooks/` 中的文档笔记本在 CI 中运行,并须与其存储的输出一致:`getting-started`、`bell-receipt`(一个 Bell 对及其回执)、`equivalence`、`noisy-run`,以及 `service-job`(在为这次运行而启动的作业服务上执行的作业;没有这样的服务时,它的单元格会跳过)。
|
||
|
||
## 测试
|
||
|
||
`ci/check.sh` 就是完整的检查,与 CI 的运行方式相同(`.github/workflows/wai-quantum-py.yml`,在 `linux` 和 `macos` 上):它从这份检出构建命令行和作业服务,用 maturin 构建 wheel,在一个全新的 venv 中用固定版本并附哈希的测试依赖(`tests/requirements.lock`)安装该 wheel,运行 pytest 并要求每个测试都执行,针对本地作业服务运行各笔记本,并在 Python 3.9 上只用该 wheel 运行 `tests/smoke.py`。这些测试要求这个包与其他入口保持一致:在这里运行的作业与命令行和作业服务的作业相同(各主机的时间及其关于能耗的说明除外),在这里封存的回执能通过 `wai-quantum verify` 验证,命令行的回执也能在这里验证,两者用同一个用户密钥签名,而小组件的前端会在 node 下以这个包构建的数据运行。
|
||
|
||
能耗:在这里的运行不计量;其结果会注明这一点(`energy.unmetered`),与命令行和浏览器标签页中的运行一样。作业服务会为每个作业的 worker 计量。
|
||
|
||
许可证:Apache-2.0。
|