-
-
Notifications
You must be signed in to change notification settings - Fork 276
Expand file tree
/
Copy pathmeasure.py
More file actions
98 lines (92 loc) · 3.91 KB
/
measure.py
File metadata and controls
98 lines (92 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from time import perf_counter
from codecarbon.external.cpu import CPU
from codecarbon.external.hardware import GPU, RAM, AppleSiliconChip
from codecarbon.external.logger import logger
class MeasurePowerEnergy:
"""
Measure power and energy consumption of a hardware component.
"""
_last_measured_time: int = 0
_hardware: list
_pue: float
_total_cpu_energy: float
_total_gpu_energy: float
_total_ram_energy: float
_total_energy: float
_cpu_power: float
_gpu_power: float
_ram_power: float
def __init__(self, hardware, pue):
"""
:param hardware: list of hardware components to measure
:param pue: Power Usage Effectiveness of the datacenter
"""
self._last_measured_time = perf_counter()
self._hardware = hardware
self._pue = pue
# TODO: Read initial energy values from hardware
self._total_cpu_energy = 0
self._total_gpu_energy = 0
self._total_ram_energy = 0
self._total_energy = 0
# Power cant't be read at init because we need time, so we set it to 0
self._cpu_power = 0
self._gpu_power = 0
self._ram_power = 0
def do_measure(self) -> None:
for hardware in self._hardware:
h_time = perf_counter()
# Compute last_duration again for more accuracy
last_duration = perf_counter() - self._last_measured_time
power, energy = hardware.measure_power_and_energy(
last_duration=last_duration
)
# Apply the PUE of the datacenter to the consumed energy
energy *= self._pue
self._total_energy += energy
if isinstance(hardware, CPU):
self._total_cpu_energy += energy
self._cpu_power = power
logger.info(
f"Energy consumed for all CPUs : {self._total_cpu_energy.kWh:.6f} kWh"
+ f". Total CPU Power : {self._cpu_power.W} W"
)
elif isinstance(hardware, GPU):
self._total_gpu_energy += energy
self._gpu_power = power
logger.info(
f"Energy consumed for all GPUs : {self._total_gpu_energy.kWh:.6f} kWh"
+ f". Total GPU Power : {self._gpu_power.W} W"
)
elif isinstance(hardware, RAM):
self._total_ram_energy += energy
self._ram_power = power
logger.info(
f"Energy consumed for RAM : {self._total_ram_energy.kWh:.6f} kWh."
+ f"RAM Power : {self._ram_power.W} W"
)
elif isinstance(hardware, AppleSiliconChip):
if hardware.chip_part == "CPU":
self._total_cpu_energy += energy
self._cpu_power = power
logger.info(
f"Energy consumed for AppleSilicon CPU : {self._total_cpu_energy.kWh:.6f} kWh"
+ f".Apple Silicon CPU Power : {self._cpu_power.W} W"
)
elif hardware.chip_part == "GPU":
self._total_gpu_energy += energy
self._gpu_power = power
logger.info(
f"Energy consumed for AppleSilicon GPU : {self._total_gpu_energy.kWh:.6f} kWh"
+ f".Apple Silicon GPU Power : {self._gpu_power.W} W"
)
else:
logger.error(f"Unknown hardware type: {hardware} ({type(hardware)})")
h_time = perf_counter() - h_time
logger.debug(
f"{hardware.__class__.__name__} : {hardware.total_power().W:,.2f} "
+ f"W during {last_duration:,.2f} s [measurement time: {h_time:,.4f}]"
)
logger.info(
f"{self._total_energy.kWh:.6f} kWh of electricity used since the beginning."
)