1717from codecarbon .core .config import get_hierarchical_config
1818from codecarbon .core .emissions import Emissions
1919from codecarbon .core .resource_tracker import ResourceTracker
20- from codecarbon .core .units import Energy , Power , Time
20+ from codecarbon .core .units import Energy , Power , Time , Water
2121from codecarbon .core .util import count_cpus , count_physical_cpus , suppress
2222from codecarbon .external .geography import CloudMetadata , GeoMetadata
2323from codecarbon .external .hardware import CPU , GPU , AppleSiliconChip
@@ -179,6 +179,7 @@ def __init__(
179179 force_cpu_power : Optional [int ] = _sentinel ,
180180 force_ram_power : Optional [int ] = _sentinel ,
181181 pue : Optional [int ] = _sentinel ,
182+ wue : Optional [bool ] = _sentinel ,
182183 force_mode_cpu_load : Optional [bool ] = _sentinel ,
183184 allow_multiple_runs : Optional [bool ] = _sentinel ,
184185 ):
@@ -238,6 +239,7 @@ def __init__(
238239 :param pue: PUE (Power Usage Effectiveness) of the datacenter.
239240 :param force_mode_cpu_load: Force the addition of a CPU in MODE_CPU_LOAD
240241 :param allow_multiple_runs: Allow multiple instances of codecarbon running in parallel. Defaults to False.
242+ :param wue: WUE (Water Usage Effectiveness) of the datacenter, L/kWh.
241243 """
242244
243245 # logger.info("base tracker init")
@@ -287,6 +289,7 @@ def __init__(
287289 self ._set_from_conf (force_cpu_power , "force_cpu_power" , None , float )
288290 self ._set_from_conf (force_ram_power , "force_ram_power" , None , float )
289291 self ._set_from_conf (pue , "pue" , 1.0 , float )
292+ self ._set_from_conf (wue , "wue" , 0 , float )
290293 self ._set_from_conf (force_mode_cpu_load , "force_mode_cpu_load" , False , bool )
291294 self ._set_from_conf (
292295 experiment_id , "experiment_id" , "5b0fa12a-3dd7-45bb-9766-cc326314d9f1"
@@ -299,6 +302,7 @@ def __init__(
299302 self ._start_time : Optional [float ] = None
300303 self ._last_measured_time : float = time .perf_counter ()
301304 self ._total_energy : Energy = Energy .from_energy (kWh = 0 )
305+ self ._total_water : Water = Water .from_litres (litres = 0 )
302306 self ._total_cpu_energy : Energy = Energy .from_energy (kWh = 0 )
303307 self ._total_gpu_energy : Energy = Energy .from_energy (kWh = 0 )
304308 self ._total_ram_energy : Energy = Energy .from_energy (kWh = 0 )
@@ -703,6 +707,7 @@ def _prepare_emissions_data(self) -> EmissionsData:
703707 gpu_energy = self ._total_gpu_energy .kWh ,
704708 ram_energy = self ._total_ram_energy .kWh ,
705709 energy_consumed = self ._total_energy .kWh ,
710+ water_consumed = self ._total_water .litres ,
706711 country_name = country_name ,
707712 country_iso_code = country_iso_code ,
708713 region = region ,
@@ -721,6 +726,7 @@ def _prepare_emissions_data(self) -> EmissionsData:
721726 ram_total_size = self ._conf .get ("ram_total_size" ),
722727 tracking_mode = self ._conf .get ("tracking_mode" ),
723728 pue = self ._pue ,
729+ wue = self ._wue ,
724730 )
725731 logger .debug (total_emissions )
726732 return total_emissions
@@ -778,7 +784,9 @@ def _do_measurements(self) -> None:
778784 ) = hardware .measure_power_and_energy (last_duration = last_duration )
779785 # Apply the PUE of the datacenter to the consumed energy
780786 energy *= self ._pue
787+ water = Water .from_litres (litres = self ._wue * energy .kWh )
781788 self ._total_energy += energy
789+ self ._total_water += water
782790 if isinstance (hardware , CPU ):
783791 self ._total_cpu_energy += energy
784792 self ._cpu_power = power
@@ -825,7 +833,7 @@ def _do_measurements(self) -> None:
825833 f"Done measure for { hardware .__class__ .__name__ } - measurement time: { h_time :,.4f} s - last call { last_duration :,.2f} s"
826834 )
827835 logger .info (
828- f"{ self ._total_energy .kWh :.6f} kWh of electricity used since the beginning."
836+ f"{ self ._total_energy .kWh :.6f} kWh of electricity and { self . _total_water . litres :.6f } L of water were used since the beginning."
829837 )
830838
831839 def _measure_power_and_energy (self ) -> None :
@@ -843,7 +851,11 @@ def _measure_power_and_energy(self) -> None:
843851 raise e
844852
845853 warning_duration = self ._measure_power_secs * 3
846- if last_duration > warning_duration and not self ._scheduler ._stopped :
854+ if (
855+ last_duration > warning_duration
856+ and self ._scheduler
857+ and not self ._scheduler ._stopped
858+ ):
847859 warn_msg = (
848860 "Background scheduler didn't run for a long period"
849861 + " (%ds), results might be inaccurate"
@@ -1066,6 +1078,7 @@ def track_emissions(
10661078 force_cpu_power : Optional [int ] = _sentinel ,
10671079 force_ram_power : Optional [int ] = _sentinel ,
10681080 pue : Optional [int ] = _sentinel ,
1081+ wue : Optional [float ] = _sentinel ,
10691082 allow_multiple_runs : Optional [bool ] = _sentinel ,
10701083):
10711084 """
@@ -1141,6 +1154,7 @@ def track_emissions(
11411154 :param force_cpu_power: cpu power to be used instead of automatic detection.
11421155 :param force_ram_power: ram power to be used instead of automatic detection.
11431156 :param pue: PUE (Power Usage Effectiveness) of the datacenter.
1157+ :param wue: WUE (Water Usage Effectiveness) of the datacenter, L/kWh.
11441158 :param allow_multiple_runs: Prevent multiple instances of codecarbon running. Defaults to False.
11451159
11461160 :return: The decorated function
@@ -1181,6 +1195,7 @@ def wrapped_fn(*args, **kwargs):
11811195 force_cpu_power = force_cpu_power ,
11821196 force_ram_power = force_ram_power ,
11831197 pue = pue ,
1198+ wue = wue ,
11841199 allow_multiple_runs = allow_multiple_runs ,
11851200 )
11861201 else :
@@ -1212,6 +1227,7 @@ def wrapped_fn(*args, **kwargs):
12121227 force_cpu_power = force_cpu_power ,
12131228 force_ram_power = force_ram_power ,
12141229 pue = pue ,
1230+ wue = wue ,
12151231 allow_multiple_runs = allow_multiple_runs ,
12161232 )
12171233 tracker .start ()
0 commit comments