wai-quantum-service: every job's energy, signed with its result #331

Merged
dcharlot merged 3 commits from wai/quantum-service-energy into main 2026-10-19 06:15:40 -04:00
Owner

Every finished job's result now carries energy: the CPU energy the job's worker process spent, inside the body the receipt seals.

How it is read. On macOS the service waits for the worker with waitid(WEXITED | WNOWAIT | WNOHANG), which does not reap it. It then reads the exited process's kernel count (proc_pid_rusage, ri_energy_nj, plus ri_billed_energy − ri_serviced_energy), and only then reaps it. An exited process has left every core, so its count is complete. Before this change, try_wait reaped the worker straight away, and its energy was lost.

What it carries, in energy-measurement §2's names:

  • joules_micro;
  • the class energy_provenance: "OnChipCounter";
  • energy_uncertainty {relative_ppm, window_us}: the rounding to whole microjoules, meeting the §2.3 floor joules_micro × relative_ppm ≥ 288 676 at every size. The window is the worker's lifetime;
  • energy_counter_filtering: "Unknown";
  • coverage, covers, excludes and cpu_ms.

What it does not claim:

  • A statevector_single job runs on the GPU, which this counter does not read, so its figure is partial.
  • A figure that includes billed work is partial too, because such credits land late.
  • A job the service cannot read (off macOS) is {"unmetered": why}, never zero joules.
  • run FILE in-process reports no energy.

Tests (51 pass, clippy clean, both on the build host):

  • the figure and the floor at every size;
  • no reading is never zero;
  • the partial cases;
  • the SDK struct layout;
  • a child that is read whole after it exits and is unreadable once reaped (macOS).

End to end: the release build ran on a spare port of the build host and ran the five benchmark jobs. Each carried a whole figure, and each receipt verified:

job CPU energy
density matrix, 12 qubits 32.1 s 96.46 J
matrix product state, 500 qubits 0.68 s 2.62 J
sparse Pauli dynamics, 127-qubit kicked Ising 0.09 s 0.25 J
GHZ state, 2,000 qubits 0.06 s 0.06 J
Pauli frames, 10,000 qubits 1.92 s 3.89 J

That is 1–3.9 J per CPU-second, within the range measured on these cores before.

Docs: the README gains an Energy section, the OpenAPI result description covers the field, and the MCP summary states the figure and its coverage. CHANGELOG entry added.

🤖 Generated with Claude Code

Every finished job's result now carries `energy`: the CPU energy the job's worker process spent, inside the body the receipt seals. **How it is read.** On macOS the service waits for the worker with `waitid(WEXITED | WNOWAIT | WNOHANG)`, which does not reap it. It then reads the exited process's kernel count (`proc_pid_rusage`, `ri_energy_nj`, plus `ri_billed_energy − ri_serviced_energy`), and only then reaps it. An exited process has left every core, so its count is complete. Before this change, `try_wait` reaped the worker straight away, and its energy was lost. **What it carries**, in energy-measurement §2's names: - `joules_micro`; - the class `energy_provenance: "OnChipCounter"`; - `energy_uncertainty` `{relative_ppm, window_us}`: the rounding to whole microjoules, meeting the §2.3 floor `joules_micro × relative_ppm ≥ 288 676` at every size. The window is the worker's lifetime; - `energy_counter_filtering: "Unknown"`; - `coverage`, `covers`, `excludes` and `cpu_ms`. **What it does not claim:** - A `statevector_single` job runs on the GPU, which this counter does not read, so its figure is `partial`. - A figure that includes billed work is `partial` too, because such credits land late. - A job the service cannot read (off macOS) is `{"unmetered": why}`, never zero joules. - `run FILE` in-process reports no energy. **Tests** (51 pass, clippy clean, both on the build host): - the figure and the floor at every size; - no reading is never zero; - the partial cases; - the SDK struct layout; - a child that is read whole after it exits and is unreadable once reaped (macOS). **End to end:** the release build ran on a spare port of the build host and ran the five benchmark jobs. Each carried a whole figure, and each receipt verified: | job | CPU | energy | |---|---|---| | density matrix, 12 qubits | 32.1 s | 96.46 J | | matrix product state, 500 qubits | 0.68 s | 2.62 J | | sparse Pauli dynamics, 127-qubit kicked Ising | 0.09 s | 0.25 J | | GHZ state, 2,000 qubits | 0.06 s | 0.06 J | | Pauli frames, 10,000 qubits | 1.92 s | 3.89 J | That is 1–3.9 J per CPU-second, within the range measured on these cores before. Docs: the README gains an Energy section, the OpenAPI result description covers the field, and the MCP summary states the figure and its coverage. CHANGELOG entry added. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
wai-quantum-service: every job's energy, signed with its result
Some checks failed
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
wai-quantum service / does this change touch it (pull_request) Has been cancelled
wai-quantum service / service · linux (pull_request) Has been cancelled
wai-quantum service / service · macos (pull_request) Has been cancelled
9fcab8163e
A finished worker is read before it is reaped: on macOS the service waits
with waitid(WNOWAIT), reads the exited process's kernel count
(proc_pid_rusage ri_energy_nj, plus energy system services billed to it),
then reaps it. An exited process has left every core, so the count is
complete.

The result carries the figure as `energy`, inside the body the receipt
seals, in energy-measurement §2's names: joules_micro, the class
OnChipCounter, the declared uncertainty (relative_ppm, window_us), which
covers the rounding to whole microjoules and meets the §2.3 floor at every
size, and the filtering state Unknown. It says what it covers and excludes.
A statevector_single job runs on the GPU, which the counter does not read,
so its figure is partial; a figure with billed work is partial too. A job
the service cannot read is {"unmetered": why}, never zero joules.

Tests: the figure and its floor at every size, no reading never zero, the
partial cases, the SDK layout, and a child read whole after it exits and
gone once reaped (macOS). End to end on the build host, the five Table 1
jobs each carried a whole figure (2-4 J per CPU-second) and their receipts
verified.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-quantum-service smoke: a job's energy is a sealed counter figure, or says why not
Some checks failed
WAI energy receipts / does this change touch it (pull_request) Successful in 4s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 6s
standards workspaces build + test / macOS energy backends (pull_request) Has been skipped
wai-quantum service / does this change touch it (pull_request) Successful in 5s
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 38s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m49s
wai-quantum service / service · macos (pull_request) Successful in 27s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 8m19s
wai-quantum service / service · linux (pull_request) Successful in 39s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Failing after 5m10s
3a9d6005c7
The ghz job's energy must be an OnChipCounter figure meeting the resolution
floor, or unmetered with a reason (SMOKE_EXPECT_ENERGY=1 requires the figure);
a changed figure must fail verification; and a GPU job's figure must be
partial, naming the GPU it does not read. All held against the branch's
release build on the build host.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge origin/main into wai/quantum-service-energy; CHANGELOG keeps every entry
All checks were successful
wai-quantum portable tensor program / does this change touch it (pull_request) Successful in 17s
wai-quantum portable tensor program / tensor program · CPU, mutants, GPU builds (pull_request) Has been skipped
wai-quantum portable tensor program / tensor program · GPUs (jetson-hub) (pull_request) Has been skipped
wai-quantum portable tensor program / tensor program · integrated GPU (framework-128gb) (pull_request) Has been skipped
wai-quantum portable tensor program / tensor program · Metal and the arm64 CPU (macos) (pull_request) Has been skipped
wai-quantum CPU vector units / does this change touch it (pull_request) Successful in 14s
wai-quantum CPU vector units / member · vector unit, rvv 1024-bit (riscv64, emulated) (pull_request) Has been skipped
wai-quantum CPU vector units / member · vector unit, sve 128-bit (aarch64, emulated) (pull_request) Has been skipped
wai-quantum CPU vector units / member · vector unit, rvv 128-bit (riscv64, emulated) (pull_request) Has been skipped
wai-quantum CPU vector units / member · vector unit, sve 2048-bit (aarch64, emulated) (pull_request) Has been skipped
wai-quantum CPU vector units / member · vector unit, avx2 (x86_64 silicon) (pull_request) Has been skipped
wai-quantum CPU vector units / member · vector unit, sve 512-bit (aarch64, emulated) (pull_request) Has been skipped
wai-quantum CPU vector units / member · vector units, avx2 and avx512 (framework-128gb silicon) (pull_request) Has been skipped
wai-quantum CPU vector units / member · vector unit absent (macos) (pull_request) Has been skipped
wai-quantum WebGPU member / does this change touch it (pull_request) Successful in 20s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Has been skipped
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Has been skipped
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Has been skipped
wai-quantum WebGPU member / member · discrete GPU, Vulkan (jetson-hub) (pull_request) Has been skipped
wai-quantum WebGPU member / member · integrated GPU, Vulkan (framework-128gb) (pull_request) Has been skipped
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Has been skipped
wai-web wasm32 / does this change touch it (pull_request) Successful in 24s
WAI mbt2018_mean integer decode (regenerated vectors) / does this change touch it (pull_request) Successful in 27s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been skipped
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Has been skipped
wai-quantum service / service · linux (pull_request) Successful in 1m11s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 7m19s
wai-quantum service / service · macos (pull_request) Successful in 36s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 8m32s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 7m49s
60e359413c
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!331
No description provided.