From 7bab6a39d9ec4f868915fccc93ece3afce6303b3 Mon Sep 17 00:00:00 2001 From: williamacostalora <157067981+williamacostalora@users.noreply.github.com> Date: Sun, 14 Jun 2026 23:03:53 -0500 Subject: [PATCH 1/2] feat: add Apple M2/M3/M4 chip TDP values to cpu_power.csv Fixes #758 - Apple Silicon chips from M2 onwards were not recognized by CodeCarbon's TDP lookup table, causing users to fall back to a constant default power estimate instead of a real measurement. Added TDP entries for: - Apple M2, M2 Pro, M2 Max, M2 Ultra - Apple M3, M3 Pro, M3 Max, M3 Ultra - Apple M4, M4 Pro, M4 Max, M4 Ultra Added unit tests to verify correct TDP lookup for all new chip variants. --- codecarbon/data/hardware/cpu_power.csv | 12 +++++++++ tests/test_cpu.py | 36 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/codecarbon/data/hardware/cpu_power.csv b/codecarbon/data/hardware/cpu_power.csv index 64b15d066..a6d16aaa0 100644 --- a/codecarbon/data/hardware/cpu_power.csv +++ b/codecarbon/data/hardware/cpu_power.csv @@ -4902,3 +4902,15 @@ TL-60,31 TL-64,35 X1150,17 X940,45 +Apple M2,15 +Apple M2 Pro,20 +Apple M2 Max,30 +Apple M2 Ultra,60 +Apple M3,15 +Apple M3 Pro,18 +Apple M3 Max,30 +Apple M3 Ultra,60 +Apple M4,15 +Apple M4 Pro,20 +Apple M4 Max,35 +Apple M4 Ultra,70 diff --git a/tests/test_cpu.py b/tests/test_cpu.py index b9acb5b59..629d29cd0 100644 --- a/tests/test_cpu.py +++ b/tests/test_cpu.py @@ -577,6 +577,42 @@ def test_main_returns_unknown_when_cpu_detection_fails(self): self.assertEqual(tdp.model, "Unknown") self.assertIsNone(tdp.tdp) + def test_apple_m2_chips_have_correct_tdp(self): + for chip, expected_tdp in [ + ("Apple M2", 15), + ("Apple M2 Pro", 20), + ("Apple M2 Max", 30), + ("Apple M2 Ultra", 60), + ]: + with mock.patch("codecarbon.core.cpu.detect_cpu_model", return_value=chip): + tdp = TDP() + self.assertEqual(tdp.model, chip) + self.assertEqual(tdp.tdp, expected_tdp) + + def test_apple_m3_chips_have_correct_tdp(self): + for chip, expected_tdp in [ + ("Apple M3", 15), + ("Apple M3 Pro", 18), + ("Apple M3 Max", 30), + ("Apple M3 Ultra", 60), + ]: + with mock.patch("codecarbon.core.cpu.detect_cpu_model", return_value=chip): + tdp = TDP() + self.assertEqual(tdp.model, chip) + self.assertEqual(tdp.tdp, expected_tdp) + + def test_apple_m4_chips_have_correct_tdp(self): + for chip, expected_tdp in [ + ("Apple M4", 15), + ("Apple M4 Pro", 20), + ("Apple M4 Max", 35), + ("Apple M4 Ultra", 70), + ]: + with mock.patch("codecarbon.core.cpu.detect_cpu_model", return_value=chip): + tdp = TDP() + self.assertEqual(tdp.model, chip) + self.assertEqual(tdp.tdp, expected_tdp) + class TestResourceTrackerCPUTracking(unittest.TestCase): def test_set_cpu_tracking_skips_tdp_when_rapl_available(self): From 8a3e3889014f5bedbd5e61f5a3b79b2eca21022e Mon Sep 17 00:00:00 2001 From: williamacostalora <157067981+williamacostalora@users.noreply.github.com> Date: Sun, 21 Jun 2026 22:41:55 -0500 Subject: [PATCH 2/2] test: verify unknown Apple Silicon chips fall back gracefully Adds a regression test confirming that chip variants not yet in cpu_power.csv (e.g. a future Apple M5) still resolve to the existing default per-thread power estimate instead of raising an error. --- tests/test_cpu.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_cpu.py b/tests/test_cpu.py index 629d29cd0..53e653008 100644 --- a/tests/test_cpu.py +++ b/tests/test_cpu.py @@ -613,6 +613,20 @@ def test_apple_m4_chips_have_correct_tdp(self): self.assertEqual(tdp.model, chip) self.assertEqual(tdp.tdp, expected_tdp) + def test_unknown_apple_chip_falls_back_gracefully(self): + with ( + mock.patch( + "codecarbon.core.cpu.detect_cpu_model", + return_value="Apple M5 Pro", + ), + mock.patch("codecarbon.core.cpu.is_psutil_available", return_value=True), + mock.patch("codecarbon.core.cpu.count_cpus", return_value=10), + ): + tdp = TDP() + + self.assertEqual(tdp.model, "Apple M5 Pro") + self.assertEqual(tdp.tdp, 10 * DEFAULT_POWER_PER_CORE) + class TestResourceTrackerCPUTracking(unittest.TestCase): def test_set_cpu_tracking_skips_tdp_when_rapl_available(self):