Module energy

Module energy 

Source
Expand description

2026-09-26: In-window GPU energy, the pure half: integrate the power readings that super::energy_sampler streams and turn a measured window into record keys.

Owner: bench hardware. Invariants:

  • No I/O: every function works on readings it is handed.
  • Every key this module writes carries gpu_rail in its name.
  • A window with no reading inside it, and a J/token ratio with no tokens or no joules, yield None: absent, never zero.

§Store joules and tokens, derive the ratios

Joules and tokens add across windows; a ratio does not. The record carries gpu_rail_energy_j and the window’s token count. It also carries one ratio, gpu_rail_joules_per_token, because a BENCH.toml ceiling can only bound a key the record carries (the per-rung J/token ceilings in kernels/gb10/qwen3.8-27b/BENCH.toml). Code that re-aggregates windows adds joules and tokens and divides once, with joules_per_token.

§Which rail

The reading is nvidia-smi’s power.draw.average, the GPU rail only. Measured 2026-09-20 on GB10, driver 580.126.09: power.limit, the module power readings and GPU memory power answer N/A, so the Grace cores and LPDDR5X are outside this number. gpu_rail in every key name keeps a reader from setting it beside a discrete card’s board power.

§Why not the driver’s energy counter

The telemetry crate reads the driver’s cumulative counter (nvmlDeviceGetTotalEnergyConsumption, crates/telemetry/src/device.rs). Switching this reader to it would change what every recorded gpu_rail_* key means under an unchanged name, while the BENCH.toml J/token ceilings bound values of this integral. Such a switch needs new key names and re-measured ceilings.

Structs§

EnergyWindow
2026-09-26: The energy integral over one measured window.
PowerSample
2026-09-26: One reading from the sampler.
SamplerCost
2026-09-26: What the sampler itself cost, written to the record as gpu_rail_sample* keys so the instrument’s overhead is visible.

Constants§

IDLE_BASELINE_SECS
2026-09-26: Length of the idle-baseline window that super::energy_sampler::EnergySampler::idle_baseline integrates.
JOULES_PER_TOKEN_KEY
2026-10-04: The J/token record key, after the c{C}_ rung prefix when there is one. A BENCH.toml bound on a key ending in it is an energy bound.
RAIL_NOTE
2026-09-26: Logged once per run when sampling starts (EnergyMeter::start).
SAMPLE_PERIOD_MS
2026-09-26: Sampler cadence (nvidia-smi -lms), written beside every run’s joules as gpu_rail_sample_period_ms.

Functions§

integrate
2026-09-26: Integrate the readings inside [start, end], both ends included.
joules_per_token
2026-09-26: GPU-rail joules per delivered output token, or None when the pair cannot support a ratio: no tokens, or a joule count that is not a finite positive number (a delivered token never costs zero energy, so 0 J means the window measured nothing). None rather than 0.0 or ∞ because a ceiling bounds this value, and any sentinel would read as a pass or as a real reading.
parse_line
2026-09-26: Parse one CSV row of --query-gpu=power.draw.average,clocks_event_reasons.sw_power_cap,clocks_event_reasons.hw_power_brake_slowdown with --format=csv,noheader,nounits, e.g. 4.76, Not Active, Active.