wai-quantum-service: every job's energy, signed with its result #331
Loading…
Reference in a new issue
No description provided.
Delete branch "wai/quantum-service-energy"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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, plusri_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_waitreaped the worker straight away, and its energy was lost.What it carries, in energy-measurement §2's names:
joules_micro;energy_provenance: "OnChipCounter";energy_uncertainty{relative_ppm, window_us}: the rounding to whole microjoules, meeting the §2.3 floorjoules_micro × relative_ppm ≥ 288 676at every size. The window is the worker's lifetime;energy_counter_filtering: "Unknown";coverage,covers,excludesandcpu_ms.What it does not claim:
statevector_singlejob runs on the GPU, which this counter does not read, so its figure ispartial.partialtoo, because such credits land late.{"unmetered": why}, never zero joules.run FILEin-process reports no energy.Tests (51 pass, clippy clean, both on the build host):
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:
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
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]>