Empty powermetrics output yields NaN power, poisoning all downstream totals on Apple Silicon
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.9k
- Forks
- 323
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 12
Description
When powermetrics produces no matching output, ApplePowermetrics.get_details() returns nan for CPU/GPU power. NaN is absorbing under addition, so a single such sample turns _total_energy, emissions and emissions_rate into nan for the remainder of the run. The CSV row and the API payload then contain NaN, which also makes the JSON invalid under the strict spec.
Reproduction
from codecarbon.core.powermetrics import ApplePowermetrics
pm = ApplePowermetrics(output_dir=tmpdir, log_file_name="empty.txt")
open(pm._log_file_path, "w").close() # sudoers rule missing, or sampler emitted nothing
d = pm.get_details()
assert math.isnan(d["CPU Power"]) # passes today
Root cause
codecarbon/core/powermetrics.py:181 and :193 call np.mean([...]) on the result of re.findall. np.mean([]) returns nan and only emits a RuntimeWarning; it does not raise, so the except Exception at codecarbon/core/powermetrics.py:201 never fires and nothing is logged.
The value flows straight through AppleSiliconChip._get_power (codecarbon/external/hardware.py:504-515) into Power.from_watts, then through BaseHardware.measure_power_and_energy into the tracker accumulators.
The GPU branch is the likelier trigger: _log_values runs powermetrics with --samplers cpu_power only (codecarbon/core/powermetrics.py:145-153), and whether that sampler emits GPU Power: lines depends on the machine and macOS version. Where it does not, gpu_power_list is empty on every call.
Expected vs actual
Expected: no samples means 0 W with a visible warning, and the run still reports finite emissions.
Actual: no samples means nan, silently, and every total for the rest of the run is nan.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in codecarbon/core/powermetrics.py at ApplePowermetrics.get_details(), especially the parsing around lines 181 and 193, and trace the values into AppleSiliconChip._get_power in codecarbon/external/hardware.py. Reproduce the empty-log case, then verify that missing CPU or GPU samples produce finite zero power, a visible warning, and finite downstream emissions and JSON payloads.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, numpy, python
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100