1- import time
21import math
32import os
4- from codecarbon .emissions_tracker import EmissionsTracker # Assuming codecarbon is installable or in PYTHONPATH
3+ import time
4+
5+ from codecarbon .emissions_tracker import (
6+ EmissionsTracker , # Assuming codecarbon is installable or in PYTHONPATH
7+ )
58from codecarbon .external .logger import logger , set_logger_level
69
710# Set a verifiable experiment name for tracking if needed (optional)
811os .environ ["CODECARBON_EXPERIMENT_ID" ] = "task-energy-test"
912
13+
1014def cpu_intensive_task (duration_seconds ):
1115 """A simple CPU-intensive task."""
1216 start_time = time .time ()
1317 while (time .time () - start_time ) < duration_seconds :
1418 _ = math .sqrt (time .time ()) * math .factorial (100 )
1519
20+
1621def main ():
17- set_logger_level ("ERROR" ) # Keep CodeCarbon's own logs quiet unless error
22+ set_logger_level ("ERROR" ) # Keep CodeCarbon's own logs quiet unless error
1823
1924 logger .info ("Starting task energy consumption test script." )
2025
@@ -25,7 +30,7 @@ def main():
2530 tracker = EmissionsTracker (
2631 project_name = "TaskEnergyTest" ,
2732 measure_power_secs = 1 ,
28- api_call_interval = 2 , # This is the key to potentially trigger the old bug
33+ api_call_interval = 2 , # This is the key to potentially trigger the old bug
2934 save_to_file = False , # Don't write to emissions.csv for this test
3035 # log_level="DEBUG" # Use "DEBUG" if you want to see CodeCarbon's internal debug logs
3136 )
@@ -37,51 +42,67 @@ def main():
3742 failing_rounds = []
3843 test_passed = True
3944
40- NUM_ROUNDS = 30 # Number of tasks to run
41- TASK_DURATION_SEC = 4 # Duration of each CPU task
42-
43- logger .info (f"Tracker initialized. Running { NUM_ROUNDS } rounds of { TASK_DURATION_SEC } s tasks." )
44- print (f"Tracker initialized. Running { NUM_ROUNDS } rounds of { TASK_DURATION_SEC } s tasks." )
45+ NUM_ROUNDS = 30 # Number of tasks to run
46+ TASK_DURATION_SEC = 4 # Duration of each CPU task
4547
48+ logger .info (
49+ f"Tracker initialized. Running { NUM_ROUNDS } rounds of { TASK_DURATION_SEC } s tasks."
50+ )
51+ print (
52+ f"Tracker initialized. Running { NUM_ROUNDS } rounds of { TASK_DURATION_SEC } s tasks."
53+ )
4654
4755 for i in range (NUM_ROUNDS ):
48- print (f"Starting round { i + 1 } /{ NUM_ROUNDS } " )
56+ print (f"Starting round { i + 1 } /{ NUM_ROUNDS } " )
4957 try :
50- tracker .start_task (f"CPU_Task_Round_{ i + 1 } " )
58+ tracker .start_task (f"CPU_Task_Round_{ i + 1 } " )
5159 cpu_intensive_task (TASK_DURATION_SEC )
5260 emissions_data = tracker .stop_task ()
5361
5462 if emissions_data :
55- task_name = emissions_data .run_id # Using run_id as a stand-in for task_name if not directly available
63+ task_name = (
64+ emissions_data .run_id
65+ ) # Using run_id as a stand-in for task_name if not directly available
5666 # In a real scenario, task_name might be part of emissions_data or retrieved via the task_id
57- print (f"Round { i + 1 } : Task '{ task_name } ' (task_idx_{ i + 1 } ) completed. Duration: { emissions_data .duration :.4f} s, Energy: { emissions_data .energy_consumed :.6f} kWh, Emissions: { emissions_data .emissions :.6f} kg" )
67+ print (
68+ f"Round { i + 1 } : Task '{ task_name } ' (task_idx_{ i + 1 } ) completed. Duration: { emissions_data .duration :.4f} s, Energy: { emissions_data .energy_consumed :.6f} kWh, Emissions: { emissions_data .emissions :.6f} kg"
69+ )
5870
5971 # Check for the bug: zero energy for a non-trivial task duration
60- if emissions_data .duration > 0.1 and emissions_data .energy_consumed == 0.0 :
61- failing_rounds .append ({
62- "round" : i + 1 ,
63- "task_name" : task_name ,
64- "duration" : emissions_data .duration ,
65- "energy_consumed" : emissions_data .energy_consumed ,
66- "error" : "Zero energy for non-trivial duration"
67- })
72+ if (
73+ emissions_data .duration > 0.1
74+ and emissions_data .energy_consumed == 0.0
75+ ):
76+ failing_rounds .append (
77+ {
78+ "round" : i + 1 ,
79+ "task_name" : task_name ,
80+ "duration" : emissions_data .duration ,
81+ "energy_consumed" : emissions_data .energy_consumed ,
82+ "error" : "Zero energy for non-trivial duration" ,
83+ }
84+ )
6885 test_passed = False
6986 else :
70- print (f"Round { i + 1 } : stop_task() did not return emissions_data." )
71- failing_rounds .append ({
72- "round" : i + 1 ,
73- "task_name" : f"CPU_Task_Round_{ i + 1 } _NoData" ,
74- "error" : "stop_task returned None"
75- })
87+ print (f"Round { i + 1 } : stop_task() did not return emissions_data." )
88+ failing_rounds .append (
89+ {
90+ "round" : i + 1 ,
91+ "task_name" : f"CPU_Task_Round_{ i + 1 } _NoData" ,
92+ "error" : "stop_task returned None" ,
93+ }
94+ )
7695 test_passed = False
7796
7897 except Exception as e :
79- print (f"Round { i + 1 } : An error occurred: { e } " )
80- failing_rounds .append ({
81- "round" : i + 1 ,
82- "task_name" : f"CPU_Task_Round_{ i + 1 } _Exception" ,
83- "error" : str (e )
84- })
98+ print (f"Round { i + 1 } : An error occurred: { e } " )
99+ failing_rounds .append (
100+ {
101+ "round" : i + 1 ,
102+ "task_name" : f"CPU_Task_Round_{ i + 1 } _Exception" ,
103+ "error" : str (e ),
104+ }
105+ )
85106 test_passed = False
86107 # Optionally, decide if one error should stop the whole test
87108 # break
@@ -90,23 +111,32 @@ def main():
90111 # and to let background scheduler of tracker run.
91112 time .sleep (1 )
92113
93- tracker .stop () # Stop the main tracker
114+ tracker .stop () # Stop the main tracker
94115
95116 if test_passed :
96- print ("TEST PASSED: No tasks with zero energy consumption detected for non-trivial durations." )
117+ print (
118+ "TEST PASSED: No tasks with zero energy consumption detected for non-trivial durations."
119+ )
97120 else :
98- print ("TEST FAILED: Some tasks reported zero energy consumption or other errors." )
121+ print (
122+ "TEST FAILED: Some tasks reported zero energy consumption or other errors."
123+ )
99124 print ("Failing rounds details:" )
100125 for detail in failing_rounds :
101126 # Ensure all fields are present with defaults for printing
102- round_num = detail .get ('round' , 'N/A' )
103- task_name_val = detail .get ('task_name' , 'N/A' )
104- duration_val = detail .get ('duration' , float ('nan' )) # Use float('nan') for unavail num
105- energy_val = detail .get ('energy_consumed' , float ('nan' ))
106- error_val = detail .get ('error' , 'None' )
107- print (f" - Round { round_num } : Task '{ task_name_val } ', "
108- f"Duration: { duration_val :.4f} s, Energy: { energy_val :.6f} kWh, "
109- f"Error: { error_val } " )
127+ round_num = detail .get ("round" , "N/A" )
128+ task_name_val = detail .get ("task_name" , "N/A" )
129+ duration_val = detail .get (
130+ "duration" , float ("nan" )
131+ ) # Use float('nan') for unavail num
132+ energy_val = detail .get ("energy_consumed" , float ("nan" ))
133+ error_val = detail .get ("error" , "None" )
134+ print (
135+ f" - Round { round_num } : Task '{ task_name_val } ', "
136+ f"Duration: { duration_val :.4f} s, Energy: { energy_val :.6f} kWh, "
137+ f"Error: { error_val } "
138+ )
139+
110140
111141if __name__ == "__main__" :
112142 main ()
0 commit comments