The energy field is contested, not empty. The prescriptive half is a decade old and ratified — ISO/IEC 23001-11 carries decoding-operation-reduction metadata whose purpose is to make a decoder do less work, and a companion carriage part now moves it. WAI's half is the measured one. Neither half currently scores against the other, and that gap is where a joule figure stops meaning anything. DEGRADATION-BLINDNESS (§7.1). A receipt that records joules spent, and nothing about how much work the decode was asked to do, rewards the wrong behaviour: a sink can always spend fewer joules by decoding worse. energy-measurement.md §5's recomputable-work-unit rule blocks the substitution at the byte-exact tier, but not at `entropy-consistency`, and not for the conventional codecs WAI already carries. So the receipt has to carry the operating point, not only the cost. REQUEST / COMMITMENT / DELIVERY (§7.2). Three distinct fields, because the interesting cases are exactly the ones where they differ. A receipt MUST NOT carry `op_delivered` alone — that is the degradation-blind case. `op_committed` MUST be what the receiver stated even where it differs from the request, since a commitment that silently becomes the request is not a commitment. And a sink that honoured a reduction request MUST NOT claim `decode-equivalence`, per the tier rule. This converts a recorded number into a number measured against a promise. The prescriptive standards say what should be spent; the measurement standards say what was; nobody scores the second against the first. THE RESIDUAL (§7.3). Where a complexity descriptor and a measured binding cover the same reconstruction, the receipt MUST carry the signed difference between predicted and measured energy — over the same work unit, never without the acquisition class of the measured term, and never suppressed for being large. The large ones are the informative ones, and suppressing them turns a falsifiable claim into an unfalsifiable one. A complexity descriptor is a prediction about energy, and until something records what actually happened against it, the prediction can never be wrong. §7.3 closes that loop inside the artifact rather than in a report. COMPANION CAPABILITY (§7.4). Green-metadata semantics register the way wai.meta.hdr10plus and wai.meta.dovi do — name the descriptor class, sink supplies the decoder, no carriage adopted. ISOBMFF/DASH carriage is somebody else's layer. NETWORK-LAYER ALIGNMENT (energy-measurement §2.1). WAI's HwShunt/ModelBased/ Estimator is a private vocabulary, and coarser than the graded accuracy hierarchy an adopted IETF GREEN draft defines for device energy. An implementation reporting under both SHOULD derive rather than assign independently, MUST say which identity it derived from, MUST NOT let a derivation improve the class, and MUST declare the tolerance the class implies — a class without a tolerance is a label. WAI does not adopt that model; the scopes differ (device vs per-object) and conflating them would breach §4. What is required is that two vocabularies for one property do not contradict each other. Ingest queue item 3 and item 8 from the landscape survey (#80 §5.3 a–e). Co-Authored-By: Claude Opus 5 <[email protected]>
12 KiB
WAI Extension: Energy Measurement
Status: Draft. Specifies how a joule figure is acquired, so that the
joules_microfield the receipt profiles already carry means the same thing in two independent implementations. No new wire format; an acquisition protocol, a reporting contract, and a quality rule over the existing receipt fields. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.
1. Why an acquisition protocol
jwp-receipts.md defines joules_micro as "microjoules
consumed producing this object". That fixes the unit and the scope of
attribution. It does not fix how a number gets into the field, and without that
the field is a number-shaped hole: one implementation can write a counter
reading, another an arithmetic model, a third a constant, and every one of them
is conformant. The figures are then incomparable, and — worse — indistinguishable,
because nothing in the receipt says which kind it is.
This extension closes that. It requires two things of any receipt carrying energy: that the figure declare how it was acquired, and that the measurement declare whether it was good enough to publish.
The contribution is not the number. It is the number plus its acquisition class, and the discipline of withholding both when the measurement fails.
2. The acquisition class (REQUIRED)
A receipt carrying a non-zero energy figure MUST carry an acquisition class alongside it, from the shared vocabulary:
| class | meaning | requires |
|---|---|---|
HwShunt |
Read from a hardware energy interface — RAPL, NVML, SMC, IOReport, or an external shunt. | a present, non-zero measurement |
ModelBased |
Computed from a calibrated per-operation model (e.g. wall time × a power constant). A real number, honestly labelled as derived. | — |
Estimator |
A coarse constant or load estimator. | — |
These are the same three names the receipt families elsewhere in the ecosystem already use; this extension deliberately reuses the vocabulary rather than minting a parallel one for media.
A counter reading is not an estimate. RAPL, NVML and IOReport are sensor
values, and HwShunt says so. What separates it from the rungs below is
provenance and scope, not accuracy — see §5.
Normative:
- An implementation MUST NOT emit a non-zero energy figure without a class. An unlabelled number cannot be compared to any other number.
- An implementation MUST NOT emit a class with a zero or absent figure. That claims a measurement which did not occur.
- The class MUST be inside the signature, so an intermediary cannot promote
a
ModelBasedfigure toHwShuntin transit. - A verifier MUST treat a receipt violating either coupling as invalid, not merely as unlabelled.
The reference implementation enforces both couplings in verify() rather than
documenting them, and returns no rate at all — never 0 — when unmetered,
because a zero reads as "this work was free", which is a stronger and false
claim than "nobody measured".
2.1 Relationship to network-layer energy identities
The three classes above are WAI's own vocabulary, and they are coarser than the
graded data-source-accuracy identity hierarchy an adopted IETF GREEN
working-group draft defines for device and sub-component energy. That hierarchy
is the network layer's answer to the same question this section asks: how was
this number obtained?
- An implementation that also reports under a network-layer energy model SHOULD derive its acquisition class from that model's identity rather than assigning one independently, and MUST state which identity it derived from. Two vocabularies for one property, assigned separately, will disagree.
- A derivation MUST NOT improve the class. Where a network-layer identity maps ambiguously, the weaker WAI class applies.
- An implementation MUST declare the tolerance its acquisition class implies. A class without a tolerance is a label; the point of grading provenance is to say how much the figure can be leaned on, and that requires a number.
WAI does not adopt the network-layer model, and this section does not restate it. The scopes differ — that model is device- and sub-component-scoped, WAI's figures are per-object — and conflating them would breach §4's attribution rules. What is required is that the two do not contradict each other about the same measurement.
3. The reference protocol: bracketed marginal measurement
On-die energy counters report the draw of a whole package or SoC, not of one process. A decode cannot be isolated on such an interface, so the reference protocol measures the marginal draw the work adds to an otherwise-idle machine:
- Idle bracket. Sample power for a fixed count with no work running. Record the mean and the standard deviation.
- Saturating burst. Run the reconstruction continuously on N threads, counting completions. Many threads are used deliberately: a single-threaded burst on a modern SoC often fails to lift total draw clear of idle drift.
- Busy bracket. Sample power again for a fixed count while the burst runs, recording the wall-clock window it spans.
- Attribute.
energy = max(0, mean_busy − mean_idle) × window, then divide by the number of completions in that window.
Per-unit energy is total marginal energy ÷ total completions, so the thread count does not enter the result. Completions MUST be counted per reconstruction, not per fixed-size batch: a cheap payload runs millions of times and an expensive one a handful, and a coarse batch collapses the count.
An implementation MUST report the idle mean, the busy mean, the sample counts, the window, and the completion count alongside any figure it publishes. Those five numbers are what make a figure auditable; the figure alone is not.
4. Attribution quality (REQUIRED)
The marginal method is only meaningful when the burst lifts power clearly above the machine's own idle fluctuation. When it does not, the method does not degrade gracefully — it returns a confidently-formatted number that is far too low, because an inflated idle baseline is subtracted from a busy mean that never rose.
This is not a theoretical concern. Measuring one fixed clip with one binary, minutes apart on the same machine:
| condition | idle | busy | marginal | reported |
|---|---|---|---|---|
| quiet | 20.45 W | 54.89 W | 34.45 W | 10,565 µJ/decode |
| (the quiet row predates this rule, so its ratio was not recorded) | ||||
| build running | ~23.9 W | 24.26 W | 0.36 W | 497 µJ/decode |
A 21× error, in the flattering direction, with nothing in the output to distinguish the two.
So an implementation MUST compute the ratio of the marginal draw to the idle standard deviation and report it:
| ratio | verdict |
|---|---|
| ≥ 10 | clean — publishable |
| ≥ 3 | usable for relative comparison — not publishable |
| ≥ 1 | noisy — do not publish |
| < 1 | unusable — the machine was not idle |
The publication bar is 10, not 3, and that is an empirical result rather than a round number. A later reading of the same clip at a ratio of 3.8 — inside what an earlier draft of this rule called "usable" — reported 2,469 µJ against the 10,565 µJ above: a 4.3× disagreement from a reading the rule had passed. A ratio in the 3–10 band is sound for comparing two workloads measured back-to-back on one machine, because the bias applies to both. It is not sound for an absolute figure.
The bias has a direction. A busy machine inflates the idle baseline, which is then subtracted from a busy mean that never rose as far, so a poor bracket always reads low. An implementation reporting energy therefore errs toward flattering itself, which is precisely why the check must be automatic rather than left to the operator's judgement.
- An implementation MUST NOT seal a
HwShuntfigure when the ratio is below 1, or when the per-unit figure rounds to zero. Neither is a measurement of low energy; both are a failure to measure, and the receipt MUST be emitted unmetered instead. - An implementation MUST NOT publish an absolute figure taken below a ratio of 10, and SHOULD warn whenever it produces one.
Emitting an unmetered receipt is the correct outcome of a failed measurement, not an error state. A tool that says "I did not measure this" is more useful than one that says "this decode cost 267 µJ" when the true figure is forty times higher.
5. What the figure is, and is not
- It is machine-specific. The same codestream on different silicon legitimately measures differently. Energy is a property of an execution, not of an artifact.
- It is a marginal figure over an idle baseline, so it excludes the fixed cost of having a machine powered on, and attributes shared platform overhead to the work only insofar as the work raised it.
- It is scoped to what the interface reports — a package or an SoC, not a process. Provenance and scope are the honest limitations, not sensor accuracy.
- It depends on the build. A debug build of the reference decoder measured 4.9× a release build of the same code. An implementation MUST state the build profile alongside any published figure.
- It is not verifiable by re-execution. A third party re-running the decode reproduces the result and the work, never the joules.
That last point is the reason the receipt profiles are shaped as they are. Where a class's reconstruction is byte-exact and proven across architectures, every field except the energy is independently checkable, and the energy is the single attested variable. Pairing a meter with a reproducible outcome is what turns an energy receipt from a claim into a measurement with one unverifiable term — so an implementation SHOULD report energy against a work unit that a verifier can recompute from the artifact, and MUST NOT report it against a work unit only the producer can compute.
6. Reporting contract
A published figure MUST be accompanied by: the acquisition class (§2); the idle mean and standard deviation, busy mean, sample counts, window and completion count (§3); the attribution-quality ratio (§4); the build profile (§5); and the recomputable work unit the rate is expressed against.
A figure published without these is not wrong so much as unusable: nothing about it can be checked, reproduced, or compared.
7. Worked example
wai.video.int_motion, real-footage vector, 8 frames of 96×96 RGB, release
build, IOReport via a non-privileged reader:
work : 221,184 subpixel-ops (8 x 96 x 96 x 3, recomputable)
cpu power idle : 24.95 W (sd 0.23 W, 10 samples)
cpu power busy : 25.84 W (14 samples)
marginal (busy-idle): 0.89 W
decodes : 1,525 over 4.23 s
marginal / idle sd : 3.8x (usable for relative comparison — NOT publishable)
-> per decode : 2,468.8 uJ
-> per kilo-subpixel : 11.16 uJ
acquisition class : HwShunt
This example is deliberately a failing one. It is a complete, honestly reported bracket that this extension nonetheless forbids publishing as an absolute figure, because 3.8 is below the bar of §4 — and the earlier reading of the same clip on a quieter machine differed by 4.3×. It is shown rather than a clean bracket because a clean bracket is not currently reproducible on the authoring machine, and substituting an invented one would be the exact failure this document exists to prevent. An implementation quoting a figure for this vector MUST first obtain a bracket at ≥ 10.
The receipt seals the codestream hash, the per-frame decoded-pixel hashes, the work figure, the energy and its class under one signature. A verifier re-derives everything but the energy from the codestream alone.
8. Reproducing a figure
An implementation claiming conformance SHOULD publish, with any figure: the vector decoded, the build profile and toolchain, the reader used for the power interface, and the five bracket parameters of §3. A figure whose bracket is not published cannot be reproduced, and an unreproducible energy number is an assertion, not a measurement — which is the failure this extension exists to prevent.