22import logging
33import datetime
44
5- from codecarbon import EmissionsTracker
6- from codecarbon .output_methods . base_output import BaseOutput as cc_BaseOutput
5+ from codecarbon import EmissionsTracker , OfflineEmissionsTracker
6+ from codecarbon .output import BaseOutput as cc_BaseOutput
77from simvue .utilities import simvue_timestamp
88
99if typing .TYPE_CHECKING :
@@ -32,30 +32,43 @@ def out(
3232
3333 if meta_update :
3434 logger .debug ("Logging CodeCarbon metadata" )
35- self ._simvue_run .update_metadata (
36- {
37- "codecarbon.country" : total .country_name ,
38- "codecarbon.country_iso_code" : total .country_iso_code ,
39- "codecarbon.region" : total .region ,
40- "codecarbon.version" : total .codecarbon_version ,
41- }
35+ try :
36+ self ._simvue_run .update_metadata (
37+ {
38+ "codecarbon" : {
39+ "country" : total .country_name ,
40+ "country_iso_code" : total .country_iso_code ,
41+ "region" : total .region ,
42+ "version" : total .codecarbon_version ,
43+ }
44+ }
45+ )
46+ except AttributeError as e :
47+ logger .error (f"Failed to update metadata: { e } " )
48+ try :
49+ _cc_timestamp = datetime .datetime .strptime (
50+ total .timestamp , "%Y-%m-%dT%H:%M:%S"
4251 )
43-
44- _cc_timestamp : datetime .datetime = datetime .datetime .strptime (
45- total .timestamp , "%Y-%m-%dT%H:%M:%S"
46- )
52+ except ValueError as e :
53+ logger .error (f"Error parsing timestamp: { e } " )
54+ return
4755
4856 logger .debug ("Logging CodeCarbon metrics" )
49- self ._simvue_run .log_metrics (
50- metrics = {
51- "codecarbon.total.emissions" : total .emissions ,
52- "codecarbon.total.energy_consumed" : total .energy_consumed ,
53- "codecarbon.delta.emissions" : delta .emissions ,
54- "codecarbon.delta.energy_consumed" : delta .energy_consumed ,
55- },
56- step = self ._metrics_step ,
57- timestamp = simvue_timestamp (_cc_timestamp ),
58- )
57+ try :
58+ self ._simvue_run .log_metrics (
59+ metrics = {
60+ "codecarbon.total.emissions" : total .emissions ,
61+ "codecarbon.total.energy_consumed" : total .energy_consumed ,
62+ "codecarbon.delta.emissions" : delta .emissions ,
63+ "codecarbon.delta.energy_consumed" : delta .energy_consumed ,
64+ },
65+ step = self ._metrics_step ,
66+ timestamp = simvue_timestamp (_cc_timestamp ),
67+ )
68+ except ArithmeticError as e :
69+ logger .error (f"Failed to log metrics: { e } " )
70+ return
71+
5972 self ._metrics_step += 1
6073
6174 def live_out (self , total : "EmissionsData" , delta : "EmissionsData" ) -> None :
@@ -71,6 +84,36 @@ def __init__(
7184 super ().__init__ (
7285 project_name = project_name ,
7386 measure_power_secs = metrics_interval ,
87+ api_call_interval = 1 ,
88+ experiment_id = None ,
89+ experiment_name = None ,
90+ logging_logger = CodeCarbonOutput (simvue_run ),
91+ save_to_logger = True ,
92+ allow_multiple_runs = True ,
93+ log_level = "error" ,
94+ )
95+
96+ def set_measure_interval (self , interval : int ) -> None :
97+ """Set the measure interval"""
98+ self ._set_from_conf (interval , "measure_power_secs" )
99+
100+ def post_init (self ) -> None :
101+ self ._set_from_conf (self ._simvue_run ._id , "experiment_id" )
102+ self ._set_from_conf (self ._simvue_run ._name , "experiment_name" )
103+ self .start ()
104+
105+
106+ class OfflineSimvueEmissionsTracker (OfflineEmissionsTracker ):
107+ def __init__ (
108+ self , project_name : str , simvue_run : "Run" , metrics_interval : int
109+ ) -> None :
110+ self ._simvue_run = simvue_run
111+ logger .setLevel (logging .ERROR )
112+ super ().__init__ (
113+ country_iso_code = simvue_run ._user_config .offline .country_iso_code ,
114+ project_name = project_name ,
115+ measure_power_secs = metrics_interval ,
116+ api_call_interval = 1 ,
74117 experiment_id = None ,
75118 experiment_name = None ,
76119 logging_logger = CodeCarbonOutput (simvue_run ),
0 commit comments