Skip to content

Fix: Prevent intermittent zero energy reporting for tasks #853

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 22, 2025

Conversation

benoit-cty
Copy link
Contributor

Problem:
EmissionsTracker.stop_task() would occasionally report zero energy consumed for a task, even when the task performed work and underlying hardware measurements indicated energy consumption.

Cause:
The issue stemmed from the self._previous_emissions instance variable, which is used to calculate energy deltas. This variable was being updated by a 'live API update' mechanism that could trigger during the manual call to _measure_power_and_energy() within stop_task(). If this live update occurred, self._previous_emissions would be set to the current total energy values including the task's consumption. Subsequently, when stop_task() attempted to calculate the task's specific delta, it would compare these updated totals against the (now also updated) self._previous_emissions, effectively calculating a delta between two identical states, resulting in zero.

Solution:

  1. Introduced a new instance variable self._active_task_emissions_at_start in BaseEmissionsTracker.
  2. In start_task(), a snapshot (deep copy) of the EmissionsData (representing total accumulated energy up to that point) is taken using self._prepare_emissions_data() and stored in self._active_task_emissions_at_start.
  3. In stop_task(): a. The energy delta for the completed task is now calculated by comparing the current total emissions (after the task's work) against the preserved self._active_task_emissions_at_start snapshot. This ensures the delta is specific to the task's duration and consumption. b. After the task-specific delta is determined, the global self._previous_emissions state is updated by calling self._compute_emissions_delta() with the current total emissions. This maintains the correct state for ongoing non-task-specific measurements or live API updates. c. self._active_task_emissions_at_start is cleared when the task stops.

This change isolates the delta calculation for tasks from the global update mechanism for _previous_emissions, ensuring accurate energy reporting for individual tasks.

Copy link
Collaborator

@inimaz inimaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @benoit-cty !

google-labs-jules bot and others added 6 commits June 22, 2025 10:26
Problem:
EmissionsTracker.stop_task() would occasionally report zero energy
consumed for a task, even when the task performed work and underlying
hardware measurements indicated energy consumption.

Cause:
The issue stemmed from the `self._previous_emissions` instance variable,
which is used to calculate energy deltas. This variable was being
updated by a 'live API update' mechanism that could trigger during
the manual call to `_measure_power_and_energy()` within `stop_task()`.
If this live update occurred, `self._previous_emissions` would be set
to the current total energy values *including* the task's consumption.
Subsequently, when `stop_task()` attempted to calculate the task's
specific delta, it would compare these updated totals against the (now also
updated) `self._previous_emissions`, effectively calculating a delta
between two identical states, resulting in zero.

Solution:
1. Introduced a new instance variable `self._active_task_emissions_at_start`
   in `BaseEmissionsTracker`.
2. In `start_task()`, a snapshot (deep copy) of the `EmissionsData`
   (representing total accumulated energy up to that point) is taken using
   `self._prepare_emissions_data()` and stored in
   `self._active_task_emissions_at_start`.
3. In `stop_task()`:
    a. The energy delta for the completed task is now calculated by
       comparing the current total emissions (after the task's work)
       against the preserved `self._active_task_emissions_at_start`
       snapshot. This ensures the delta is specific to the task's duration
       and consumption.
    b. After the task-specific delta is determined, the global
       `self._previous_emissions` state is updated by calling
       `self._compute_emissions_delta()` with the current total emissions.
       This maintains the correct state for ongoing non-task-specific
       measurements or live API updates.
    c. `self._active_task_emissions_at_start` is cleared when the task
       stops.

This change isolates the delta calculation for tasks from the global
update mechanism for `_previous_emissions`, ensuring accurate energy
reporting for individual tasks.
This commit adds a new unit test, `test_task_energy_with_live_update_interference`,
to `tests/test_emissions_tracker.py`.

The test is designed to:
- Verify that `EmissionsTracker.stop_task()` correctly calculates task-specific
  energy consumption.
- Specifically, it ensures accuracy even when an internal 'live API update'
  (triggered by `api_call_interval` being met during the `_measure_power_and_energy`
  call within `stop_task()`) occurs. This was the scenario that previously
  caused `_previous_emissions` to be updated prematurely, leading to
  intermittent zero-energy reporting for tasks.

The test mocks hardware energy measurements (CPU and RAM) to return
controlled, non-zero values and sets `api_call_interval=1` to reliably
trigger the problematic condition. It then asserts that the `EmissionsData`
returned by `stop_task()` reflects the correct, non-zero energy consumed
during the task.

This unit test complements the fix that ensures `_active_task_emissions_at_start`
is used for task-specific delta calculations, safeguarding against regressions.
@benoit-cty benoit-cty force-pushed the fix/intermittent-zero-task-energy branch from a914c77 to c18ff0f Compare June 22, 2025 08:26
@benoit-cty benoit-cty merged commit eca114e into master Jun 22, 2025
8 checks passed
@benoit-cty benoit-cty deleted the fix/intermittent-zero-task-energy branch June 22, 2025 08:41
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.

Emissions & energy consumed is zero when tracking tasks
2 participants