[package] name = "jouleclaw-energy" version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true repository.workspace = true description = "Honest energy telemetry for JouleClaw. EnergyCounter trait + Provenance tag (HwShunt | ModelBased | Estimator) plus concrete platform backends (RAPL, NVML, Apple Silicon estimator) and a thread-safe ledger. The thermodynamic circuit breaker is only as honest as the worst counter in the request's span." [dependencies] jouleclaw-core = { path = "../jouleclaw-core" } thiserror.workspace = true serde = { workspace = true, optional = true } serde_json = { workspace = true, optional = true } tracing = { workspace = true, optional = true } nvml-wrapper = { workspace = true, optional = true } # `libc`: the IOReport backend's CoreFoundation types and thread clock on macOS, # the SMC backend's Mach types, and the liveness probe's thread CPU clock on # every Unix (RAPL on Linux). [target.'cfg(unix)'.dependencies] libc = "0.2" [features] default = ["serde"] serde = ["dep:serde", "dep:serde_json"] # Per-platform energy backends. Off by default so the foundation is OS-neutral; # downstream crates / binaries enable what their target supports. rapl = [] # Intel/AMD x86 — Linux sysfs powercap, or the energy-status MSRs where powercap lists no package (HwShunt while live) nvml = ["dep:nvml-wrapper", "dep:tracing"] # NVIDIA discrete — NVML cumulative-energy counter (HwShunt while live), power-draw integral (ModelBased) otherwise ioreport = [] # Apple Silicon M-series — real IOReport energy counter (HwShunt while every CPU rail is live), load-avg estimator fallback; and the per-process GPU counter (GPU rail × this process's GPU-time share) ina3221 = [] # NVIDIA Jetson (Orin / Thor) — sysfs i2c shunt reader hwmon = [] # Linux generic — for AMD Strix Halo / Ryzen AI Max iGPU + others smc = [] # Mac — the SMC's whole-machine power (`PSTR`) integrated over time (ModelBased, domain System); a sampler thread per process # The per-process GPU counter's hardware test loads the GPU itself (this crate # holds no Metal; its consumers supply the load). Same Metal bindings as # `jouleclaw-backend-apple`. [target.'cfg(target_os = "macos")'.dev-dependencies] objc2 = "0.6" objc2-foundation = "0.3" objc2-metal = "0.3"