Skip to content

fix: skip uncorrectable RAPL counter wraps - #1321

Open
davidberenstein1957 wants to merge 2 commits into
masterfrom
fix/rapl-wraparound-negative-energy
Open

fix: skip uncorrectable RAPL counter wraps#1321
davidberenstein1957 wants to merge 2 commits into
masterfrom
fix/rapl-wraparound-negative-energy

Conversation

@davidberenstein1957

Copy link
Copy Markdown
Collaborator

Closes #1309

What changed

RAPLFile.delta() now re-checks the wrap correction: if the corrected reading is still below the previous one, the sample is dropped (zero energy delta, zero power) with a warning, instead of emitting a negative energy delta.

Why

max_energy_range_uj is set to 0 whenever it cannot be read (codecarbon/core/rapl.py:45). The comment claims wrap detection is then disabled, but only the correction was disabled — the wrap branch still ran and produced energy_delta = energy - last_energy, a large negative value (up to -1.19e-3 kWh for a 2^32 uJ package domain). That flows unchecked into _total_energy / _total_cpu_energy, and the abs() in Power.from_energies_and_delay masks it in the power column.

The same guard also covers the other sources of a backwards counter: driver resets, suspend/resume, and the _get_value() transient-error fallback that returns 0. It mirrors what codecarbon/core/windows_emi.py:566-574 already does for EMI.

Dropping a sample loses at most one interval of genuine energy — strictly better than subtracting an hour's worth. Systems where max_energy_range_uj is readable are unaffected.

Verification

tests/test_rapl_permissions.py:

  • test_rapl_wraparound_without_max_skips_sample — fails on master (energy_delta.kWh is about -1.11e-3), passes here.
  • test_rapl_wraparound_with_max_is_corrected — pins the existing wrap correction against regression.

uv run pytest tests/test_rapl_permissions.py -q → 2 passed, 2 skipped (the pre-existing Linux-only cases). black --check clean; ruff reports only pre-existing findings in the touched files.

Merge order

This should land before the rapl_include_dram change: DRAM domains have smaller max ranges and wrap far more often, which makes this defect fire much more frequently.

🤖 Generated with Claude Code

When max_energy_range_uj is unreadable, max_energy_reading is 0, so the
wrap-around branch still ran but corrected nothing, emitting a large
negative energy delta straight into the CPU and total energy. Drop the
sample instead, matching the EMI backend's behaviour. The same guard
also covers driver resets and the transient read-error fallback.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.61%. Comparing base (065d0e6) to head (8c607c8).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1321      +/-   ##
==========================================
+ Coverage   91.39%   91.61%   +0.22%     
==========================================
  Files          49       49              
  Lines        5056     5071      +15     
==========================================
+ Hits         4621     4646      +25     
+ Misses        435      425      -10     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

A failed read returned Energy(0), which looked like a wrap-around and,
with a readable max_energy_range_uj, injected a spurious positive delta
of up to one counter range. _get_value now returns None and the sample
is skipped and re-baselined. The uncorrectable-wrap warning is emitted
once per file instead of every measurement cycle.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@davidberenstein1957
davidberenstein1957 marked this pull request as ready for review August 12, 2026 19:14
@davidberenstein1957
davidberenstein1957 requested a review from a team as a code owner August 12, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RAPL counter wrap yields negative energy when max_energy_range_uj is unreadable

1 participant