def measure_power_and_energy(self, last_duration: float) -> Tuple[Power, Energy]: """ Base implementation: we get the power from the hardware and convert it to energy. """ power = self.total_power() energy = Energy.from_power_and_time( power=power, time=Time.from_seconds(last_duration)) return power, energy
def _measure_power(self) -> None: """ A function that is periodically run by the `BackgroundScheduler` every `self._measure_power` seconds. :return: None """ last_duration = time.time() - self._last_measured_time warning_duration = self._measure_power_secs * 3 if last_duration > warning_duration: warn_msg = ( "Background scheduler didn't run for a " + "long period (%ds), results might be inacurate" ) logger.warning(warn_msg, last_duration) self._total_energy += Energy.from_power_and_time( power=self._hardware.total_power, time=Time.from_seconds(last_duration) ) self._last_measured_time = time.time()
def _prepare_emissions_data(self) -> EmissionsData: cloud: CloudMetadata = self._get_cloud_metadata() geo: GeoMetadata = self._get_geo_metadata() duration: Time = Time.from_seconds(time.time() - self._start_time) if cloud.is_on_private_infra: emissions = self._emissions.get_private_infra_emissions( self._total_energy, geo) country_name = geo.country_name country_iso_code = geo.country_iso_code region = geo.region on_cloud = "N" cloud_provider = "" cloud_region = "" else: emissions = self._emissions.get_cloud_emissions( self._total_energy, cloud) country_name = self._emissions.get_cloud_country_name(cloud) country_iso_code = self._emissions.get_cloud_country_iso_code( cloud) region = self._emissions.get_cloud_geo_region(cloud) on_cloud = "Y" cloud_provider = cloud.provider cloud_region = cloud.region return EmissionsData( timestamp=datetime.now().strftime("%Y-%m-%dT%H:%M:%S"), experiment_id=str(uuid.uuid4()), project_name=self._project_name, duration=duration.seconds, emissions=emissions, energy_consumed=self._total_energy.kwh, country_name=country_name, country_iso_code=country_iso_code, region=region, on_cloud=on_cloud, cloud_provider=cloud_provider, cloud_region=cloud_region, )
def _measure_power(self) -> None: """ A function that is periodically run by the `BackgroundScheduler` every `self._measure_power` seconds. :return: None """ last_duration = time.time() - self._last_measured_time warning_duration = self._measure_power_secs * 3 if last_duration > warning_duration: warn_msg = ( "CODECARBON : Background scheduler didn't run for a long period" + " (%ds), results might be inaccurate") logger.warning(warn_msg, last_duration) for hardware in self._hardware: self._total_energy += Energy.from_power_and_time( power=hardware.total_power(), time=Time.from_seconds(last_duration)) logger.info( f"CODECARBON : Energy consumed {hardware.__class__.__name__} : {self._total_energy}" ) self._last_measured_time = time.time()
def _prepare_emissions_data(self, delta=False) -> EmissionsData: """ :delta: True to return only the delta comsumption since last call """ cloud: CloudMetadata = self._get_cloud_metadata() duration: Time = Time.from_seconds(time.time() - self._start_time) if cloud.is_on_private_infra: emissions = self._emissions.get_private_infra_emissions( self._total_energy, self._geo) # float: kg co2_eq country_name = self._geo.country_name country_iso_code = self._geo.country_iso_code region = self._geo.region on_cloud = "N" cloud_provider = "" cloud_region = "" else: emissions = self._emissions.get_cloud_emissions( self._total_energy, cloud) country_name = self._emissions.get_cloud_country_name(cloud) country_iso_code = self._emissions.get_cloud_country_iso_code( cloud) region = self._emissions.get_cloud_geo_region(cloud) on_cloud = "Y" cloud_provider = cloud.provider cloud_region = cloud.region total_emissions = EmissionsData( timestamp=datetime.now().strftime("%Y-%m-%dT%H:%M:%S"), project_name=self._project_name, run_id=str(self.run_id), duration=duration.seconds, emissions=emissions, emissions_rate=emissions * 1000 / duration.seconds, # g/s cpu_power=self._cpu_power.W, gpu_power=self._gpu_power.W, ram_power=self._ram_power.W, cpu_energy=self._total_cpu_energy.kWh, gpu_energy=self._total_gpu_energy.kWh, ram_energy=self._total_ram_energy.kWh, energy_consumed=self._total_energy.kWh, country_name=country_name, country_iso_code=country_iso_code, region=region, on_cloud=on_cloud, cloud_provider=cloud_provider, cloud_region=cloud_region, os=self._conf.get("os"), python_version=self._conf.get("python_version"), gpu_count=self._conf.get("gpu_count"), gpu_model=self._conf.get("gpu_model"), cpu_count=self._conf.get("cpu_count"), cpu_model=self._conf.get("cpu_model"), longitude=self._conf.get("longitude"), latitude=self._conf.get("latitude"), ram_total_size=self._conf.get("ram_total_size"), tracking_mode=self._conf.get("tracking_mode"), ) if delta: if self._previous_emissions is None: self._previous_emissions = total_emissions else: # Create a copy delta_emissions = dataclasses.replace(total_emissions) # Compute emissions rate from delta delta_emissions.compute_delta_emission( self._previous_emissions) # TODO : find a way to store _previous_emissions only when # TODO : the API call succeeded self._previous_emissions = total_emissions total_emissions = delta_emissions logger.debug(total_emissions) return total_emissions
def end(self, delay): self.power_measurement = ( abs(float(self._get_value()) - float(self.energy_reading)) / Time.from_seconds(delay).hours) return