willsh1997 commited on
Commit
deb7c43
·
1 Parent(s): 654d664

:wrench: remove codecarbon install, add slightly modified codecarbon pkg to repo

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. codecarbon/__init__.py +13 -0
  2. codecarbon/_version.py +1 -0
  3. codecarbon/cli/__init__.py +0 -0
  4. codecarbon/cli/cli_utils.py +110 -0
  5. codecarbon/cli/main.py +381 -0
  6. codecarbon/core/__init__.py +0 -0
  7. codecarbon/core/api_client.py +362 -0
  8. codecarbon/core/cloud.py +71 -0
  9. codecarbon/core/co2_signal.py +62 -0
  10. codecarbon/core/config.py +115 -0
  11. codecarbon/core/cpu.py +521 -0
  12. codecarbon/core/emissions.py +308 -0
  13. codecarbon/core/gpu.py +305 -0
  14. codecarbon/core/measure.py +97 -0
  15. codecarbon/core/powermetrics.py +200 -0
  16. codecarbon/core/rapl.py +58 -0
  17. codecarbon/core/resource_tracker.py +230 -0
  18. codecarbon/core/schemas.py +110 -0
  19. codecarbon/core/units.py +164 -0
  20. codecarbon/core/util.py +157 -0
  21. codecarbon/data/canada_provinces.geojson +0 -0
  22. codecarbon/data/cloud/impact.csv +41 -0
  23. codecarbon/data/hardware/cpu_dataset_builder/CPU_Create_Dataset.ipynb +1671 -0
  24. codecarbon/data/hardware/cpu_dataset_builder/README.md +15 -0
  25. codecarbon/data/hardware/cpu_dataset_builder/amd_cpu_desktop_dataset.csv +0 -0
  26. codecarbon/data/hardware/cpu_dataset_builder/amd_cpu_scrapper.py +120 -0
  27. codecarbon/data/hardware/cpu_dataset_builder/amd_cpu_server_dataset.csv +203 -0
  28. codecarbon/data/hardware/cpu_dataset_builder/intel_cpu_ark_dataset.csv +0 -0
  29. codecarbon/data/hardware/cpu_dataset_builder/intel_cpu_scrapper.py +284 -0
  30. codecarbon/data/hardware/cpu_dataset_builder/merge_scrapped_cpu_power.py +159 -0
  31. codecarbon/data/hardware/cpu_load_profiling/AMD_EPYC_8024P_8C/compare_cpu_load_and_RAPL-all_cores-AMD_EPYC_8024P_8-Core_Processor-2025-01-14-tasks.csv +1 -0
  32. codecarbon/data/hardware/cpu_load_profiling/AMD_EPYC_8024P_8C/compare_cpu_load_and_RAPL-all_cores-AMD_EPYC_8024P_8-Core_Processor-2025-01-14.csv +12 -0
  33. codecarbon/data/hardware/cpu_load_profiling/AMD_EPYC_8024P_8C/compare_cpu_load_and_RAPL-some_cores-AMD_EPYC_8024P_8-Core_Processor-2025-01-14-tasks.csv +1 -0
  34. codecarbon/data/hardware/cpu_load_profiling/AMD_EPYC_8024P_8C/compare_cpu_load_and_RAPL-some_cores-AMD_EPYC_8024P_8-Core_Processor-2025-01-14.csv +12 -0
  35. codecarbon/data/hardware/cpu_load_profiling/AMD_Threadripper/compare_cpu_load_and_RAPL-all_cores-AMD_Ryzen_Threadripper_1950X_16-Core_Processor-2025-01-14.csv +12 -0
  36. codecarbon/data/hardware/cpu_load_profiling/AMD_Threadripper/compare_cpu_load_and_RAPL-some_cores-AMD_Ryzen_Threadripper_1950X_16-Core_Processor-2025-01-14.csv +12 -0
  37. codecarbon/data/hardware/cpu_load_profiling/E3-1240/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14-tasks.csv +1 -0
  38. codecarbon/data/hardware/cpu_load_profiling/E3-1240/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14.csv +12 -0
  39. codecarbon/data/hardware/cpu_load_profiling/E3-1240/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14-tasks.csv +1 -0
  40. codecarbon/data/hardware/cpu_load_profiling/E3-1240/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14.csv +10 -0
  41. codecarbon/data/hardware/cpu_load_profiling/E5-1240/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14-tasks.csv +1 -0
  42. codecarbon/data/hardware/cpu_load_profiling/E5-1240/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14.csv +12 -0
  43. codecarbon/data/hardware/cpu_load_profiling/E5-1240/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14-tasks.csv +1 -0
  44. codecarbon/data/hardware/cpu_load_profiling/E5-1240/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14.csv +10 -0
  45. codecarbon/data/hardware/cpu_load_profiling/E5-2620/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E5-2620_v3_@_2.40GHz-2025-01-14-tasks.csv +1 -0
  46. codecarbon/data/hardware/cpu_load_profiling/E5-2620/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E5-2620_v3_@_2.40GHz-2025-01-14.csv +12 -0
  47. codecarbon/data/hardware/cpu_load_profiling/E5-2620/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E5-2620_v3_@_2.40GHz-2025-01-14-tasks.csv +1 -0
  48. codecarbon/data/hardware/cpu_load_profiling/E5-2620/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E5-2620_v3_@_2.40GHz-2025-01-14.csv +12 -0
  49. codecarbon/data/hardware/cpu_power.csv +0 -0
  50. codecarbon/data/private_infra/2016/canada_energy_mix.json +171 -0
codecarbon/__init__.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ The Carbon Tracker module. The following objects/decorators belong to the Public API
3
+ """
4
+
5
+ from ._version import __version__ # noqa
6
+ from .emissions_tracker import (
7
+ EmissionsTracker,
8
+ OfflineEmissionsTracker,
9
+ track_emissions,
10
+ )
11
+
12
+ __all__ = ["EmissionsTracker", "OfflineEmissionsTracker", "track_emissions"]
13
+ __app_name__ = "codecarbon"
codecarbon/_version.py ADDED
@@ -0,0 +1 @@
 
 
1
+ __version__ = "3.0.2"
codecarbon/cli/__init__.py ADDED
File without changes
codecarbon/cli/cli_utils.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import configparser
2
+ from pathlib import Path
3
+ from typing import Optional
4
+
5
+ import typer
6
+ from rich.prompt import Confirm
7
+
8
+
9
+ def get_config(path: Optional[Path] = None):
10
+ p = path or Path.cwd().resolve() / ".codecarbon.config"
11
+
12
+ if p.exists():
13
+ config = configparser.ConfigParser()
14
+ config.read(str(p))
15
+ if "codecarbon" in config.sections():
16
+ d = dict(config["codecarbon"])
17
+ return d
18
+
19
+ else:
20
+ raise FileNotFoundError(
21
+ "No .codecarbon.config file found in the current directory."
22
+ )
23
+
24
+
25
+ def get_api_endpoint(path: Optional[Path] = None):
26
+ p = path or Path.cwd().resolve() / ".codecarbon.config"
27
+ if p.exists():
28
+ config = configparser.ConfigParser()
29
+ config.read(str(p))
30
+ if "codecarbon" in config.sections():
31
+ d = dict(config["codecarbon"])
32
+ if "api_endpoint" in d:
33
+ return d["api_endpoint"]
34
+ else:
35
+ with p.open("a") as f:
36
+ f.write("api_endpoint=https://api.codecarbon.io\n")
37
+ return "https://api.codecarbon.io"
38
+
39
+
40
+ def get_existing_local_exp_id(path: Optional[Path] = None):
41
+ p = path or Path.cwd().resolve() / ".codecarbon.config"
42
+ if p.exists():
43
+ existing_path = p
44
+ else:
45
+ existing_path = Path("~/.codecarbon.config").expanduser()
46
+ return _get_local_exp_id(existing_path)
47
+
48
+
49
+ def _get_local_exp_id(p: Optional[Path] = None):
50
+ config = configparser.ConfigParser()
51
+ config.read(str(p))
52
+ if "codecarbon" in config.sections():
53
+ d = dict(config["codecarbon"])
54
+ if "experiment_id" in d:
55
+ return d["experiment_id"]
56
+
57
+
58
+ def write_local_exp_id(exp_id, path: Optional[Path] = None):
59
+ p = path or Path.cwd().resolve() / ".codecarbon.config"
60
+
61
+ config = configparser.ConfigParser()
62
+ if p.exists():
63
+ config.read(str(p))
64
+ if "codecarbon" not in config.sections():
65
+ config.add_section("codecarbon")
66
+
67
+ config["codecarbon"]["experiment_id"] = exp_id
68
+
69
+ with p.open("w") as f:
70
+ config.write(f)
71
+
72
+
73
+ def overwrite_local_config(config_name, value, path: Optional[Path] = None):
74
+ p = path or Path.cwd().resolve() / ".codecarbon.config"
75
+
76
+ config = configparser.ConfigParser()
77
+ if p.exists():
78
+ config.read(str(p))
79
+ if "codecarbon" not in config.sections():
80
+ config.add_section("codecarbon")
81
+
82
+ config["codecarbon"][config_name] = value
83
+ with p.open("w") as f:
84
+ config.write(f)
85
+
86
+
87
+ def create_new_config_file():
88
+ typer.echo("Creating new config file")
89
+ file_path = typer.prompt(
90
+ "Where do you want to put your config file ?",
91
+ type=str,
92
+ default="~/.codecarbon.config",
93
+ )
94
+ if file_path[0] == "~":
95
+ file_path = Path.home() / file_path[2:]
96
+ else:
97
+ file_path = Path(file_path)
98
+
99
+ if not file_path.parent.exists():
100
+ create = Confirm.ask(
101
+ "Parent folder does not exist do you want to create it (and parents) ?"
102
+ )
103
+ if create:
104
+ file_path.parent.mkdir(parents=True, exist_ok=True)
105
+
106
+ file_path.touch()
107
+ with open(file_path, "w") as f:
108
+ f.write("[codecarbon]\n")
109
+ typer.echo(f"Config file created at {file_path}")
110
+ return file_path
codecarbon/cli/main.py ADDED
@@ -0,0 +1,381 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import time
4
+ from pathlib import Path
5
+ from typing import Optional
6
+
7
+ import questionary
8
+ import requests
9
+ import typer
10
+ from fief_client import Fief
11
+ from fief_client.integrations.cli import FiefAuth
12
+ from rich import print
13
+ from rich.prompt import Confirm
14
+ from typing_extensions import Annotated
15
+
16
+ from codecarbon import __app_name__, __version__
17
+ from codecarbon.cli.cli_utils import (
18
+ create_new_config_file,
19
+ get_api_endpoint,
20
+ get_config,
21
+ get_existing_local_exp_id,
22
+ overwrite_local_config,
23
+ )
24
+ from codecarbon.core.api_client import ApiClient, get_datetime_with_timezone
25
+ from codecarbon.core.schemas import ExperimentCreate, OrganizationCreate, ProjectCreate
26
+ from codecarbon.emissions_tracker import EmissionsTracker
27
+
28
+ AUTH_CLIENT_ID = os.environ.get(
29
+ "AUTH_CLIENT_ID",
30
+ "jsUPWIcUECQFE_ouanUuVhXx52TTjEVcVNNtNGeyAtU",
31
+ )
32
+ AUTH_SERVER_URL = os.environ.get(
33
+ "AUTH_SERVER_URL", "https://auth.codecarbon.io/codecarbon"
34
+ )
35
+ API_URL = os.environ.get("API_URL", "https://dashboard.codecarbon.io/api")
36
+
37
+ DEFAULT_PROJECT_ID = "e60afa92-17b7-4720-91a0-1ae91e409ba1"
38
+ DEFAULT_ORGANIzATION_ID = "e60afa92-17b7-4720-91a0-1ae91e409ba1"
39
+
40
+ codecarbon = typer.Typer(no_args_is_help=True)
41
+
42
+
43
+ def _version_callback(value: bool) -> None:
44
+ if value:
45
+ print(f"{__app_name__} v{__version__}")
46
+ raise typer.Exit()
47
+
48
+
49
+ @codecarbon.callback()
50
+ def main(
51
+ version: Optional[bool] = typer.Option(
52
+ None,
53
+ "--version",
54
+ "-v",
55
+ help="Show the application's version and exit.",
56
+ callback=_version_callback,
57
+ is_eager=True,
58
+ ),
59
+ ) -> None:
60
+ return
61
+
62
+
63
+ def show_config(path: Path = Path("./.codecarbon.config")) -> None:
64
+ d = get_config(path)
65
+ api_endpoint = get_api_endpoint(path)
66
+ api = ApiClient(endpoint_url=api_endpoint)
67
+ api.set_access_token(_get_access_token())
68
+ print("Current configuration : \n")
69
+ print("Config file content : ")
70
+ print(d)
71
+ try:
72
+ if "organization_id" not in d:
73
+ print(
74
+ "No organization_id in config, follow setup instruction to complete your configuration file!",
75
+ )
76
+ else:
77
+ org = api.get_organization(d["organization_id"])
78
+
79
+ if "project_id" not in d:
80
+ print(
81
+ "No project_id in config, follow setup instruction to complete your configuration file!",
82
+ )
83
+ else:
84
+ project = api.get_project(d["project_id"])
85
+ if "experiment_id" not in d:
86
+ print(
87
+ "No experiment_id in config, follow setup instruction to complete your configuration file!",
88
+ )
89
+ else:
90
+ experiment = api.get_experiment(d["experiment_id"])
91
+ print("\nExperiment :")
92
+ print(experiment)
93
+ print("\nProject :")
94
+ print(project)
95
+ print("\nOrganization :")
96
+ print(org)
97
+ except Exception as e:
98
+ raise ValueError(
99
+ f"Your configuration is invalid, please verify your configuration file at {path}. To start from scratch, run `codecarbon config` and overwrite your configuration file. (error: {e})"
100
+ )
101
+
102
+
103
+ def get_fief_auth():
104
+ fief = Fief(AUTH_SERVER_URL, AUTH_CLIENT_ID)
105
+ fief_auth = FiefAuth(fief, "./credentials.json")
106
+ return fief_auth
107
+
108
+
109
+ def _get_access_token():
110
+ try:
111
+ access_token_info = get_fief_auth().access_token_info()
112
+ access_token = access_token_info["access_token"]
113
+ return access_token
114
+ except Exception as e:
115
+ raise ValueError(
116
+ f"Not able to retrieve the access token, please run `codecarbon login` first! (error: {e})"
117
+ )
118
+
119
+
120
+ def _get_id_token():
121
+ id_token = get_fief_auth()._tokens["id_token"]
122
+ return id_token
123
+
124
+
125
+ @codecarbon.command(
126
+ "test-api", short_help="Make an authenticated GET request to an API endpoint"
127
+ )
128
+ def api_get():
129
+ """
130
+ ex: test-api
131
+ """
132
+ api = ApiClient(endpoint_url=API_URL) # TODO: get endpoint from config
133
+ api.set_access_token(_get_access_token())
134
+ organizations = api.get_list_organizations()
135
+ print(organizations)
136
+
137
+
138
+ @codecarbon.command("login", short_help="Login to CodeCarbon")
139
+ def login():
140
+ get_fief_auth().authorize()
141
+ api = ApiClient(endpoint_url=API_URL) # TODO: get endpoint from config
142
+ id_token = _get_id_token()
143
+ api.set_access_token(id_token)
144
+ api.check_auth()
145
+
146
+
147
+ def get_api_key(project_id: str):
148
+ req = requests.post(
149
+ f"{API_URL}/projects/{project_id}/api-tokens",
150
+ json={
151
+ "project_id": project_id,
152
+ "name": "api token",
153
+ "x_token": "???",
154
+ },
155
+ headers={"Authorization": f"Bearer {_get_access_token()}"},
156
+ )
157
+ api_key = req.json()["token"]
158
+ return api_key
159
+
160
+
161
+ @codecarbon.command("get-token", short_help="Get project token")
162
+ def get_token(project_id: str):
163
+ # api = ApiClient(endpoint_url=API_URL) # TODO: get endpoint from config
164
+ # api.set_access_token(_get_access_token())
165
+ token = get_api_key(project_id)
166
+ print("Your token: " + token)
167
+ print("Add it to the api_key field in your configuration file")
168
+
169
+
170
+ @codecarbon.command("config", short_help="Generate or show config")
171
+ def config():
172
+ """
173
+ Initialize CodeCarbon, this will prompt you for configuration of Organisation/Team/Project/Experiment.
174
+ """
175
+
176
+ print("Welcome to CodeCarbon configuration wizard")
177
+ home = Path.home()
178
+ global_path = (home / ".codecarbon.config").expanduser().resolve()
179
+
180
+ if global_path.exists():
181
+ print("Existing global config file found :")
182
+ show_config(global_path)
183
+
184
+ use_config = questionary_prompt(
185
+ "Use existing global ~/.codecarbon.config to configure or create a new file somewhere else ?",
186
+ ["~/.codecarbon.config", "Create New Config"],
187
+ default="~/.codecarbon.config",
188
+ )
189
+
190
+ if use_config == "~/.codecarbon.config":
191
+ modify = Confirm.ask("Do you want to modify the existing config file ?")
192
+ if modify:
193
+ print(f"Modifying existing config file {global_path}:")
194
+ file_path = global_path
195
+ else:
196
+ print(f"Using already existing global config file {global_path}")
197
+
198
+ return
199
+ else:
200
+ file_path = create_new_config_file()
201
+ else:
202
+ file_path = create_new_config_file()
203
+
204
+ api_endpoint = get_api_endpoint(file_path)
205
+ api_endpoint = typer.prompt(
206
+ f"Current API endpoint is {api_endpoint}. Press enter to continue or input other url",
207
+ type=str,
208
+ default=api_endpoint,
209
+ )
210
+ overwrite_local_config("api_endpoint", api_endpoint, path=file_path)
211
+ api = ApiClient(endpoint_url=api_endpoint)
212
+ api.set_access_token(_get_access_token())
213
+ organizations = api.get_list_organizations()
214
+ org = questionary_prompt(
215
+ "Pick existing organization from list or Create new organization ?",
216
+ [org["name"] for org in organizations] + ["Create New Organization"],
217
+ default="Create New Organization",
218
+ )
219
+
220
+ if org == "Create New Organization":
221
+ org_name = typer.prompt("Organization name", default="Code Carbon user test")
222
+ org_description = typer.prompt(
223
+ "Organization description", default="Code Carbon user test"
224
+ )
225
+
226
+ organization_create = OrganizationCreate(
227
+ name=org_name,
228
+ description=org_description,
229
+ )
230
+ organization = api.create_organization(organization=organization_create)
231
+ if organization is None:
232
+ print("Error creating organization")
233
+ return
234
+ print(f"Created organization : {organization}")
235
+ else:
236
+ organization = [orga for orga in organizations if orga["name"] == org][0]
237
+ org_id = organization["id"]
238
+ overwrite_local_config("organization_id", org_id, path=file_path)
239
+
240
+ projects = api.list_projects_from_organization(org_id)
241
+ project_names = [project["name"] for project in projects] if projects else []
242
+ project = questionary_prompt(
243
+ "Pick existing project from list or Create new project ?",
244
+ project_names + ["Create New Project"],
245
+ default="Create New Project",
246
+ )
247
+ if project == "Create New Project":
248
+ project_name = typer.prompt("Project name", default="Code Carbon user test")
249
+ project_description = typer.prompt(
250
+ "Project description", default="Code Carbon user test"
251
+ )
252
+ project_create = ProjectCreate(
253
+ name=project_name,
254
+ description=project_description,
255
+ organization_id=org_id,
256
+ )
257
+ project = api.create_project(project=project_create)
258
+ print(f"Created project : {project}")
259
+ else:
260
+ project = [p for p in projects if p["name"] == project][0]
261
+ project_id = project["id"]
262
+ overwrite_local_config("project_id", project_id, path=file_path)
263
+
264
+ experiments = api.list_experiments_from_project(project_id)
265
+ experiments_names = (
266
+ [experiment["name"] for experiment in experiments] if experiments else []
267
+ )
268
+
269
+ experiment = questionary_prompt(
270
+ "Pick existing experiment from list or Create new experiment ?",
271
+ experiments_names + ["Create New Experiment"],
272
+ default="Create New Experiment",
273
+ )
274
+ if experiment == "Create New Experiment":
275
+ print("Creating new experiment")
276
+ exp_name = typer.prompt("Experiment name :", default="Code Carbon user test")
277
+ exp_description = typer.prompt(
278
+ "Experiment description :",
279
+ default="Code Carbon user test ",
280
+ )
281
+
282
+ exp_on_cloud = Confirm.ask("Is this experiment running on the cloud ?")
283
+ if exp_on_cloud is True:
284
+ cloud_provider = typer.prompt(
285
+ "Cloud provider (AWS, GCP, Azure, ...)", default="AWS"
286
+ )
287
+ cloud_region = typer.prompt(
288
+ "Cloud region (eu-west-1, us-east-1, ...)", default="eu-west-1"
289
+ )
290
+ else:
291
+ cloud_provider = None
292
+ cloud_region = None
293
+ country_name = typer.prompt("Country name :", default="Auto")
294
+ country_iso_code = typer.prompt("Country ISO code :", default="Auto")
295
+ region = typer.prompt("Region :", default="Auto")
296
+ if country_name == "Auto":
297
+ country_name = None
298
+ if country_iso_code == "Auto":
299
+ country_iso_code = None
300
+ if region == "Auto":
301
+ region = None
302
+ experiment_create = ExperimentCreate(
303
+ timestamp=get_datetime_with_timezone(),
304
+ name=exp_name,
305
+ description=exp_description,
306
+ on_cloud=exp_on_cloud,
307
+ project_id=project["id"],
308
+ country_name=country_name,
309
+ country_iso_code=country_iso_code,
310
+ region=region,
311
+ cloud_provider=cloud_provider,
312
+ cloud_region=cloud_region,
313
+ )
314
+ experiment = api.add_experiment(experiment=experiment_create)
315
+
316
+ else:
317
+ experiment = [e for e in experiments if e["name"] == experiment][0]
318
+
319
+ overwrite_local_config("experiment_id", experiment["id"], path=file_path)
320
+ api_key = get_api_key(project_id)
321
+ overwrite_local_config("api_key", api_key, path=file_path)
322
+ show_config(file_path)
323
+ print(
324
+ "Consult [link=https://mlco2.github.io/codecarbon/usage.html#configuration]configuration documentation[/link] for more configuration options"
325
+ )
326
+
327
+
328
+ @codecarbon.command("monitor", short_help="Monitor your machine's carbon emissions.")
329
+ def monitor(
330
+ measure_power_secs: Annotated[
331
+ int, typer.Argument(help="Interval between two measures.")
332
+ ] = 10,
333
+ api_call_interval: Annotated[
334
+ int, typer.Argument(help="Number of measures between API calls.")
335
+ ] = 30,
336
+ api: Annotated[
337
+ bool, typer.Option(help="Choose to call Code Carbon API or not")
338
+ ] = True,
339
+ ):
340
+ """Monitor your machine's carbon emissions.
341
+
342
+ Args:
343
+ measure_power_secs (Annotated[int, typer.Argument, optional): Interval between two measures. Defaults to 10.
344
+ api_call_interval (Annotated[int, typer.Argument, optional): Number of measures before calling API. Defaults to 30.
345
+ api (Annotated[bool, typer.Option, optional): Choose to call Code Carbon API or not. Defaults to True.
346
+ """
347
+ experiment_id = get_existing_local_exp_id()
348
+ if api:
349
+ if experiment_id is None:
350
+ print(
351
+ "ERROR: No experiment id, call 'codecarbon config' first.",
352
+ file=sys.stderr,
353
+ )
354
+ print("CodeCarbon is going in an infinite loop to monitor this machine.")
355
+ with EmissionsTracker(
356
+ measure_power_secs=measure_power_secs,
357
+ api_call_interval=api_call_interval,
358
+ save_to_api=api,
359
+ ) as tracker:
360
+ # Infinite loop
361
+ while True:
362
+ if (
363
+ hasattr(tracker, "_another_instance_already_running")
364
+ and tracker._another_instance_already_running
365
+ ):
366
+ print("Another instance of CodeCarbon is already running. Exiting.")
367
+ break
368
+ time.sleep(300)
369
+
370
+
371
+ def questionary_prompt(prompt, list_options, default):
372
+ value = questionary.select(
373
+ prompt,
374
+ list_options,
375
+ default,
376
+ ).ask()
377
+ return value
378
+
379
+
380
+ if __name__ == "__main__":
381
+ codecarbon()
codecarbon/core/__init__.py ADDED
File without changes
codecarbon/core/api_client.py ADDED
@@ -0,0 +1,362 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+
3
+ Based on https://kernelpanic.io/the-modern-way-to-call-apis-in-python
4
+
5
+ TODO : use async call to API
6
+ """
7
+
8
+ # from httpx import AsyncClient
9
+ import dataclasses
10
+ import json
11
+ from datetime import timedelta, tzinfo
12
+
13
+ import arrow
14
+ import requests
15
+
16
+ from codecarbon.core.schemas import (
17
+ EmissionCreate,
18
+ ExperimentCreate,
19
+ OrganizationCreate,
20
+ ProjectCreate,
21
+ RunCreate,
22
+ )
23
+ from codecarbon.external.logger import logger
24
+
25
+ # from codecarbon.output import EmissionsData
26
+
27
+
28
+ def get_datetime_with_timezone():
29
+ timestamp = str(arrow.now().isoformat())
30
+ return timestamp
31
+
32
+
33
+ class ApiClient: # (AsyncClient)
34
+ """
35
+ This class call the Code Carbon API
36
+ """
37
+
38
+ run_id = None
39
+
40
+ def __init__(
41
+ self,
42
+ endpoint_url="https://api.codecarbon.io",
43
+ experiment_id=None,
44
+ api_key=None,
45
+ access_token=None,
46
+ conf=None,
47
+ create_run_automatically=True,
48
+ ):
49
+ """
50
+ :endpoint_url: URL of the API endpoint
51
+ :experiment_id: ID of the experiment
52
+ :api_key: Code Carbon API_KEY
53
+ :access_token: Code Carbon API access token
54
+ :conf: Metadata of the experiment
55
+ :create_run_automatically: If False, do not create a run. To use API in read only mode.
56
+ """
57
+ # super().__init__(base_url=endpoint_url) # (AsyncClient)
58
+ self.url = endpoint_url
59
+ self.experiment_id = experiment_id
60
+ self.api_key = api_key
61
+ self.conf = conf
62
+ self.access_token = access_token
63
+ if self.experiment_id is not None and create_run_automatically:
64
+ self._create_run(self.experiment_id)
65
+
66
+ def _get_headers(self):
67
+ headers = {"Content-Type": "application/json"}
68
+ if self.api_key:
69
+ # set the x-api-token header
70
+ headers["x-api-token"] = self.api_key
71
+ elif self.access_token:
72
+ headers["Authorization"] = f"Bearer {self.access_token}"
73
+ return headers
74
+
75
+ def set_access_token(self, token: str):
76
+ """This method sets the access token to be used for the API.
77
+ Args:
78
+ token (str): access token to be used for the API
79
+ """
80
+ self.access_token = token
81
+
82
+ def check_auth(self):
83
+ """
84
+ Check API access to user account
85
+ """
86
+ url = self.url + "/auth/check"
87
+ headers = self._get_headers()
88
+ r = requests.get(url=url, timeout=2, headers=headers)
89
+ if r.status_code != 200:
90
+ self._log_error(url, {}, r)
91
+ return None
92
+ return r.json()
93
+
94
+ def get_list_organizations(self):
95
+ """
96
+ List all organizations
97
+ """
98
+ url = self.url + "/organizations"
99
+ headers = self._get_headers()
100
+ r = requests.get(url=url, timeout=2, headers=headers)
101
+ if r.status_code != 200:
102
+ self._log_error(url, {}, r)
103
+ return None
104
+ return r.json()
105
+
106
+ def check_organization_exists(self, organization_name: str):
107
+ """
108
+ Check if an organization exists
109
+ """
110
+ organizations = self.get_list_organizations()
111
+ if organizations is None:
112
+ return False
113
+ for organization in organizations:
114
+ if organization["name"] == organization_name:
115
+ return organization
116
+ return False
117
+
118
+ def create_organization(self, organization: OrganizationCreate):
119
+ """
120
+ Create an organization
121
+ """
122
+ payload = dataclasses.asdict(organization)
123
+ url = self.url + "/organizations"
124
+ if organization := self.check_organization_exists(organization.name):
125
+ logger.warning(
126
+ f"Organization {organization['name']} already exists. Skipping creation."
127
+ )
128
+ return organization
129
+ else:
130
+ headers = self._get_headers()
131
+ r = requests.post(url=url, json=payload, timeout=2, headers=headers)
132
+ if r.status_code != 201:
133
+ self._log_error(url, payload, r)
134
+ return None
135
+ return r.json()
136
+
137
+ def get_organization(self, organization_id):
138
+ """
139
+ Get an organization
140
+ """
141
+ headers = self._get_headers()
142
+ url = self.url + "/organizations/" + organization_id
143
+ r = requests.get(url=url, timeout=2, headers=headers)
144
+ if r.status_code != 200:
145
+ self._log_error(url, {}, r)
146
+ return None
147
+ return r.json()
148
+
149
+ def update_organization(self, organization: OrganizationCreate):
150
+ """
151
+ Update an organization
152
+ """
153
+ payload = dataclasses.asdict(organization)
154
+ headers = self._get_headers()
155
+ url = self.url + "/organizations/" + organization.id
156
+ r = requests.patch(url=url, json=payload, timeout=2, headers=headers)
157
+ if r.status_code != 200:
158
+ self._log_error(url, payload, r)
159
+ return None
160
+ return r.json()
161
+
162
+ def list_projects_from_organization(self, organization_id):
163
+ """
164
+ List all projects
165
+ """
166
+ url = self.url + "/organizations/" + organization_id + "/projects"
167
+ headers = self._get_headers()
168
+ r = requests.get(url=url, timeout=2, headers=headers)
169
+ if r.status_code != 200:
170
+ self._log_error(url, {}, r)
171
+ return None
172
+ return r.json()
173
+
174
+ def create_project(self, project: ProjectCreate):
175
+ """
176
+ Create a project
177
+ """
178
+ payload = dataclasses.asdict(project)
179
+ url = self.url + "/projects"
180
+ headers = self._get_headers()
181
+ r = requests.post(url=url, json=payload, timeout=2, headers=headers)
182
+ if r.status_code != 201:
183
+ self._log_error(url, payload, r)
184
+ return None
185
+ return r.json()
186
+
187
+ def get_project(self, project_id):
188
+ """
189
+ Get a project
190
+ """
191
+ url = self.url + "/projects/" + project_id
192
+ headers = self._get_headers()
193
+ r = requests.get(url=url, timeout=2, headers=headers)
194
+ if r.status_code != 200:
195
+ self._log_error(url, {}, r)
196
+ return None
197
+ return r.json()
198
+
199
+ def add_emission(self, carbon_emission: dict):
200
+ assert self.experiment_id is not None
201
+ if self.run_id is None:
202
+ logger.warning(
203
+ "ApiClient.add_emission() need a run_id : the initial call may "
204
+ + "have failed. Retrying..."
205
+ )
206
+ self._create_run(self.experiment_id)
207
+ if self.run_id is None:
208
+ logger.error(
209
+ "ApiClient.add_emission still no run_id, aborting for this time !"
210
+ )
211
+ return False
212
+ if carbon_emission["duration"] < 1:
213
+ logger.warning(
214
+ "ApiClient : emissions not sent because of a duration smaller than 1."
215
+ )
216
+ return False
217
+ emission = EmissionCreate(
218
+ timestamp=get_datetime_with_timezone(),
219
+ run_id=self.run_id,
220
+ duration=int(carbon_emission["duration"]),
221
+ emissions_sum=carbon_emission["emissions"],
222
+ emissions_rate=carbon_emission["emissions_rate"],
223
+ cpu_power=carbon_emission["cpu_power"],
224
+ gpu_power=carbon_emission["gpu_power"],
225
+ ram_power=carbon_emission["ram_power"],
226
+ cpu_energy=carbon_emission["cpu_energy"],
227
+ gpu_energy=carbon_emission["gpu_energy"],
228
+ ram_energy=carbon_emission["ram_energy"],
229
+ energy_consumed=carbon_emission["energy_consumed"],
230
+ )
231
+ try:
232
+ payload = dataclasses.asdict(emission)
233
+ url = self.url + "/emissions"
234
+ headers = self._get_headers()
235
+ r = requests.post(url=url, json=payload, timeout=2, headers=headers)
236
+ if r.status_code != 201:
237
+ self._log_error(url, payload, r)
238
+ return False
239
+ logger.debug(f"ApiClient - Successful upload emission {payload} to {url}")
240
+ except Exception as e:
241
+ logger.error(e, exc_info=True)
242
+ return False
243
+ return True
244
+
245
+ def _create_run(self, experiment_id: str):
246
+ """
247
+ Create the experiment for project_id
248
+ """
249
+ if self.experiment_id is None:
250
+ # TODO : raise an Exception ?
251
+ logger.error(
252
+ "ApiClient FATAL The ApiClient._create_run() needs an experiment_id !"
253
+ )
254
+ return None
255
+ try:
256
+ run = RunCreate(
257
+ timestamp=get_datetime_with_timezone(),
258
+ experiment_id=experiment_id,
259
+ os=self.conf.get("os"),
260
+ python_version=self.conf.get("python_version"),
261
+ codecarbon_version=self.conf.get("codecarbon_version"),
262
+ cpu_count=self.conf.get("cpu_count"),
263
+ cpu_model=self.conf.get("cpu_model"),
264
+ gpu_count=self.conf.get("gpu_count"),
265
+ gpu_model=self.conf.get("gpu_model"),
266
+ # Reduce precision for Privacy
267
+ longitude=round(self.conf.get("longitude", 0), 1),
268
+ latitude=round(self.conf.get("latitude", 0), 1),
269
+ region=self.conf.get("region"),
270
+ provider=self.conf.get("provider"),
271
+ ram_total_size=self.conf.get("ram_total_size"),
272
+ tracking_mode=self.conf.get("tracking_mode"),
273
+ )
274
+ payload = dataclasses.asdict(run)
275
+ url = self.url + "/runs"
276
+ headers = self._get_headers()
277
+ r = requests.post(url=url, json=payload, timeout=2, headers=headers)
278
+ if r.status_code != 201:
279
+ self._log_error(url, payload, r)
280
+ return None
281
+ self.run_id = r.json()["id"]
282
+ logger.info(
283
+ "ApiClient Successfully registered your run on the API.\n\n"
284
+ + f"Run ID: {self.run_id}\n"
285
+ + f"Experiment ID: {self.experiment_id}\n"
286
+ )
287
+ return self.run_id
288
+ except requests.exceptions.ConnectionError as e:
289
+ logger.error(
290
+ f"Failed to connect to API, please check the configuration. {e}",
291
+ exc_info=False,
292
+ )
293
+ except Exception as e:
294
+ logger.error(e, exc_info=True)
295
+
296
+ def list_experiments_from_project(self, project_id: str):
297
+ """
298
+ List all experiments for a project
299
+ """
300
+ url = self.url + "/projects/" + project_id + "/experiments"
301
+ headers = self._get_headers()
302
+ r = requests.get(url=url, timeout=2, headers=headers)
303
+ if r.status_code != 200:
304
+ self._log_error(url, {}, r)
305
+ return []
306
+ return r.json()
307
+
308
+ def set_experiment(self, experiment_id: str):
309
+ """
310
+ Set the experiment id
311
+ """
312
+ self.experiment_id = experiment_id
313
+
314
+ def add_experiment(self, experiment: ExperimentCreate):
315
+ """
316
+ Create an experiment, used by the CLI, not the package.
317
+ ::experiment:: The experiment to create.
318
+ """
319
+ payload = dataclasses.asdict(experiment)
320
+ url = self.url + "/experiments"
321
+ headers = self._get_headers()
322
+ r = requests.post(url=url, json=payload, timeout=2, headers=headers)
323
+ if r.status_code != 201:
324
+ self._log_error(url, payload, r)
325
+ return None
326
+ return r.json()
327
+
328
+ def get_experiment(self, experiment_id):
329
+ """
330
+ Get an experiment by id
331
+ """
332
+ url = self.url + "/experiments/" + experiment_id
333
+ headers = self._get_headers()
334
+ r = requests.get(url=url, timeout=2, headers=headers)
335
+ if r.status_code != 200:
336
+ self._log_error(url, {}, r)
337
+ return None
338
+ return r.json()
339
+
340
+ def _log_error(self, url, payload, response):
341
+ if len(payload) > 0:
342
+ logger.error(
343
+ f"ApiClient Error when calling the API on {url} with : {json.dumps(payload)}"
344
+ )
345
+ else:
346
+ logger.error(f"ApiClient Error when calling the API on {url}")
347
+ logger.error(
348
+ f"ApiClient API return http code {response.status_code} and answer : {response.text}"
349
+ )
350
+
351
+ def close_experiment(self):
352
+ """
353
+ Tell the API that the experiment has ended.
354
+ """
355
+
356
+
357
+ class simple_utc(tzinfo):
358
+ def tzname(self, **kwargs):
359
+ return "UTC"
360
+
361
+ def utcoffset(self, dt):
362
+ return timedelta(0)
codecarbon/core/cloud.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Dict, Optional
2
+
3
+ import requests
4
+
5
+ from codecarbon.external.logger import logger
6
+
7
+
8
+ def postprocess_gcp_cloud_metadata(cloud_metadata: Dict[str, Any]) -> Dict[str, Any]:
9
+ # Attributes contains custom metadata and also contains Kubernetes config,
10
+ # startup script and secrets, filter it out
11
+ if "attributes" in cloud_metadata:
12
+ del cloud_metadata["attributes"]
13
+
14
+ return cloud_metadata
15
+
16
+
17
+ CLOUD_METADATA_MAPPING: Dict[str, Dict[str, Any]] = {
18
+ "AWS": {
19
+ "url": "http://169.254.169.254/latest/dynamic/instance-identity/document",
20
+ "headers": {},
21
+ },
22
+ "Azure": {
23
+ "url": "http://169.254.169.254/metadata/instance?api-version=2019-08-15",
24
+ "headers": {"Metadata": "true"},
25
+ },
26
+ "GCP": {
27
+ "url": "http://169.254.169.254/computeMetadata/v1/instance/?recursive=true&alt=json", # noqa: E501
28
+ "headers": {"Metadata-Flavor": "Google"},
29
+ "postprocess_function": postprocess_gcp_cloud_metadata,
30
+ },
31
+ }
32
+
33
+
34
+ def get_env_cloud_details(timeout: int = 1) -> Optional[Any]:
35
+ """
36
+ >>> get_env_cloud_details()
37
+ {'provider': 'AWS',
38
+ 'metadata': {'accountId': '26550917306',
39
+ 'architecture': 'x86_64',
40
+ 'availabilityZone': 'us-east-1b',
41
+ 'billingProducts': None,
42
+ 'devpayProductCodes': None,
43
+ 'marketplaceProductCodes': None,
44
+ 'imageId': 'ami-025ed45832b817a35',
45
+ 'instanceId': 'i-7c3e81fed58d8f7f7',
46
+ 'instanceType': 'g4dn.2xlarge',
47
+ 'kernelId': None,
48
+ 'pendingTime': '2020-01-23T20:44:53Z',
49
+ 'privateIp': '172.156.72.143',
50
+ 'ramdiskId': None,
51
+ 'region': 'us-east-1',
52
+ 'version': '2017-09-30'}}
53
+ """
54
+ for provider in CLOUD_METADATA_MAPPING.keys():
55
+ try:
56
+ params = CLOUD_METADATA_MAPPING[provider]
57
+ response = requests.get(
58
+ params["url"], headers=params["headers"], timeout=timeout
59
+ )
60
+ response.raise_for_status()
61
+ response_data = response.json()
62
+
63
+ postprocess_function = params.get("postprocess_function")
64
+ if postprocess_function is not None:
65
+ response_data = postprocess_function(response_data)
66
+
67
+ return {"provider": provider, "metadata": response_data}
68
+ except requests.exceptions.RequestException:
69
+ logger.debug("Not running on %s", provider)
70
+
71
+ return None
codecarbon/core/co2_signal.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Dict
2
+
3
+ import requests
4
+
5
+ from codecarbon.core.units import EmissionsPerKWh, Energy
6
+ from codecarbon.external.geography import GeoMetadata
7
+
8
+ URL: str = "https://api.co2signal.com/v1/latest"
9
+ CO2_SIGNAL_API_TIMEOUT: int = 30
10
+
11
+
12
+ def get_emissions(
13
+ energy: Energy, geo: GeoMetadata, co2_signal_api_token: str = ""
14
+ ) -> float:
15
+ """
16
+ Calculate the CO2 emissions based on energy consumption and geographic location.
17
+
18
+ This function retrieves the carbon intensity (in grams of CO2 per kWh) from the CO2
19
+ Signal API based on the geographic location provided. It then calculates the total
20
+ CO2 emissions for a given amount of energy consumption.
21
+
22
+ Args:
23
+ energy (Energy):
24
+ An object representing the energy consumption in kilowatt-hours (kWh).
25
+ geo (GeoMetadata):
26
+ Geographic metadata, including either latitude/longitude
27
+ or a country code.
28
+ co2_signal_api_token (str, optional):
29
+ The API token for authenticating with the CO2 Signal API (default is an empty string).
30
+
31
+ Returns:
32
+ float:
33
+ The total CO2 emissions in kilograms based on the provided energy consumption and
34
+ carbon intensity of the specified geographic location.
35
+
36
+ Raises:
37
+ CO2SignalAPIError:
38
+ If the CO2 Signal API request fails or returns an error.
39
+ """
40
+ params: Dict[str, Any]
41
+ if geo.latitude:
42
+ params = {"lat": geo.latitude, "lon": geo.longitude}
43
+ else:
44
+ params = {"countryCode": geo.country_2letter_iso_code}
45
+ resp = requests.get(
46
+ URL,
47
+ params=params,
48
+ headers={"auth-token": co2_signal_api_token},
49
+ timeout=CO2_SIGNAL_API_TIMEOUT,
50
+ )
51
+ if resp.status_code != 200:
52
+ message = resp.json().get("error") or resp.json().get("message")
53
+ raise CO2SignalAPIError(message)
54
+ carbon_intensity_g_per_kWh = resp.json()["data"]["carbonIntensity"]
55
+ emissions_per_kWh: EmissionsPerKWh = EmissionsPerKWh.from_g_per_kWh(
56
+ carbon_intensity_g_per_kWh
57
+ )
58
+ return emissions_per_kWh.kgs_per_kWh * energy.kWh
59
+
60
+
61
+ class CO2SignalAPIError(Exception):
62
+ pass
codecarbon/core/config.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import configparser
2
+ import os
3
+ from pathlib import Path
4
+ from typing import List
5
+
6
+ from codecarbon.external.logger import logger
7
+
8
+
9
+ def clean_env_key(k: str) -> str:
10
+ """
11
+ Clean up an environment variable key: remove starting
12
+ CODECARBON_ and to lower case.
13
+
14
+ eg: "CODECARBON_PROJECT_NAME" -> "project_name"
15
+
16
+ Args:
17
+ k (str): Environment variable key
18
+
19
+ Returns:
20
+ str: Cleaned str
21
+ """
22
+ assert isinstance(k, str)
23
+ return k.lower().replace("codecarbon_", "", 1)
24
+
25
+
26
+ def parse_env_config() -> dict:
27
+ """
28
+ Get all environment variables starting with "CODECARBON_" (also in lower caps)
29
+ mapped to their values in a dict
30
+
31
+ eg:
32
+ * "CODECARBON_PROJECT_NAME=DeepLearning" -> {"project_name": "DeepLearning"}
33
+ * "codecarbon_project_name=DeepLearning" -> {"project_name": "DeepLearning"}
34
+
35
+ Returns:
36
+ dict: existing relevant environment variables mapped into a dict
37
+ """
38
+ return {
39
+ "codecarbon": {
40
+ clean_env_key(k): v
41
+ for k, v in os.environ.items()
42
+ if k.lower().startswith("codecarbon_")
43
+ }
44
+ }
45
+
46
+
47
+ def parse_gpu_ids(gpu_ids_str: str) -> List[int]:
48
+ """
49
+ Transforms the potential gpu_ids string into a list of int values
50
+
51
+ Args:
52
+ gpu_ids_str (str): The config file or environment variable value for `gpu_ids`
53
+ which is read as a string and should be parsed into a list of ints
54
+
55
+ Returns:
56
+ list[int]: The list of GPU ids available declared by the user.
57
+ Potentially empty.
58
+ """
59
+ if not isinstance(gpu_ids_str, str):
60
+ return gpu_ids_str
61
+
62
+ gpu_ids_str = "".join(c for c in gpu_ids_str if (c.isalnum() or c == ","))
63
+ str_ids = [gpu_id for gpu_id in gpu_ids_str.split(",") if gpu_id]
64
+ return list(map(int, str_ids))
65
+
66
+
67
+ def get_hierarchical_config():
68
+ """
69
+ Get the user-defined codecarbon configuration ConfigParser dictionnary
70
+ (actually a configparser.SectionProxy instance).
71
+
72
+ ```
73
+ >>> from codecarbon.core.config import get_hierarchical_config
74
+ >>> conf = get_hierarchical_config()
75
+ >>> print(conf)
76
+ ```
77
+
78
+ `conf` works like a regular dict + methods getint(key) getfloat(key)
79
+ and getboolean(key) to automatically parse strings into those types.
80
+
81
+ All values (outputs of get(key)) are strings.
82
+
83
+ It looks for, and reads, a config file .codecarbon.config in the user's $HOME.
84
+ It then looks for, reads, and updates the previous configuration from a config
85
+ file .codecarbon.config in the current working directory (Path.cwd()).
86
+ Finally it updates the resulting config from any environment variable starting
87
+ with `CODECARBON_` (for instance if `CODECARBON_PROJECT_NAME` is `your-project`
88
+ then the resulting configuration key `project_name` will have value `your-project`)
89
+
90
+ Returns:
91
+ dict: The final configuration dict parsed from global,
92
+ local and environment configurations. **All values are strings**.
93
+ """
94
+
95
+ config = configparser.ConfigParser()
96
+
97
+ cwd = Path.cwd()
98
+ home = Path.home()
99
+ global_path = str((home / ".codecarbon.config").expanduser().resolve())
100
+ local_path = str((cwd / ".codecarbon.config").expanduser().resolve())
101
+ if Path(global_path).exists():
102
+ logger.info(
103
+ f"Codecarbon is taking the configuration from global file: {global_path}"
104
+ )
105
+ if Path(local_path).exists():
106
+ logger.info(f"Some variables are overriden by the local file: {local_path}")
107
+ elif Path(local_path).exists():
108
+ logger.info(
109
+ f"Codecarbon is taking the configuration from the local file {local_path}"
110
+ )
111
+
112
+ config.read([global_path, local_path])
113
+ config.read_dict(parse_env_config())
114
+
115
+ return dict(config["codecarbon"])
codecarbon/core/cpu.py ADDED
@@ -0,0 +1,521 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Implements tracking Intel CPU Power Consumption on Mac and Windows
3
+ using Intel Power Gadget
4
+ https://software.intel.com/content/www/us/en/develop/articles/intel-power-gadget.html
5
+ """
6
+
7
+ import os
8
+ import re
9
+ import shutil
10
+ import subprocess
11
+ import sys
12
+ from typing import Dict, Optional, Tuple
13
+
14
+ import pandas as pd
15
+ import psutil
16
+ from rapidfuzz import fuzz, process, utils
17
+
18
+ from codecarbon.core.rapl import RAPLFile
19
+ from codecarbon.core.units import Time
20
+ from codecarbon.core.util import detect_cpu_model
21
+ from codecarbon.external.logger import logger
22
+ from codecarbon.input import DataSource
23
+
24
+ # default W value per core for a CPU if no model is found in the ref csv
25
+ DEFAULT_POWER_PER_CORE = 4
26
+
27
+
28
+ def is_powergadget_available() -> bool:
29
+ """
30
+ Checks if Intel Power Gadget is available on the system.
31
+
32
+ Returns:
33
+ bool: `True` if Intel Power Gadget is available, `False` otherwise.
34
+ """
35
+ try:
36
+ IntelPowerGadget()
37
+ return True
38
+ except Exception as e:
39
+ logger.debug(
40
+ "Not using PowerGadget, an exception occurred while instantiating "
41
+ + "IntelPowerGadget : %s",
42
+ e,
43
+ )
44
+ return False
45
+
46
+
47
+ def is_rapl_available() -> bool:
48
+ """
49
+ Checks if Intel RAPL is available on the system.
50
+
51
+ Returns:
52
+ bool: `True` if Intel RAPL is available, `False` otherwise.
53
+ """
54
+ try:
55
+ IntelRAPL()
56
+ return True
57
+ except Exception as e:
58
+ logger.debug(
59
+ "Not using the RAPL interface, an exception occurred while instantiating "
60
+ + "IntelRAPL : %s",
61
+ e,
62
+ )
63
+ return False
64
+
65
+
66
+ def is_psutil_available():
67
+ try:
68
+ nice = psutil.cpu_times().nice
69
+ if nice > 0.0001:
70
+ return True
71
+ else:
72
+ logger.debug(
73
+ f"is_psutil_available() : psutil.cpu_times().nice is too small : {nice} !"
74
+ )
75
+ return False
76
+ except Exception as e:
77
+ logger.debug(
78
+ "Not using the psutil interface, an exception occurred while instantiating "
79
+ + f"psutil.cpu_times : {e}",
80
+ )
81
+ return False
82
+
83
+
84
+ class IntelPowerGadget:
85
+ """
86
+ A class to interface with Intel Power Gadget for monitoring CPU power consumption on Windows and (non-Apple Silicon) macOS.
87
+
88
+ This class provides methods to set up and execute Intel Power Gadget's command-line interface (CLI) to
89
+ log power consumption data over a specified duration and resolution. It also includes functionality to
90
+ read and process the logged data to extract CPU power details.
91
+
92
+ Methods:
93
+ start():
94
+ Placeholder method for starting the Intel Power Gadget monitoring.
95
+
96
+ get_cpu_details() -> Dict:
97
+ Fetches the CPU power details by reading the values from the logged CSV file.
98
+
99
+ """
100
+
101
+ _osx_exec = "PowerLog"
102
+ _osx_exec_backup = "/Applications/Intel Power Gadget/PowerLog"
103
+ _windows_exec = "PowerLog3.0.exe"
104
+
105
+ def __init__(
106
+ self,
107
+ output_dir: str = ".",
108
+ duration=1,
109
+ resolution=100,
110
+ log_file_name="intel_power_gadget_log.csv",
111
+ ):
112
+ self._log_file_path = os.path.join(output_dir, log_file_name)
113
+ self._system = sys.platform.lower()
114
+ self._duration = duration
115
+ self._resolution = resolution
116
+ self._windows_exec_backup = None
117
+ self._setup_cli()
118
+
119
+ def _setup_cli(self) -> None:
120
+ """
121
+ Setup cli command to run Intel Power Gadget
122
+ """
123
+ if self._system.startswith("win"):
124
+ self._get_windows_exec_backup()
125
+ if shutil.which(self._windows_exec):
126
+ self._cli = shutil.which(
127
+ self._windows_exec
128
+ ) # Windows exec is a relative path
129
+ elif shutil.which(self._windows_exec_backup):
130
+ self._cli = self._windows_exec_backup
131
+ else:
132
+ raise FileNotFoundError(
133
+ f"Intel Power Gadget executable not found on {self._system}"
134
+ )
135
+ elif self._system.startswith("darwin"):
136
+ if shutil.which(self._osx_exec):
137
+ self._cli = self._osx_exec
138
+ elif shutil.which(self._osx_exec_backup):
139
+ self._cli = self._osx_exec_backup
140
+ else:
141
+ raise FileNotFoundError(
142
+ f"Intel Power Gadget executable not found on {self._system}"
143
+ )
144
+ else:
145
+ raise SystemError("Platform not supported by Intel Power Gadget")
146
+
147
+ def _get_windows_exec_backup(self) -> None:
148
+ """
149
+ Find the windows executable for the current version of intel power gadget.
150
+ Example: "C:\\Program Files\\Intel\\Power Gadget 3.5\\PowerLog3.0.exe"
151
+ """
152
+ parent_folder = "C:\\Program Files\\Intel\\"
153
+
154
+ # Get a list of all subdirectories in the parent folder
155
+ subfolders = [f.name for f in os.scandir(parent_folder) if f.is_dir()]
156
+
157
+ # Look for a folder that contains "Power Gadget" in its name
158
+ desired_folder = next(
159
+ (folder for folder in subfolders if "Power Gadget" in folder), None
160
+ )
161
+ if desired_folder:
162
+ self._windows_exec_backup = os.path.join(
163
+ parent_folder, desired_folder, self._windows_exec
164
+ )
165
+ else:
166
+ self._windows_exec_backup = None
167
+
168
+ def _log_values(self) -> None:
169
+ """
170
+ Logs output from Intel Power Gadget command line to a file
171
+ """
172
+ returncode = None
173
+ if self._system.startswith("win"):
174
+ returncode = subprocess.call(
175
+ [
176
+ self._cli,
177
+ "-duration",
178
+ str(self._duration),
179
+ "-resolution",
180
+ str(self._resolution),
181
+ "-file",
182
+ self._log_file_path,
183
+ ],
184
+ shell=True,
185
+ stdout=subprocess.PIPE,
186
+ stderr=subprocess.PIPE,
187
+ )
188
+ elif self._system.startswith("darwin"):
189
+ returncode = subprocess.call(
190
+ f"'{self._cli}' -duration {self._duration} -resolution {self._resolution} -file {self._log_file_path} > /dev/null", # noqa: E501
191
+ shell=True,
192
+ )
193
+ else:
194
+ return None
195
+
196
+ if returncode != 0:
197
+ logger.warning(
198
+ "Returncode while logging power values using "
199
+ + "Intel Power Gadget: %s",
200
+ returncode,
201
+ )
202
+
203
+ def get_cpu_details(self) -> Dict:
204
+ """
205
+ Fetches the CPU Power Details by fetching values from a logged csv file
206
+ in _log_values function
207
+ """
208
+ self._log_values()
209
+ cpu_details = {}
210
+ try:
211
+ cpu_data = pd.read_csv(self._log_file_path).dropna()
212
+ for col_name in cpu_data.columns:
213
+ if col_name in ["System Time", "Elapsed Time (sec)", "RDTSC"]:
214
+ continue
215
+ if "Cumulative" in col_name:
216
+ cpu_details[col_name] = cpu_data[col_name].iloc[-1]
217
+ else:
218
+ cpu_details[col_name] = cpu_data[col_name].mean()
219
+ except Exception as e:
220
+ logger.info(
221
+ f"Unable to read Intel Power Gadget logged file at {self._log_file_path}\n \
222
+ Exception occurred %s",
223
+ e,
224
+ exc_info=True,
225
+ )
226
+ return cpu_details
227
+
228
+ def start(self) -> None:
229
+ """
230
+ Placeholder method for starting the Intel Power Gadget monitoring.
231
+ """
232
+ # TODO: Read energy
233
+
234
+
235
+ class IntelRAPL:
236
+ """
237
+ A class to interface Intel's Running Average Power Limit (RAPL) for monitoring CPU power consumption.
238
+
239
+ This class provides methods to set up and read energy consumption data from Intel RAPL files,
240
+ which are available on Linux systems.
241
+ It enables the measurement of CPU energy usage over time and provides methods to fetch
242
+ both dynamic and static CPU energy details.
243
+
244
+ Attributes:
245
+ _lin_rapl_dir (str): The directory path where Intel RAPL files are located.
246
+ _system (str): The platform of the running system, typically used to ensure compatibility.
247
+ _rapl_files (List[RAPLFile]): A list of RAPLFile objects representing the files to read energy data from.
248
+ _cpu_details (Dict): A dictionary storing the latest CPU energy details.
249
+ _last_mesure (int): Placeholder for storing the last measurement time.
250
+
251
+ Methods:
252
+ start():
253
+ Starts monitoring CPU energy consumption.
254
+
255
+ get_cpu_details(duration: Time) -> Dict:
256
+ Fetches the CPU energy deltas over a specified duration by reading values from RAPL files.
257
+
258
+ get_static_cpu_details() -> Dict:
259
+ Returns the CPU details without recalculating them.
260
+
261
+ """
262
+
263
+ def __init__(self, rapl_dir="/sys/class/powercap/intel-rapl/subsystem"):
264
+ self._lin_rapl_dir = rapl_dir
265
+ self._system = sys.platform.lower()
266
+ self._rapl_files = []
267
+ self._setup_rapl()
268
+ self._cpu_details: Dict = {}
269
+
270
+ self._last_mesure = 0
271
+
272
+ def _is_platform_supported(self) -> bool:
273
+ return self._system.startswith("lin")
274
+
275
+ def _setup_rapl(self) -> None:
276
+ if self._is_platform_supported():
277
+ if os.path.exists(self._lin_rapl_dir):
278
+ self._fetch_rapl_files()
279
+ else:
280
+ raise FileNotFoundError(
281
+ f"Intel RAPL files not found at {self._lin_rapl_dir} "
282
+ + f"on {self._system}"
283
+ )
284
+ else:
285
+ raise SystemError("Platform not supported by Intel RAPL Interface")
286
+
287
+ def _fetch_rapl_files(self) -> None:
288
+ """
289
+ Fetches RAPL files from the RAPL directory
290
+ """
291
+
292
+ # consider files like `intel-rapl:$i`
293
+ files = list(filter(lambda x: ":" in x, os.listdir(self._lin_rapl_dir)))
294
+
295
+ i = 0
296
+ for file in files:
297
+ path = os.path.join(self._lin_rapl_dir, file, "name")
298
+ with open(path) as f:
299
+ name = f.read().strip()
300
+ # Fake the name used by Power Gadget
301
+ # We ignore "core" in name as it seems to be included in "package" for Intel CPU.
302
+ # TODO: Use "dram" for memory power
303
+ if "package" in name:
304
+ name = f"Processor Energy Delta_{i}(kWh)"
305
+ i += 1
306
+ # RAPL file to take measurement from
307
+ rapl_file = os.path.join(self._lin_rapl_dir, file, "energy_uj")
308
+ # RAPL file containing maximum possible value of energy_uj above which it wraps
309
+ rapl_file_max = os.path.join(
310
+ self._lin_rapl_dir, file, "max_energy_range_uj"
311
+ )
312
+ try:
313
+ # Try to read the file to be sure we can
314
+ with open(rapl_file, "r") as f:
315
+ _ = float(f.read())
316
+ self._rapl_files.append(
317
+ RAPLFile(name=name, path=rapl_file, max_path=rapl_file_max)
318
+ )
319
+ logger.debug("We will read Intel RAPL files at %s", rapl_file)
320
+ except PermissionError as e:
321
+ raise PermissionError(
322
+ "PermissionError : Unable to read Intel RAPL files for CPU power, we will use a constant for your CPU power."
323
+ + " Please view https://github.com/mlco2/codecarbon/issues/244"
324
+ + " for workarounds : %s",
325
+ e,
326
+ ) from e
327
+
328
+ def get_cpu_details(self, duration: Time) -> Dict:
329
+ """
330
+ Fetches the CPU Energy Deltas by fetching values from RAPL files
331
+ """
332
+ cpu_details = {}
333
+ try:
334
+ list(map(lambda rapl_file: rapl_file.delta(duration), self._rapl_files))
335
+
336
+ for rapl_file in self._rapl_files:
337
+ logger.debug(rapl_file)
338
+ cpu_details[rapl_file.name] = rapl_file.energy_delta.kWh
339
+ # We fake the name used by Power Gadget when using RAPL
340
+ if "Energy" in rapl_file.name:
341
+ cpu_details[rapl_file.name.replace("Energy", "Power")] = (
342
+ rapl_file.power.W
343
+ )
344
+ except Exception as e:
345
+ logger.info(
346
+ "Unable to read Intel RAPL files at %s\n \
347
+ Exception occurred %s",
348
+ self._rapl_files,
349
+ e,
350
+ exc_info=True,
351
+ )
352
+ self._cpu_details = cpu_details
353
+ logger.debug("get_cpu_details %s", self._cpu_details)
354
+ return cpu_details
355
+
356
+ def get_static_cpu_details(self) -> Dict:
357
+ """
358
+ Return CPU details without computing them.
359
+ """
360
+ return self._cpu_details
361
+
362
+ def start(self) -> None:
363
+ """
364
+ Starts monitoring CPU energy consumption.
365
+ """
366
+ for rapl_file in self._rapl_files:
367
+ rapl_file.start()
368
+
369
+
370
+ class TDP:
371
+ """
372
+ Represents Thermal Design Power (TDP) for detecting and estimating
373
+ the power consumption of the CPU on a machine.
374
+
375
+ The class provides methods to identify the CPU model, match it with known TDP
376
+ values from a dataset, and return the corresponding power consumption in watts.
377
+
378
+ Attributes:
379
+ model (str): The detected CPU model name.
380
+ tdp (int): The TDP value of the detected CPU in watts.
381
+
382
+ Methods:
383
+ start():
384
+ Placeholder method to initiate TDP analysis.
385
+
386
+ """
387
+
388
+ def __init__(self):
389
+ self.model, self.tdp = self._main()
390
+
391
+ @staticmethod
392
+ def _get_cpu_constant_power(match: str, cpu_power_df: pd.DataFrame) -> int:
393
+ """Extract constant power from matched CPU"""
394
+ return float(cpu_power_df[cpu_power_df["Name"] == match]["TDP"].values[0])
395
+
396
+ def _get_cpu_power_from_registry(self, cpu_model_raw: str) -> Optional[int]:
397
+ cpu_power_df = DataSource().get_cpu_power_data()
398
+ cpu_matching = self._get_matching_cpu(cpu_model_raw, cpu_power_df)
399
+ if cpu_matching:
400
+ power = self._get_cpu_constant_power(cpu_matching, cpu_power_df)
401
+ return power
402
+ return None
403
+
404
+ def _get_matching_cpu(
405
+ self, model_raw: str, cpu_df: pd.DataFrame, greedy=False
406
+ ) -> str:
407
+ """
408
+ Get matching cpu name
409
+
410
+ :args:
411
+ model_raw (str): raw name of the cpu model detected on the machine
412
+
413
+ cpu_df (DataFrame): table containing cpu models along their tdp
414
+
415
+ greedy (default False): if multiple cpu models match with an equal
416
+ ratio of similarity, greedy (True) selects the first model,
417
+ following the order of the cpu list provided, while non-greedy
418
+ returns None.
419
+
420
+ :return: name of the matching cpu model
421
+
422
+ :notes:
423
+ Thanks to the greedy mode, even though the match could be a model
424
+ with a tdp very different from the actual tdp of current cpu, it
425
+ still enables the relative comparison of models emissions running
426
+ on the same machine.
427
+
428
+ THRESHOLD_DIRECT defines the similarity ratio value to consider
429
+ almost-exact matches.
430
+
431
+ THRESHOLD_TOKEN_SET defines the similarity ratio value to consider
432
+ token_set matches (for more detail see fuzz.token_set_ratio).
433
+ """
434
+ THRESHOLD_DIRECT: int = 100
435
+ THRESHOLD_TOKEN_SET: int = 100
436
+
437
+ direct_match = process.extractOne(
438
+ model_raw,
439
+ cpu_df["Name"],
440
+ processor=lambda s: s.lower(),
441
+ scorer=fuzz.ratio,
442
+ score_cutoff=THRESHOLD_DIRECT,
443
+ )
444
+
445
+ if direct_match:
446
+ return direct_match[0]
447
+
448
+ model_raw = model_raw.replace("(R)", "")
449
+ start_cpu = model_raw.find(" CPU @ ")
450
+ if start_cpu > 0:
451
+ model_raw = model_raw[0:start_cpu]
452
+ model_raw = model_raw.replace(" CPU", "")
453
+ model_raw = re.sub(r" @\s*\d+\.\d+GHz", "", model_raw)
454
+ direct_match = process.extractOne(
455
+ model_raw,
456
+ cpu_df["Name"],
457
+ processor=lambda s: s.lower(),
458
+ scorer=fuzz.ratio,
459
+ score_cutoff=THRESHOLD_DIRECT,
460
+ )
461
+
462
+ if direct_match:
463
+ return direct_match[0]
464
+ indirect_matches = process.extract(
465
+ model_raw,
466
+ cpu_df["Name"],
467
+ processor=utils.default_process,
468
+ scorer=fuzz.token_set_ratio,
469
+ score_cutoff=THRESHOLD_TOKEN_SET,
470
+ )
471
+
472
+ if indirect_matches:
473
+ if (
474
+ greedy
475
+ or len(indirect_matches) == 1
476
+ or indirect_matches[0][1] != indirect_matches[1][1]
477
+ ):
478
+ return indirect_matches[0][0]
479
+
480
+ return None
481
+
482
+ def _main(self) -> Tuple[str, int]:
483
+ """
484
+ Get CPU power from constant mode
485
+
486
+ :return: model name (str), power in Watt (int)
487
+ """
488
+ cpu_model_detected = detect_cpu_model()
489
+
490
+ if cpu_model_detected:
491
+ power = self._get_cpu_power_from_registry(cpu_model_detected)
492
+
493
+ if power:
494
+ logger.debug(
495
+ "CPU : We detect a %s with a TDP of %s W",
496
+ cpu_model_detected,
497
+ power,
498
+ )
499
+ return cpu_model_detected, power
500
+ logger.warning(
501
+ "We saw that you have a %s but we don't know it."
502
+ + " Please contact us.",
503
+ cpu_model_detected,
504
+ )
505
+ if is_psutil_available():
506
+ # Count thread of the CPU
507
+ threads = psutil.cpu_count(logical=True)
508
+ estimated_tdp = threads * DEFAULT_POWER_PER_CORE
509
+ logger.warning(
510
+ f"We will use the default power consumption of {DEFAULT_POWER_PER_CORE} W per thread for your {threads} CPU, so {estimated_tdp}W."
511
+ )
512
+ return cpu_model_detected, estimated_tdp
513
+ return cpu_model_detected, None
514
+ logger.warning(
515
+ "We were unable to detect your CPU using the `cpuinfo` package."
516
+ + " Resorting to a default power consumption."
517
+ )
518
+ return "Unknown", None
519
+
520
+ def start(self):
521
+ pass
codecarbon/core/emissions.py ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Provides functionality to compute emissions for cloud & private infra
3
+ based on impact & energy Usage package
4
+
5
+ https://github.com/mlco2/impact
6
+ https://github.com/responsibleproblemsolving/energy-usage
7
+ """
8
+
9
+ from typing import Dict, Optional
10
+
11
+ import pandas as pd
12
+
13
+ from codecarbon.core import co2_signal
14
+ from codecarbon.core.units import EmissionsPerKWh, Energy
15
+ from codecarbon.external.geography import CloudMetadata, GeoMetadata
16
+ from codecarbon.external.logger import logger
17
+ from codecarbon.input import DataSource, DataSourceException
18
+
19
+
20
+ class Emissions:
21
+ def __init__(
22
+ self, data_source: DataSource, co2_signal_api_token: Optional[str] = None
23
+ ):
24
+ self._data_source = data_source
25
+ self._co2_signal_api_token = co2_signal_api_token
26
+
27
+ def get_cloud_emissions(
28
+ self, energy: Energy, cloud: CloudMetadata, geo: GeoMetadata = None
29
+ ) -> float:
30
+ """
31
+ Computes emissions for cloud infra
32
+ :param energy: Mean power consumption of the process (kWh)
33
+ :param cloud: Region of compute
34
+ :param geo: Instance of GeoMetadata to fallback if we don't find cloud carbon intensity
35
+ :return: CO2 emissions in kg
36
+ """
37
+
38
+ df: pd.DataFrame = self._data_source.get_cloud_emissions_data()
39
+ try:
40
+ emissions_per_kWh: EmissionsPerKWh = EmissionsPerKWh.from_g_per_kWh(
41
+ df.loc[
42
+ (df["provider"] == cloud.provider) & (df["region"] == cloud.region)
43
+ ]["impact"].item()
44
+ )
45
+ emissions = emissions_per_kWh.kgs_per_kWh * energy.kWh # kgs
46
+ except Exception as e:
47
+ logger.warning(
48
+ f"Cloud electricity carbon intensity for provider '{cloud.provider}' and region '{cloud.region}' not found, using country value instead. Error : {e}"
49
+ )
50
+ logger.warning(
51
+ "AWS and Azure do not provide any carbon intensity data. Only GCP does it."
52
+ )
53
+ if geo:
54
+ emissions = self.get_private_infra_emissions(
55
+ energy, geo
56
+ ) # float: kg co2_eq
57
+ else:
58
+ carbon_intensity_per_source = (
59
+ DataSource().get_carbon_intensity_per_source_data()
60
+ )
61
+ emissions = (
62
+ EmissionsPerKWh.from_g_per_kWh(
63
+ carbon_intensity_per_source.get("world_average")
64
+ ).kgs_per_kWh
65
+ * energy.kWh
66
+ ) # kgs
67
+ return emissions
68
+
69
+ def get_cloud_country_name(self, cloud: CloudMetadata) -> str:
70
+ """
71
+ Returns the Country Name where the cloud region is located
72
+ """
73
+ df: pd.DataFrame = self._data_source.get_cloud_emissions_data()
74
+ flags = (df["provider"] == cloud.provider) & (df["region"] == cloud.region)
75
+ selected = df.loc[flags]
76
+ if not len(selected):
77
+ raise ValueError(
78
+ "Unable to find country name for "
79
+ f"cloud_provider={cloud.provider}, "
80
+ f"cloud_region={cloud.region}"
81
+ )
82
+ return selected["country_name"].item()
83
+
84
+ def get_cloud_country_iso_code(self, cloud: CloudMetadata) -> str:
85
+ """
86
+ Returns the Country ISO Code where the cloud region is located
87
+ """
88
+ df: pd.DataFrame = self._data_source.get_cloud_emissions_data()
89
+ flags = (df["provider"] == cloud.provider) & (df["region"] == cloud.region)
90
+ selected = df.loc[flags]
91
+ if not len(selected):
92
+ raise ValueError(
93
+ "Unable to find country ISO Code for "
94
+ f"cloud_provider={cloud.provider}, "
95
+ f"cloud_region={cloud.region}"
96
+ )
97
+ return selected["countryIsoCode"].item()
98
+
99
+ def get_cloud_geo_region(self, cloud: CloudMetadata) -> str:
100
+ """
101
+ Returns the State/City where the cloud region is located
102
+ """
103
+ df: pd.DataFrame = self._data_source.get_cloud_emissions_data()
104
+ flags = (df["provider"] == cloud.provider) & (df["region"] == cloud.region)
105
+ selected = df.loc[flags]
106
+ if not len(selected):
107
+ raise ValueError(
108
+ "Unable to find State/City name for "
109
+ f"cloud_provider={cloud.provider}, "
110
+ f"cloud_region={cloud.region}"
111
+ )
112
+
113
+ state = selected["state"].item()
114
+ if state is not None:
115
+ return state
116
+ city = selected["city"].item()
117
+ return city
118
+
119
+ def get_private_infra_emissions(self, energy: Energy, geo: GeoMetadata) -> float:
120
+ """
121
+ Computes emissions for private infra
122
+ :param energy: Mean power consumption of the process (kWh)
123
+ :param geo: Country and region metadata
124
+ :return: CO2 emissions in kg
125
+ """
126
+ if self._co2_signal_api_token:
127
+ try:
128
+ return co2_signal.get_emissions(energy, geo, self._co2_signal_api_token)
129
+ except Exception as e:
130
+ logger.error(
131
+ "co2_signal.get_emissions: "
132
+ + str(e)
133
+ + " >>> Using CodeCarbon's data."
134
+ )
135
+
136
+ compute_with_regional_data: bool = (geo.region is not None) and (
137
+ geo.country_iso_code.upper() in ["USA", "CAN"]
138
+ )
139
+
140
+ if compute_with_regional_data:
141
+ try:
142
+ return self.get_region_emissions(energy, geo)
143
+ except Exception as e:
144
+ logger.error(e, exc_info=True)
145
+ logger.warning(
146
+ "Regional emissions retrieval failed."
147
+ + " Falling back on country emissions."
148
+ )
149
+ return self.get_country_emissions(energy, geo)
150
+
151
+ def get_region_emissions(self, energy: Energy, geo: GeoMetadata) -> float:
152
+ """
153
+ Computes emissions for a region on private infra.
154
+ Given an quantity of power consumed, use regional data
155
+ on emissions per unit power consumed or the mix of energy sources.
156
+ https://github.com/responsibleproblemsolving/energy-usage#calculating-co2-emissions
157
+ :param energy: Mean power consumption of the process (kWh)
158
+ :param geo: Country and region metadata.
159
+ :return: CO2 emissions in kg
160
+ """
161
+ try:
162
+ country_emissions_data = self._data_source.get_country_emissions_data(
163
+ geo.country_iso_code.lower()
164
+ )
165
+
166
+ if geo.region not in country_emissions_data:
167
+ # TODO: Deal with missing data, default to something
168
+ raise ValueError(
169
+ f"Region: {geo.region} not found for Country"
170
+ + f" with ISO CODE : {geo.country_iso_code}"
171
+ )
172
+
173
+ emissions_per_kWh: EmissionsPerKWh = EmissionsPerKWh.from_lbs_per_mWh(
174
+ country_emissions_data[geo.region]["emissions"]
175
+ )
176
+ except DataSourceException:
177
+ # This country has regional data at the energy mix level,
178
+ # not the emissions level
179
+ country_energy_mix_data = self._data_source.get_country_energy_mix_data(
180
+ geo.country_iso_code.lower()
181
+ )
182
+ region_energy_mix_data = country_energy_mix_data[geo.region]
183
+ emissions_per_kWh = self._region_energy_mix_to_emissions_rate(
184
+ region_energy_mix_data
185
+ )
186
+
187
+ return emissions_per_kWh.kgs_per_kWh * energy.kWh # kgs
188
+
189
+ def get_country_emissions(self, energy: Energy, geo: GeoMetadata) -> float:
190
+ """
191
+ Computes emissions for a country on private infra,
192
+ given a quantity of power consumed by
193
+ using data for the mix of energy sources of that country.
194
+ :param energy: Mean power consumption of the process (kWh)
195
+ :param geo: Country and region metadata
196
+ :return: CO2 emissions in kg
197
+ """
198
+ energy_mix = self._data_source.get_global_energy_mix_data()
199
+
200
+ if geo.country_iso_code not in energy_mix:
201
+ logger.warning(
202
+ f"We do not have data for {geo.country_iso_code}, using world average."
203
+ )
204
+ carbon_intensity_per_source = (
205
+ DataSource().get_carbon_intensity_per_source_data()
206
+ )
207
+ return (
208
+ EmissionsPerKWh.from_g_per_kWh(
209
+ carbon_intensity_per_source.get("world_average")
210
+ ).kgs_per_kWh
211
+ * energy.kWh
212
+ ) # kgs
213
+
214
+ country_energy_mix: Dict = energy_mix[geo.country_iso_code]
215
+ emissions_per_kWh = self._global_energy_mix_to_emissions_rate(
216
+ country_energy_mix
217
+ )
218
+ logger.debug(
219
+ f"We apply an energy mix of {emissions_per_kWh.kgs_per_kWh * 1000:.0f}"
220
+ + f" g.CO2eq/kWh for {geo.country_name}"
221
+ )
222
+
223
+ return emissions_per_kWh.kgs_per_kWh * energy.kWh # kgs
224
+
225
+ @staticmethod
226
+ def _global_energy_mix_to_emissions_rate(energy_mix: Dict) -> EmissionsPerKWh:
227
+ """
228
+ Convert a mix of electricity sources into emissions per kWh.
229
+ :param energy_mix: A dictionary that breaks down the electricity produced into
230
+ energy sources, with a total value. Format will vary, but must have keys for "total_TWh"
231
+ :return: an EmissionsPerKwh object representing the average emissions rate
232
+ in Kgs.CO2 / kWh
233
+ """
234
+ # If we have the chance to have the carbon intensity for this country
235
+ if energy_mix.get("carbon_intensity"):
236
+ return EmissionsPerKWh.from_g_per_kWh(energy_mix.get("carbon_intensity"))
237
+
238
+ # Else we compute it from the energy mix.
239
+ # Read carbon_intensity from the json data file.
240
+ carbon_intensity_per_source = (
241
+ DataSource().get_carbon_intensity_per_source_data()
242
+ )
243
+ carbon_intensity = 0
244
+ energy_sum = energy_mix["total_TWh"]
245
+ energy_sum_computed = 0
246
+ # Iterate through each source of energy in the country
247
+ for energy_type, energy_per_year in energy_mix.items():
248
+ if "_TWh" in energy_type:
249
+ # Compute the carbon intensity ratio of this source for this country
250
+ carbon_intensity_for_type = carbon_intensity_per_source.get(
251
+ energy_type[: -len("_TWh")]
252
+ )
253
+ if carbon_intensity_for_type: # to ignore "total_TWh"
254
+ carbon_intensity += (
255
+ energy_per_year / energy_sum
256
+ ) * carbon_intensity_for_type
257
+ energy_sum_computed += energy_per_year
258
+
259
+ # Sanity check
260
+ if energy_sum_computed != energy_sum:
261
+ logger.error(
262
+ f"We find {energy_sum_computed} TWh instead of {energy_sum} TWh for {energy_mix.get('country_name')}, using world average."
263
+ )
264
+ return EmissionsPerKWh.from_g_per_kWh(
265
+ carbon_intensity_per_source.get("world_average")
266
+ )
267
+
268
+ return EmissionsPerKWh.from_g_per_kWh(carbon_intensity)
269
+
270
+ @staticmethod
271
+ def _region_energy_mix_to_emissions_rate(energy_mix: Dict) -> EmissionsPerKWh:
272
+ """
273
+ Convert a mix of energy sources into emissions per kWh
274
+ https://github.com/responsibleproblemsolving/energy-usage#calculating-co2-emissions
275
+ :param energy_mix: A dictionary that breaks down the energy produced into
276
+ sources, with a total value. Format will vary, but must have keys for "coal"
277
+ "petroleum" and "naturalGas" and "total"
278
+ :return: an EmissionsPerKwh object representing the average emissions rate
279
+ """
280
+ # source:
281
+ # https://github.com/responsibleproblemsolving/energy-usage#conversion-to-co2
282
+ emissions_by_source: Dict[str, EmissionsPerKWh] = {
283
+ "coal": EmissionsPerKWh.from_kgs_per_kWh(0.995725971),
284
+ "petroleum": EmissionsPerKWh.from_kgs_per_kWh(0.8166885263),
285
+ "naturalGas": EmissionsPerKWh.from_kgs_per_kWh(0.7438415916),
286
+ }
287
+ emissions_percentage: Dict[str, float] = {}
288
+ for energy_type in energy_mix.keys():
289
+ if energy_type not in ["total", "isoCode", "country_name"]:
290
+ emissions_percentage[energy_type] = (
291
+ energy_mix[energy_type] / energy_mix["total"]
292
+ )
293
+ # Weighted sum of emissions by % of contributions
294
+ # `emissions_percentage`: coal: 0.5, petroleum: 0.25, naturalGas: 0.25
295
+ # `emission_value`: coal: 0.995725971, petroleum: 0.8166885263, naturalGas: 0.7438415916 # noqa: E501
296
+ # `emissions_per_kWh`: (0.5 * 0.995725971) + (0.25 * 0.8166885263) * (0.25 * 0.7438415916) # noqa: E501
297
+ # >> 0.5358309 kg/kWh
298
+ emissions_per_kWh = EmissionsPerKWh.from_kgs_per_kWh(
299
+ sum(
300
+ [
301
+ emissions_percentage[source]
302
+ * value.kgs_per_kWh # % (0.x) # kgs / kWh
303
+ for source, value in emissions_by_source.items()
304
+ ]
305
+ )
306
+ )
307
+
308
+ return emissions_per_kWh
codecarbon/core/gpu.py ADDED
@@ -0,0 +1,305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass, field
2
+ from typing import Any, Dict, List, Union
3
+
4
+ import pynvml
5
+
6
+ from codecarbon.core.units import Energy, Power, Time
7
+ from codecarbon.external.logger import logger
8
+
9
+
10
+ @dataclass
11
+ class GPUDevice:
12
+ """
13
+ Represents a GPU device with associated energy and power metrics.
14
+
15
+ Attributes:
16
+ handle (any): An identifier for the GPU device.
17
+ gpu_index (int): The index of the GPU device in the system.
18
+ energy_delta (Energy): The amount of energy consumed by the GPU device
19
+ since the last measurement, expressed in kilowatt-hours (kWh).
20
+ Defaults to an initial value of 0 kWh.
21
+ power (Power): The current power consumption of the GPU device,
22
+ measured in watts (W). Defaults to an initial value of 0 W.
23
+ last_energy (Energy): The last recorded energy reading for the GPU
24
+ device, expressed in kilowatt-hours (kWh). This is used to
25
+ calculate `energy_delta`. Defaults to an initial value of 0 kWh.
26
+ """
27
+
28
+ handle: any
29
+ gpu_index: int
30
+ # Energy consumed in kWh
31
+ energy_delta: Energy = field(default_factory=lambda: Energy(0))
32
+ # Power based on reading
33
+ power: Power = field(default_factory=lambda: Power(0))
34
+ # Last energy reading in kWh
35
+ last_energy: Energy = field(default_factory=lambda: Energy(0))
36
+
37
+ def start(self) -> None:
38
+ self.last_energy = self._get_energy_kwh()
39
+
40
+ def __post_init__(self) -> None:
41
+ self.last_energy = self._get_energy_kwh()
42
+ self._init_static_details()
43
+
44
+ def _get_energy_kwh(self) -> Energy:
45
+ total_energy_consumption = self._get_total_energy_consumption()
46
+ if total_energy_consumption is None:
47
+ return self.last_energy
48
+ return Energy.from_millijoules(total_energy_consumption)
49
+
50
+ def delta(self, duration: Time) -> dict:
51
+ """
52
+ Compute the energy/power used since last call.
53
+ """
54
+ new_last_energy = energy = self._get_energy_kwh()
55
+ self.power = self.power.from_energies_and_delay(
56
+ energy, self.last_energy, duration
57
+ )
58
+ self.energy_delta = energy - self.last_energy
59
+ self.last_energy = new_last_energy
60
+ return {
61
+ "name": self._gpu_name,
62
+ "uuid": self._uuid,
63
+ "delta_energy_consumption": self.energy_delta,
64
+ "power_usage": self.power,
65
+ }
66
+
67
+ def get_static_details(self) -> Dict[str, Any]:
68
+ return {
69
+ "name": self._gpu_name,
70
+ "uuid": self._uuid,
71
+ "total_memory": self._total_memory,
72
+ "power_limit": self._power_limit,
73
+ "gpu_index": self.gpu_index,
74
+ }
75
+
76
+ def _init_static_details(self) -> None:
77
+ self._gpu_name = self._get_gpu_name()
78
+ self._uuid = self._get_uuid()
79
+ self._power_limit = self._get_power_limit()
80
+ # Get the memory
81
+ memory = self._get_memory_info()
82
+ self._total_memory = memory.total
83
+
84
+ def get_gpu_details(self) -> Dict[str, Any]:
85
+ # Memory
86
+ memory = self._get_memory_info()
87
+
88
+ device_details = {
89
+ "name": self._gpu_name,
90
+ "uuid": self._uuid,
91
+ "free_memory": memory.free,
92
+ "total_memory": memory.total,
93
+ "used_memory": memory.used,
94
+ "temperature": self._get_temperature(),
95
+ "power_usage": self._get_power_usage(),
96
+ "power_limit": self._power_limit,
97
+ "total_energy_consumption": self._get_total_energy_consumption(),
98
+ "gpu_utilization": self._get_gpu_utilization(),
99
+ "compute_mode": self._get_compute_mode(),
100
+ "compute_processes": self._get_compute_processes(),
101
+ "graphics_processes": self._get_graphics_processes(),
102
+ }
103
+ return device_details
104
+
105
+ def _to_utf8(self, str_or_bytes) -> Any:
106
+ if hasattr(str_or_bytes, "decode"):
107
+ return str_or_bytes.decode("utf-8", errors="replace")
108
+
109
+ return str_or_bytes
110
+
111
+ def _get_total_energy_consumption(self) -> int:
112
+ """Returns total energy consumption for this GPU in millijoules (mJ) since the driver was last reloaded
113
+ https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1g732ab899b5bd18ac4bfb93c02de4900a
114
+ """
115
+ try:
116
+ return pynvml.nvmlDeviceGetTotalEnergyConsumption(self.handle)
117
+ except pynvml.NVMLError:
118
+ logger.warning(
119
+ "Failed to retrieve gpu total energy consumption", exc_info=True
120
+ )
121
+ return None
122
+
123
+ def _get_gpu_name(self) -> Any:
124
+ """Returns the name of the GPU device
125
+ https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1ga5361803e044c6fdf3b08523fb6d1481
126
+ """
127
+ try:
128
+ name = pynvml.nvmlDeviceGetName(self.handle)
129
+ return self._to_utf8(name)
130
+ except UnicodeDecodeError:
131
+ return "Unknown GPU"
132
+
133
+ def _get_uuid(self) -> Any:
134
+ """Returns the globally unique GPU device UUID
135
+ https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1g72710fb20f30f0c2725ce31579832654
136
+ """
137
+ uuid = pynvml.nvmlDeviceGetUUID(self.handle)
138
+ return self._to_utf8(uuid)
139
+
140
+ def _get_memory_info(self):
141
+ """Returns memory info in bytes
142
+ https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1g2dfeb1db82aa1de91aa6edf941c85ca8
143
+ """
144
+ return pynvml.nvmlDeviceGetMemoryInfo(self.handle)
145
+
146
+ def _get_temperature(self) -> int:
147
+ """Returns degrees in the Celsius scale
148
+ https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1g92d1c5182a14dd4be7090e3c1480b121
149
+ """
150
+ return pynvml.nvmlDeviceGetTemperature(self.handle, pynvml.NVML_TEMPERATURE_GPU)
151
+
152
+ def _get_power_usage(self) -> int:
153
+ """Returns power usage in milliwatts
154
+ https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1g7ef7dff0ff14238d08a19ad7fb23fc87
155
+ """
156
+ return pynvml.nvmlDeviceGetPowerUsage(self.handle)
157
+
158
+ def _get_power_limit(self) -> Union[int, None]:
159
+ """Returns max power usage in milliwatts
160
+ https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1g263b5bf552d5ec7fcd29a088264d10ad
161
+ """
162
+ try:
163
+ return pynvml.nvmlDeviceGetEnforcedPowerLimit(self.handle)
164
+ except Exception:
165
+ return None
166
+
167
+ def _get_gpu_utilization(self):
168
+ """Returns the % of utilization of the kernels during the last sample
169
+ https://docs.nvidia.com/deploy/nvml-api/structnvmlUtilization__t.html#structnvmlUtilization__t
170
+ """
171
+ return pynvml.nvmlDeviceGetUtilizationRates(self.handle).gpu
172
+
173
+ def _get_compute_mode(self) -> int:
174
+ """Returns the compute mode of the GPU
175
+ https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1gbed1b88f2e3ba39070d31d1db4340233
176
+ """
177
+ return pynvml.nvmlDeviceGetComputeMode(self.handle)
178
+
179
+ def _get_compute_processes(self) -> List:
180
+ """Returns the list of processes ids having a compute context on the
181
+ device with the memory used
182
+ https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1g46ceaea624d5c96e098e03c453419d68
183
+ """
184
+ try:
185
+ processes = pynvml.nvmlDeviceGetComputeRunningProcesses(self.handle)
186
+
187
+ return [{"pid": p.pid, "used_memory": p.usedGpuMemory} for p in processes]
188
+ except pynvml.NVMLError:
189
+ return []
190
+
191
+ def _get_graphics_processes(self) -> List:
192
+ """Returns the list of processes ids having a graphics context on the
193
+ device with the memory used
194
+ https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1g7eacf7fa7ba4f4485d166736bf31195e
195
+ """
196
+ try:
197
+ processes = pynvml.nvmlDeviceGetGraphicsRunningProcesses(self.handle)
198
+
199
+ return [{"pid": p.pid, "used_memory": p.usedGpuMemory} for p in processes]
200
+ except pynvml.NVMLError:
201
+ return []
202
+
203
+
204
+ class AllGPUDevices:
205
+ def __init__(self) -> None:
206
+ if is_gpu_details_available():
207
+ logger.debug("GPU available. Starting setup")
208
+ self.device_count = pynvml.nvmlDeviceGetCount()
209
+ else:
210
+ logger.error("There is no GPU available")
211
+ self.device_count = 0
212
+ self.devices = []
213
+ for i in range(self.device_count):
214
+ handle = pynvml.nvmlDeviceGetHandleByIndex(i)
215
+ gpu_device = GPUDevice(handle=handle, gpu_index=i)
216
+ self.devices.append(gpu_device)
217
+
218
+ def get_gpu_static_info(self) -> List:
219
+ """Get all GPUs static information.
220
+ >>> get_gpu_static_info()
221
+ [
222
+ {
223
+ "name": "Tesla V100-SXM2-16GB",
224
+ "uuid": "GPU-4e817856-1fb8-192a-7ab7-0e0e4476c184",
225
+ "total_memory": 16945512448,
226
+ "power_limit": 300000,
227
+ "gpu_index": 0,
228
+ }
229
+ ]
230
+ """
231
+ try:
232
+ devices_static_info = []
233
+ for i in range(self.device_count):
234
+ gpu_device = self.devices[i]
235
+ devices_static_info.append(gpu_device.get_static_details())
236
+ return devices_static_info
237
+
238
+ except pynvml.NVMLError:
239
+ logger.warning("Failed to retrieve gpu static info", exc_info=True)
240
+ return []
241
+
242
+ def get_gpu_details(self) -> List:
243
+ """Get all GPUs instantaneous metrics
244
+ >>> get_gpu_details()
245
+ [
246
+ {
247
+ "name": "Tesla V100-SXM2-16GB",
248
+ "uuid": "GPU-4e817856-1fb8-192a-7ab7-0e0e4476c184",
249
+ "free_memory": 16945381376,
250
+ "total_memory": 16945512448,
251
+ "used_memory": 131072,
252
+ "temperature": 28,
253
+ "total_energy_consumption":2000,
254
+ "power_usage": 42159,
255
+ "power_limit": 300000,
256
+ "gpu_utilization": 0,
257
+ "compute_mode": 0,
258
+ "compute_processes": [],
259
+ "graphics_processes": [],
260
+ }
261
+ ]
262
+ """
263
+ try:
264
+ devices_info = []
265
+ for i in range(self.device_count):
266
+ gpu_device: GPUDevice = self.devices[i]
267
+ devices_info.append(gpu_device.get_gpu_details())
268
+ return devices_info
269
+
270
+ except pynvml.NVMLError:
271
+ logger.warning("Failed to retrieve gpu information", exc_info=True)
272
+ return []
273
+
274
+ def get_delta(self, last_duration: Time) -> List:
275
+ """Get difference since last time this function was called
276
+ >>> get_delta()
277
+ [
278
+ {
279
+ "name": "Tesla V100-SXM2-16GB",
280
+ "uuid": "GPU-4e817856-1fb8-192a-7ab7-0e0e4476c184",
281
+ "delta_energy_consumption":2000,
282
+ "power_usage": 42159,
283
+ }
284
+ ]
285
+ """
286
+ try:
287
+ devices_info = []
288
+ for i in range(self.device_count):
289
+ gpu_device: GPUDevice = self.devices[i]
290
+ devices_info.append(gpu_device.delta(last_duration))
291
+ return devices_info
292
+
293
+ except pynvml.NVMLError:
294
+ logger.warning("Failed to retrieve gpu information", exc_info=True)
295
+ return []
296
+
297
+
298
+ def is_gpu_details_available() -> bool:
299
+ """Returns True if the GPU details are available."""
300
+ try:
301
+ pynvml.nvmlInit()
302
+ return True
303
+
304
+ except pynvml.NVMLError:
305
+ return False
codecarbon/core/measure.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from time import perf_counter
2
+
3
+ from codecarbon.external.hardware import CPU, GPU, RAM, AppleSiliconChip
4
+ from codecarbon.external.logger import logger
5
+
6
+
7
+ class MeasurePowerEnergy:
8
+ """
9
+ Measure power and energy consumption of a hardware component.
10
+ """
11
+
12
+ _last_measured_time: int = 0
13
+ _hardware: list
14
+ _pue: float
15
+ _total_cpu_energy: float
16
+ _total_gpu_energy: float
17
+ _total_ram_energy: float
18
+ _total_energy: float
19
+ _cpu_power: float
20
+ _gpu_power: float
21
+ _ram_power: float
22
+
23
+ def __init__(self, hardware, pue):
24
+ """
25
+ :param hardware: list of hardware components to measure
26
+ :param pue: Power Usage Effectiveness of the datacenter
27
+ """
28
+ self._last_measured_time = perf_counter()
29
+ self._hardware = hardware
30
+ self._pue = pue
31
+ # TODO: Read initial energy values from hardware
32
+ self._total_cpu_energy = 0
33
+ self._total_gpu_energy = 0
34
+ self._total_ram_energy = 0
35
+ self._total_energy = 0
36
+ # Power cant't be read at init because we need time, so we set it to 0
37
+ self._cpu_power = 0
38
+ self._gpu_power = 0
39
+ self._ram_power = 0
40
+
41
+ def do_measure(self) -> None:
42
+ for hardware in self._hardware:
43
+ h_time = perf_counter()
44
+ # Compute last_duration again for more accuracy
45
+ last_duration = perf_counter() - self._last_measured_time
46
+ power, energy = hardware.measure_power_and_energy(
47
+ last_duration=last_duration
48
+ )
49
+ # Apply the PUE of the datacenter to the consumed energy
50
+ energy *= self._pue
51
+ self._total_energy += energy
52
+ if isinstance(hardware, CPU):
53
+ self._total_cpu_energy += energy
54
+ self._cpu_power = power
55
+ logger.info(
56
+ f"Energy consumed for all CPUs : {self._total_cpu_energy.kWh:.6f} kWh"
57
+ + f". Total CPU Power : {self._cpu_power.W} W"
58
+ )
59
+ elif isinstance(hardware, GPU):
60
+ self._total_gpu_energy += energy
61
+ self._gpu_power = power
62
+ logger.info(
63
+ f"Energy consumed for all GPUs : {self._total_gpu_energy.kWh:.6f} kWh"
64
+ + f". Total GPU Power : {self._gpu_power.W} W"
65
+ )
66
+ elif isinstance(hardware, RAM):
67
+ self._total_ram_energy += energy
68
+ self._ram_power = power
69
+ logger.info(
70
+ f"Energy consumed for RAM : {self._total_ram_energy.kWh:.6f} kWh."
71
+ + f"RAM Power : {self._ram_power.W} W"
72
+ )
73
+ elif isinstance(hardware, AppleSiliconChip):
74
+ if hardware.chip_part == "CPU":
75
+ self._total_cpu_energy += energy
76
+ self._cpu_power = power
77
+ logger.info(
78
+ f"Energy consumed for AppleSilicon CPU : {self._total_cpu_energy.kWh:.6f} kWh"
79
+ + f".Apple Silicon CPU Power : {self._cpu_power.W} W"
80
+ )
81
+ elif hardware.chip_part == "GPU":
82
+ self._total_gpu_energy += energy
83
+ self._gpu_power = power
84
+ logger.info(
85
+ f"Energy consumed for AppleSilicon GPU : {self._total_gpu_energy.kWh:.6f} kWh"
86
+ + f".Apple Silicon GPU Power : {self._gpu_power.W} W"
87
+ )
88
+ else:
89
+ logger.error(f"Unknown hardware type: {hardware} ({type(hardware)})")
90
+ h_time = perf_counter() - h_time
91
+ logger.debug(
92
+ f"{hardware.__class__.__name__} : {hardware.total_power().W:,.2f} "
93
+ + f"W during {last_duration:,.2f} s [measurement time: {h_time:,.4f}]"
94
+ )
95
+ logger.info(
96
+ f"{self._total_energy.kWh:.6f} kWh of electricity used since the beginning."
97
+ )
codecarbon/core/powermetrics.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import shutil
4
+ import subprocess
5
+ import sys
6
+ from typing import Dict
7
+
8
+ import numpy as np
9
+
10
+ from codecarbon.core.util import detect_cpu_model
11
+ from codecarbon.external.logger import logger
12
+
13
+
14
+ def is_powermetrics_available() -> bool:
15
+ try:
16
+ ApplePowermetrics()
17
+ response = _has_powermetrics_sudo()
18
+ return response
19
+ except Exception as e:
20
+ logger.debug(
21
+ "Not using PowerMetrics, an exception occurred while instantiating"
22
+ + f" Powermetrics : {e}",
23
+ )
24
+ return False
25
+
26
+
27
+ def _has_powermetrics_sudo() -> bool:
28
+ if shutil.which("sudo") is None:
29
+ logger.debug("sudo not available, we won't use Apple PowerMetrics.")
30
+ return False
31
+ if shutil.which("powermetrics") is None:
32
+ logger.info(
33
+ "Apple PowerMetrics not available. Please install it if you are using an Apple product."
34
+ )
35
+ return False
36
+
37
+ with subprocess.Popen(
38
+ [
39
+ "sudo",
40
+ "powermetrics",
41
+ "--samplers",
42
+ "cpu_power",
43
+ "-n",
44
+ "1",
45
+ "-i",
46
+ "1",
47
+ "-o",
48
+ "/dev/null",
49
+ ],
50
+ stdout=subprocess.PIPE,
51
+ stderr=subprocess.PIPE,
52
+ text=True,
53
+ ) as process:
54
+ _, stderr = process.communicate()
55
+
56
+ if re.search(r"[sudo].*password", stderr):
57
+ logger.debug(
58
+ """Not using PowerMetrics, sudo password prompt detected.
59
+ If you want to enable Powermetrics please modify your sudoers file
60
+ as described in :
61
+ https://mlco2.github.io/codecarbon/methodology.html#power-usage
62
+ """
63
+ )
64
+ return False
65
+ if process.returncode != 0:
66
+ raise Exception("Return code != 0")
67
+
68
+ return True
69
+
70
+
71
+ class ApplePowermetrics:
72
+ """
73
+ A class to interact with and retrieve power metrics on Apple Silicon devices using
74
+ the `powermetrics` command-line tool.
75
+
76
+ Methods:
77
+ --------
78
+ __init__(output_dir: str = ".", n_points=10, interval=100, log_file_name="powermetrics_log.txt"):
79
+ Initializes the ApplePowermetrics instance, setting up the log file path, system info,
80
+ and other configurations.
81
+
82
+ get_details() -> Dict:
83
+ Parses the log file generated by `powermetrics` and returns a dictionary containing
84
+ the average CPU and GPU power consumption and energy deltas. If parsing fails, logs
85
+ the exception and returns an empty dictionary.
86
+
87
+ start() -> None:
88
+ Placeholder method for starting the energy reading process (to be implemented).
89
+ """
90
+
91
+ _osx_silicon_exec = "powermetrics"
92
+
93
+ def __init__(
94
+ self,
95
+ output_dir: str = ".",
96
+ n_points=10,
97
+ interval=100,
98
+ log_file_name="powermetrics_log.txt",
99
+ ):
100
+ self._log_file_path = os.path.join(output_dir, log_file_name)
101
+ self._system = sys.platform.lower()
102
+ self._n_points = n_points
103
+ self._interval = interval
104
+ self._setup_cli()
105
+
106
+ def _setup_cli(self) -> None:
107
+ """
108
+ Setup cli command to run Powermetrics
109
+ """
110
+ if self._system.startswith("darwin"):
111
+ cpu_model = detect_cpu_model()
112
+ if cpu_model.startswith("Apple"):
113
+ if shutil.which(self._osx_silicon_exec):
114
+ self._cli = self._osx_silicon_exec
115
+ else:
116
+ raise FileNotFoundError(
117
+ f"Powermetrics executable not found on {self._system}"
118
+ )
119
+ else:
120
+ raise SystemError("Platform not supported by Powermetrics")
121
+
122
+ def _log_values(self) -> None:
123
+ """
124
+ Logs output from Powermetrics to a file
125
+ """
126
+ returncode = None
127
+
128
+ if self._system.startswith("darwin"):
129
+ # Run the powermetrics command with sudo and capture its output
130
+ cmd = [
131
+ "sudo",
132
+ "powermetrics",
133
+ "-n",
134
+ str(self._n_points),
135
+ "",
136
+ "--samplers",
137
+ "cpu_power",
138
+ "--format",
139
+ "csv",
140
+ "-i",
141
+ str(self._interval),
142
+ "-o",
143
+ self._log_file_path,
144
+ ]
145
+ returncode = subprocess.call(cmd, universal_newlines=True)
146
+
147
+ else:
148
+ return None
149
+
150
+ if returncode != 0:
151
+ logger.warning(
152
+ "Returncode while logging power values using "
153
+ + f"Powermetrics: {returncode}"
154
+ )
155
+ return
156
+
157
+ def get_details(self) -> Dict:
158
+ """
159
+ Fetches the CPU Power Details by fetching values from a logged csv file
160
+ in _log_values function
161
+ """
162
+ self._log_values()
163
+ details = dict()
164
+ try:
165
+ with open(self._log_file_path) as f:
166
+ logfile = f.read()
167
+ cpu_pattern = r"CPU Power: (\d+) mW"
168
+ cpu_power_list = re.findall(cpu_pattern, logfile)
169
+
170
+ details["CPU Power"] = np.mean(
171
+ [float(power) / 1000 for power in cpu_power_list]
172
+ )
173
+ details["CPU Energy Delta"] = np.sum(
174
+ [
175
+ (self._interval / 1000) * (float(power) / 1000)
176
+ for power in cpu_power_list
177
+ ]
178
+ )
179
+ gpu_pattern = r"GPU Power: (\d+) mW"
180
+ gpu_power_list = re.findall(gpu_pattern, logfile)
181
+ details["GPU Power"] = np.mean(
182
+ [float(power) / 1000 for power in gpu_power_list]
183
+ )
184
+ details["GPU Energy Delta"] = np.sum(
185
+ [
186
+ (self._interval / 1000) * (float(power) / 1000)
187
+ for power in gpu_power_list
188
+ ]
189
+ )
190
+ except Exception as e:
191
+ logger.info(
192
+ f"Unable to read Powermetrics logged file at {self._log_file_path}\n \
193
+ Exception occurred {e}",
194
+ exc_info=True,
195
+ )
196
+ return details
197
+
198
+ def start(self) -> None:
199
+ # TODO: Read energy
200
+ pass
codecarbon/core/rapl.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass, field
2
+
3
+ from codecarbon.core.units import Energy, Power, Time
4
+ from codecarbon.external.logger import logger
5
+
6
+
7
+ @dataclass
8
+ class RAPLFile:
9
+ # RAPL device being measured
10
+ name: str
11
+ # Path to file containing RAPL reading
12
+ path: str
13
+ # Path to corresponding file containing maximum possible RAPL reading
14
+ max_path: str
15
+ # Energy consumed in kWh
16
+ energy_delta: Energy = field(default_factory=lambda: Energy(0))
17
+ # Power based on reading
18
+ power: Power = field(default_factory=lambda: Power(0))
19
+ # Last energy reading in kWh
20
+ last_energy: Energy = field(default_factory=lambda: Energy(0))
21
+ # Max value energy can hold before it wraps
22
+ max_energy_reading: Energy = field(default_factory=lambda: Energy(0))
23
+
24
+ def __post_init__(self):
25
+ self.last_energy = self._get_value()
26
+ with open(self.max_path, "r") as f:
27
+ max_micro_joules = float(f.read())
28
+
29
+ self.max_energy_reading = Energy.from_ujoules(max_micro_joules)
30
+
31
+ def _get_value(self) -> Energy:
32
+ """
33
+ Reads the value in the file at the path
34
+ """
35
+ with open(self.path, "r") as f:
36
+ micro_joules = float(f.read())
37
+
38
+ e = Energy.from_ujoules(micro_joules)
39
+ return e
40
+
41
+ def start(self) -> None:
42
+ self.last_energy = self._get_value()
43
+
44
+ def delta(self, duration: Time) -> None:
45
+ """
46
+ Compute the energy used since last call.
47
+ """
48
+ new_last_energy = energy = self._get_value()
49
+ if self.last_energy > energy:
50
+ logger.debug(
51
+ f"In RAPLFile : Current energy value ({energy}) is lower than previous value ({self.last_energy}). Assuming wrap-around! Source file : {self.path}"
52
+ )
53
+ energy = energy + self.max_energy_reading
54
+ self.power = self.power.from_energies_and_delay(
55
+ energy, self.last_energy, duration
56
+ )
57
+ self.energy_delta = energy - self.last_energy
58
+ self.last_energy = new_last_energy
codecarbon/core/resource_tracker.py ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections import Counter
2
+ from typing import List, Union
3
+
4
+ from codecarbon.core import cpu, gpu, powermetrics
5
+ from codecarbon.core.config import parse_gpu_ids
6
+ from codecarbon.core.util import detect_cpu_model, is_linux_os, is_mac_os, is_windows_os
7
+ from codecarbon.external.hardware import CPU, GPU, MODE_CPU_LOAD, AppleSiliconChip
8
+ from codecarbon.external.logger import logger
9
+ from codecarbon.external.ram import RAM
10
+
11
+
12
+ class ResourceTracker:
13
+ cpu_tracker = gpu_tracker = ram_tracker = "Unspecified"
14
+
15
+ def __init__(self, tracker):
16
+ self.tracker = tracker
17
+
18
+ def set_RAM_tracking(self):
19
+ logger.info("[setup] RAM Tracking...")
20
+ if self.tracker._force_ram_power is not None:
21
+ self.ram_tracker = (
22
+ f"User specified constant: {self.tracker._force_ram_power} Watts"
23
+ )
24
+ logger.info(
25
+ f"Using user-provided RAM power: {self.tracker._force_ram_power} Watts"
26
+ )
27
+ else:
28
+ self.ram_tracker = "RAM power estimation model"
29
+ ram = RAM(
30
+ tracking_mode=self.tracker._tracking_mode,
31
+ force_ram_power=self.tracker._force_ram_power,
32
+ )
33
+ self.tracker._conf["ram_total_size"] = ram.machine_memory_GB
34
+ self.tracker._hardware: List[Union[RAM, CPU, GPU, AppleSiliconChip]] = [ram]
35
+
36
+ def set_CPU_tracking(self):
37
+ logger.info("[setup] CPU Tracking...")
38
+ cpu_number = self.tracker._conf.get("cpu_physical_count")
39
+ tdp = cpu.TDP()
40
+ if self.tracker._force_cpu_power is not None:
41
+ logger.info(
42
+ f"Using user-provided CPU power: {self.tracker._force_cpu_power} Watts"
43
+ )
44
+ self.cpu_tracker = "User Input TDP constant"
45
+ max_power = self.tracker._force_cpu_power
46
+ else:
47
+ max_power = tdp.tdp * cpu_number if tdp.tdp is not None else None
48
+ if self.tracker._conf.get("force_mode_cpu_load", False) and (
49
+ tdp.tdp is not None or self.tracker._force_cpu_power is not None
50
+ ):
51
+ if cpu.is_psutil_available():
52
+ # Register a CPU with MODE_CPU_LOAD
53
+ model = tdp.model
54
+ hardware_cpu = CPU.from_utils(
55
+ self.tracker._output_dir,
56
+ MODE_CPU_LOAD,
57
+ model,
58
+ max_power,
59
+ tracking_mode=self.tracker._tracking_mode,
60
+ )
61
+ self.cpu_tracker = MODE_CPU_LOAD
62
+ self.tracker._conf["cpu_model"] = hardware_cpu.get_model()
63
+ self.tracker._hardware.append(hardware_cpu)
64
+ return
65
+ else:
66
+ logger.warning(
67
+ "Force CPU load mode requested but psutil is not available."
68
+ )
69
+ if cpu.is_powergadget_available() and self.tracker._force_cpu_power is None:
70
+ logger.info("Tracking Intel CPU via Power Gadget")
71
+ self.cpu_tracker = "Power Gadget"
72
+ hardware_cpu = CPU.from_utils(
73
+ self.tracker._output_dir, "intel_power_gadget"
74
+ )
75
+ self.tracker._hardware.append(hardware_cpu)
76
+ self.tracker._conf["cpu_model"] = hardware_cpu.get_model()
77
+ elif cpu.is_rapl_available():
78
+ logger.info("Tracking Intel CPU via RAPL interface")
79
+ self.cpu_tracker = "RAPL"
80
+ hardware_cpu = CPU.from_utils(
81
+ output_dir=self.tracker._output_dir, mode="intel_rapl"
82
+ )
83
+ self.tracker._hardware.append(hardware_cpu)
84
+ self.tracker._conf["cpu_model"] = hardware_cpu.get_model()
85
+ if "AMD Ryzen Threadripper" in self.tracker._conf["cpu_model"]:
86
+ logger.warning(
87
+ "The RAPL energy and power reported is divided by 2 for all 'AMD Ryzen Threadripper' as it seems to give better results."
88
+ )
89
+ # change code to check if powermetrics needs to be installed or just sudo setup
90
+ elif (
91
+ powermetrics.is_powermetrics_available()
92
+ and self.tracker._force_cpu_power is None
93
+ ):
94
+ logger.info("Tracking Apple CPU and GPU via PowerMetrics")
95
+ self.gpu_tracker = "PowerMetrics"
96
+ self.cpu_tracker = "PowerMetrics"
97
+ hardware_cpu = AppleSiliconChip.from_utils(
98
+ self.tracker._output_dir, chip_part="CPU"
99
+ )
100
+ self.tracker._hardware.append(hardware_cpu)
101
+ self.tracker._conf["cpu_model"] = hardware_cpu.get_model()
102
+
103
+ hardware_gpu = AppleSiliconChip.from_utils(
104
+ self.tracker._output_dir, chip_part="GPU"
105
+ )
106
+ self.tracker._hardware.append(hardware_gpu)
107
+
108
+ self.tracker._conf["gpu_model"] = hardware_gpu.get_model()
109
+ self.tracker._conf["gpu_count"] = 1
110
+ else:
111
+ # Explain what to install to increase accuracy
112
+ cpu_tracking_install_instructions = ""
113
+ if is_mac_os():
114
+ if (
115
+ "M1" in detect_cpu_model()
116
+ or "M2" in detect_cpu_model()
117
+ or "M3" in detect_cpu_model()
118
+ ):
119
+ cpu_tracking_install_instructions = ""
120
+ cpu_tracking_install_instructions = "Mac OS and ARM processor detected: Please enable PowerMetrics sudo to measure CPU"
121
+ else:
122
+ cpu_tracking_install_instructions = "Mac OS detected: Please install Intel Power Gadget or enable PowerMetrics sudo to measure CPU"
123
+ elif is_windows_os():
124
+ cpu_tracking_install_instructions = "Windows OS detected: Please install Intel Power Gadget to measure CPU"
125
+ elif is_linux_os():
126
+ cpu_tracking_install_instructions = "Linux OS detected: Please ensure RAPL files exist at /sys/class/powercap/intel-rapl/subsystem to measure CPU"
127
+ logger.warning(
128
+ f"No CPU tracking mode found. Falling back on estimation based on TDP for CPU. \n {cpu_tracking_install_instructions}\n"
129
+ )
130
+ self.cpu_tracker = "TDP constant"
131
+ model = tdp.model
132
+ if (max_power is None) and self.tracker._force_cpu_power:
133
+ # We haven't been able to calculate CPU power but user has input a default one. We use it
134
+ user_input_power = self.tracker._force_cpu_power
135
+ logger.debug(f"Using user input TDP: {user_input_power} W")
136
+ self.cpu_tracker = "User Input TDP constant"
137
+ max_power = user_input_power
138
+ logger.info(f"CPU Model on constant consumption mode: {model}")
139
+ self.tracker._conf["cpu_model"] = model
140
+ if tdp:
141
+ if cpu.is_psutil_available():
142
+ logger.warning(
143
+ "No CPU tracking mode found. Falling back on CPU load mode."
144
+ )
145
+ hardware_cpu = CPU.from_utils(
146
+ self.tracker._output_dir,
147
+ MODE_CPU_LOAD,
148
+ model,
149
+ max_power,
150
+ tracking_mode=self.tracker._tracking_mode,
151
+ )
152
+ self.cpu_tracker = MODE_CPU_LOAD
153
+ else:
154
+ logger.warning(
155
+ "No CPU tracking mode found. Falling back on CPU constant mode."
156
+ )
157
+ hardware_cpu = CPU.from_utils(
158
+ self.tracker._output_dir, "constant", model, max_power
159
+ )
160
+ self.cpu_tracker = "global constant"
161
+ self.tracker._hardware.append(hardware_cpu)
162
+ else:
163
+ if cpu.is_psutil_available():
164
+ logger.warning(
165
+ "Failed to match CPU TDP constant. Falling back on CPU load mode."
166
+ )
167
+ hardware_cpu = CPU.from_utils(
168
+ self.tracker._output_dir,
169
+ MODE_CPU_LOAD,
170
+ model,
171
+ max_power,
172
+ tracking_mode=self.tracker._tracking_mode,
173
+ )
174
+ self.cpu_tracker = MODE_CPU_LOAD
175
+ else:
176
+ logger.warning(
177
+ "Failed to match CPU TDP constant. Falling back on a global constant."
178
+ )
179
+ self.cpu_tracker = "global constant"
180
+ hardware_cpu = CPU.from_utils(self.tracker._output_dir, "constant")
181
+ self.tracker._hardware.append(hardware_cpu)
182
+
183
+ def set_GPU_tracking(self):
184
+ logger.info("[setup] GPU Tracking...")
185
+ if self.tracker._gpu_ids:
186
+ # If _gpu_ids is a string or a list of int, parse it to a list of ints
187
+ if isinstance(self.tracker._gpu_ids, str) or (
188
+ isinstance(self.tracker._gpu_ids, list)
189
+ and all(isinstance(gpu_id, int) for gpu_id in self.tracker._gpu_ids)
190
+ ):
191
+ self.tracker._gpu_ids: List = parse_gpu_ids(self.tracker._gpu_ids)
192
+ self.tracker._conf["gpu_ids"] = self.tracker._gpu_ids
193
+ self.tracker._conf["gpu_count"] = len(self.tracker._gpu_ids)
194
+ else:
195
+ logger.warning(
196
+ "Invalid gpu_ids format. Expected a string or a list of ints."
197
+ )
198
+ if gpu.is_gpu_details_available():
199
+ logger.info("Tracking Nvidia GPU via pynvml")
200
+ gpu_devices = GPU.from_utils(self.tracker._gpu_ids)
201
+ self.tracker._hardware.append(gpu_devices)
202
+ gpu_names = [n["name"] for n in gpu_devices.devices.get_gpu_static_info()]
203
+ gpu_names_dict = Counter(gpu_names)
204
+ self.tracker._conf["gpu_model"] = "".join(
205
+ [f"{i} x {name}" for name, i in gpu_names_dict.items()]
206
+ )
207
+ if self.tracker._conf.get("gpu_count") is None:
208
+ self.tracker._conf["gpu_count"] = len(
209
+ gpu_devices.devices.get_gpu_static_info()
210
+ )
211
+ self.gpu_tracker = "pynvml"
212
+ else:
213
+ logger.info("No GPU found.")
214
+
215
+ def set_CPU_GPU_ram_tracking(self):
216
+ """
217
+ Set up CPU, GPU and RAM tracking based on the user's configuration.
218
+ param tracker: BaseEmissionsTracker object
219
+ """
220
+ self.set_RAM_tracking()
221
+ self.set_CPU_tracking()
222
+ self.set_GPU_tracking()
223
+
224
+ logger.info(
225
+ f"""The below tracking methods have been set up:
226
+ RAM Tracking Method: {self.ram_tracker}
227
+ CPU Tracking Method: {self.cpu_tracker}
228
+ GPU Tracking Method: {self.gpu_tracker}
229
+ """
230
+ )
codecarbon/core/schemas.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Here is the schemas used to communicate with the API.
3
+ """
4
+
5
+ from dataclasses import dataclass
6
+ from datetime import datetime
7
+ from typing import Optional
8
+ from uuid import UUID
9
+
10
+
11
+ @dataclass
12
+ class EmissionBase:
13
+ timestamp: str
14
+ run_id: str
15
+ duration: int
16
+ emissions_sum: float
17
+ emissions_rate: float
18
+ cpu_power: float
19
+ gpu_power: float
20
+ ram_power: float
21
+ cpu_energy: float
22
+ gpu_energy: float
23
+ ram_energy: float
24
+ energy_consumed: float
25
+
26
+
27
+ class EmissionCreate(EmissionBase):
28
+ pass
29
+
30
+
31
+ class Emission(EmissionBase):
32
+ id: str
33
+
34
+
35
+ @dataclass
36
+ class RunBase:
37
+ timestamp: str
38
+ experiment_id: str
39
+ os: Optional[str]
40
+ python_version: Optional[str]
41
+ codecarbon_version: Optional[str]
42
+ cpu_count: Optional[int]
43
+ cpu_model: Optional[str]
44
+ gpu_count: Optional[int]
45
+ gpu_model: Optional[str]
46
+ longitude: Optional[float]
47
+ latitude: Optional[float]
48
+ region: Optional[str]
49
+ provider: Optional[str]
50
+ ram_total_size: Optional[float]
51
+ tracking_mode: Optional[str]
52
+
53
+
54
+ class RunCreate(RunBase):
55
+ pass
56
+
57
+
58
+ class Run(RunBase):
59
+ id: str
60
+
61
+
62
+ @dataclass
63
+ class ExperimentBase:
64
+ timestamp: datetime
65
+ name: str
66
+ description: str
67
+ on_cloud: bool
68
+ project_id: UUID
69
+ country_name: Optional[str] = None
70
+ country_iso_code: Optional[str] = None
71
+ region: Optional[str] = None
72
+ cloud_provider: Optional[str] = None
73
+ cloud_region: Optional[str] = None
74
+
75
+
76
+ class ExperimentCreate(ExperimentBase):
77
+ pass
78
+
79
+
80
+ class Experiment(ExperimentBase):
81
+ id: str
82
+
83
+
84
+ @dataclass
85
+ class OrganizationBase:
86
+ name: str
87
+ description: str
88
+
89
+
90
+ class OrganizationCreate(OrganizationBase):
91
+ pass
92
+
93
+
94
+ class Organization(OrganizationBase):
95
+ id: str
96
+
97
+
98
+ @dataclass
99
+ class ProjectBase:
100
+ name: str
101
+ description: str
102
+ organization_id: str
103
+
104
+
105
+ class ProjectCreate(ProjectBase):
106
+ pass
107
+
108
+
109
+ class Project(ProjectBase):
110
+ id: str
codecarbon/core/units.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Provides functionality for unit conversions
3
+ """
4
+
5
+ from dataclasses import dataclass, field
6
+
7
+ # from pydantic.dataclasses import dataclass, field
8
+
9
+
10
+ @dataclass
11
+ class Time:
12
+ """
13
+ Measured in seconds
14
+ """
15
+
16
+ seconds: float
17
+ SECONDS_TO_HOURS = 1 / 3600
18
+
19
+ @property
20
+ def hours(self) -> float:
21
+ return self.seconds * Time.SECONDS_TO_HOURS
22
+
23
+ @classmethod
24
+ def from_seconds(cls, seconds: float) -> "Time":
25
+ return cls(seconds=seconds)
26
+
27
+
28
+ @dataclass
29
+ class EmissionsPerKWh:
30
+ """
31
+ Measured in kg/kWh
32
+ """
33
+
34
+ LBS_MWH_TO_KG_KWH = 0.00045359237
35
+ G_KWH_TO_KG_KWH = 0.001
36
+
37
+ kgs_per_kWh: float
38
+
39
+ @classmethod
40
+ def from_lbs_per_mWh(cls, lbs_per_mWh: float) -> "EmissionsPerKWh":
41
+ return cls(kgs_per_kWh=lbs_per_mWh * EmissionsPerKWh.LBS_MWH_TO_KG_KWH)
42
+
43
+ @classmethod
44
+ def from_g_per_kWh(cls, g_per_kWh: float) -> "EmissionsPerKWh":
45
+ return cls(kgs_per_kWh=g_per_kWh * EmissionsPerKWh.G_KWH_TO_KG_KWH)
46
+
47
+ @classmethod
48
+ def from_kgs_per_kWh(cls, kgs_per_kWh: float) -> "EmissionsPerKWh":
49
+ return cls(kgs_per_kWh=kgs_per_kWh)
50
+
51
+
52
+ @dataclass(order=True)
53
+ class Energy:
54
+ """
55
+ Measured in kWh
56
+ """
57
+
58
+ UJOULES_TO_JOULES = 10 ** (-6)
59
+ MILLIJOULES_TO_JOULES = 10 ** (-3)
60
+ JOULES_TO_KWH = 2.77778e-7
61
+
62
+ kWh: float = field(compare=True)
63
+
64
+ def __post_init__(self):
65
+ self.kWh = float(self.kWh)
66
+
67
+ @classmethod
68
+ def from_power_and_time(cls, *, power: "Power", time: "Time") -> "Energy":
69
+ assert isinstance(power.kW, float)
70
+ assert isinstance(time.hours, float)
71
+ energy = power.kW * time.hours
72
+ return cls(kWh=energy)
73
+
74
+ @classmethod
75
+ def from_ujoules(cls, energy: float) -> "Energy":
76
+ return cls(kWh=energy * Energy.UJOULES_TO_JOULES * Energy.JOULES_TO_KWH)
77
+
78
+ @classmethod
79
+ def from_millijoules(cls, energy: float) -> "Energy":
80
+ return cls(kWh=energy * Energy.MILLIJOULES_TO_JOULES * Energy.JOULES_TO_KWH)
81
+
82
+ @classmethod
83
+ def from_energy(cls, kWh: float) -> "Energy":
84
+ return cls(kWh=kWh)
85
+
86
+ def __sub__(self, other: "Energy") -> "Energy":
87
+ return Energy(self.kWh - other.kWh)
88
+
89
+ def __add__(self, other: "Energy") -> "Energy":
90
+ return Energy(self.kWh + other.kWh)
91
+
92
+ def __mul__(self, factor: float) -> "Energy":
93
+ assert isinstance(factor, float)
94
+ assert isinstance(self.kWh, float)
95
+ result = Energy(self.kWh * factor)
96
+ return result
97
+
98
+ def __float__(self) -> float:
99
+ return float(self.kWh)
100
+
101
+ def __truediv__(self, divisor: float) -> "Energy":
102
+ return Energy(self.kWh / divisor)
103
+
104
+
105
+ @dataclass
106
+ class Power:
107
+ """
108
+ Measured in kW
109
+ """
110
+
111
+ MILLI_WATTS_TO_WATTS = 0.001
112
+ WATTS_TO_KILO_WATTS = 0.001
113
+
114
+ kW: float
115
+
116
+ @classmethod
117
+ def from_milli_watts(cls, milli_watts: float) -> "Power":
118
+ return cls(
119
+ kW=milli_watts * Power.MILLI_WATTS_TO_WATTS * Power.WATTS_TO_KILO_WATTS
120
+ )
121
+
122
+ @classmethod
123
+ def from_watts(cls, watts: float) -> "Power":
124
+ return cls(kW=watts * Power.WATTS_TO_KILO_WATTS)
125
+
126
+ @classmethod
127
+ def from_energies_and_delay(cls, e1: "Energy", e2: "Energy", delay: "Time"):
128
+ """
129
+ P = (E_{t1} - E_{t2}) / delay (=t2-t1)
130
+ kW kWh kWh h
131
+
132
+ Args:
133
+ e1 (Energy): First measurement
134
+ e2 (Energy): Second measurement
135
+ delay (Time): Time between measurements
136
+
137
+ Returns:
138
+ Power: Resulting Power estimation
139
+ """
140
+ delta_energy = float(abs(e2.kWh - e1.kWh))
141
+ kW = delta_energy / delay.hours if delay.hours != 0.0 else 0.0
142
+ return cls(kW=kW)
143
+
144
+ @classmethod
145
+ def from_energy_delta_and_delay(cls, e: "Energy", delay: "Time"):
146
+ return cls.from_energies_and_delay(e, Energy(0), delay)
147
+
148
+ @property
149
+ def W(self):
150
+ if not isinstance(self.kW, float):
151
+ return self.kW
152
+ return self.kW * 1000
153
+
154
+ def __add__(self, other: "Power") -> "Power":
155
+ return Power(self.kW + other.kW)
156
+
157
+ def __mul__(self, factor: float) -> "Power":
158
+ return Power(self.kW * factor)
159
+
160
+ def __truediv__(self, divisor: float) -> "Power":
161
+ return Power(self.kW / divisor)
162
+
163
+ def __floordiv__(self, divisor: float) -> "Power":
164
+ return Power(self.kW // divisor)
codecarbon/core/util.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import subprocess
4
+ import sys
5
+ from contextlib import contextmanager
6
+ from os.path import expandvars
7
+ from pathlib import Path
8
+ from typing import Optional, Union
9
+
10
+ import cpuinfo
11
+ import psutil
12
+
13
+ from codecarbon.external.logger import logger
14
+
15
+ SLURM_JOB_ID = os.environ.get(
16
+ "SLURM_JOB_ID", # default
17
+ os.environ.get("SLURM_JOBID"), # deprecated but may still be used
18
+ )
19
+
20
+
21
+ @contextmanager
22
+ def suppress(*exceptions):
23
+ try:
24
+ yield
25
+ except exceptions:
26
+ logger.warning("graceful shutdown. Exceptions:")
27
+ logger.warning(
28
+ exceptions if len(exceptions) != 1 else exceptions[0], exc_info=True
29
+ )
30
+ logger.warning("stopping.")
31
+
32
+
33
+ def resolve_path(path: Union[str, Path]) -> Path:
34
+ """
35
+ Fully resolve a path:
36
+ resolve env vars ($HOME etc.) -> expand user (~) -> make absolute
37
+
38
+ Args:
39
+ path (Union[str, Path]): Path to a file or repository to resolve as
40
+ string or pathlib.Path
41
+
42
+ Returns:
43
+ pathlib.Path: resolved absolute path
44
+ """
45
+ return Path(expandvars(str(path))).expanduser().resolve()
46
+
47
+
48
+ def backup(file_path: Union[str, Path], ext: Optional[str] = ".bak") -> None:
49
+ """
50
+ Resolves the path to a path then backs it up, adding the extension provided.
51
+ Warning : this function will rename the file in place, it's the calling function that will write a new file at the original path.
52
+ This function will not overwrite existing backups but add a number.
53
+
54
+ Args:
55
+ file_path (Union[str, Path]): Path to a file to backup.
56
+ ext (Optional[str], optional): extension to append to the filename when
57
+ backing it up. Defaults to ".bak".
58
+ """
59
+ file_path = resolve_path(file_path)
60
+ if not file_path.exists():
61
+ return
62
+ assert file_path.is_file()
63
+ idx = 0
64
+ parent = file_path.parent
65
+ file_name = f"{file_path.name}{ext}"
66
+ backup_path = parent / file_name
67
+
68
+ while backup_path.exists():
69
+ file_name = f"{file_path.name}_{idx}{ext}"
70
+ backup_path = parent / file_name
71
+ idx += 1
72
+
73
+ file_path.rename(backup_path)
74
+
75
+
76
+ def detect_cpu_model() -> str:
77
+ cpu_info = cpuinfo.get_cpu_info()
78
+ if cpu_info:
79
+ cpu_model_detected = cpu_info.get("brand_raw", "")
80
+ return cpu_model_detected
81
+ return None
82
+
83
+
84
+ def is_mac_os() -> str:
85
+ system = sys.platform.lower()
86
+ return system.startswith("dar")
87
+
88
+
89
+ def is_windows_os() -> str:
90
+ system = sys.platform.lower()
91
+ return system.startswith("win")
92
+
93
+
94
+ def is_linux_os() -> str:
95
+ system = sys.platform.lower()
96
+ return system.startswith("lin")
97
+
98
+
99
+ def count_physical_cpus():
100
+ import platform
101
+ import subprocess
102
+
103
+ if platform.system() == "Windows":
104
+ return int(os.environ.get("NUMBER_OF_PROCESSORS", 1))
105
+ else:
106
+ try:
107
+ output = subprocess.check_output(["lscpu"], text=True)
108
+ for line in output.split("\n"):
109
+ if "Socket(s):" in line:
110
+ return int(line.split(":")[1].strip())
111
+ else:
112
+ return 1
113
+ except Exception as e:
114
+ logger.warning(
115
+ f"Error while trying to count physical CPUs: {e}. Defaulting to 1."
116
+ )
117
+ return 1
118
+
119
+
120
+ def count_cpus() -> int:
121
+ if SLURM_JOB_ID is None:
122
+ return psutil.cpu_count()
123
+
124
+ try:
125
+ logger.debug(
126
+ "SLURM environment detected for job {SLURM_JOB_ID}, running"
127
+ + " `scontrol show job $SLURM_JOB_ID` to count SLURM-available cpus."
128
+ )
129
+ scontrol = subprocess.check_output(
130
+ [f"scontrol show job {SLURM_JOB_ID}"], shell=True
131
+ ).decode()
132
+ except subprocess.CalledProcessError:
133
+ logger.warning(
134
+ "Error running `scontrol show job $SLURM_JOB_ID` "
135
+ + "to count SLURM-available cpus. Using the machine's cpu count."
136
+ )
137
+ return psutil.cpu_count(logical=True)
138
+
139
+ num_cpus_matches = re.findall(r"NumCPUs=\d+", scontrol)
140
+
141
+ if len(num_cpus_matches) == 0:
142
+ logger.warning(
143
+ "Could not find NumCPUs= after running `scontrol show job $SLURM_JOB_ID` "
144
+ + "to count SLURM-available cpus. Using the machine's cpu count."
145
+ )
146
+ return psutil.cpu_count(logical=True)
147
+
148
+ if len(num_cpus_matches) > 1:
149
+ logger.warning(
150
+ "Unexpected output after running `scontrol show job $SLURM_JOB_ID` "
151
+ + "to count SLURM-available cpus. Using the machine's cpu count."
152
+ )
153
+ return psutil.cpu_count(logical=True)
154
+
155
+ num_cpus = num_cpus_matches[0].replace("NumCPUs=", "")
156
+ logger.debug(f"Detected {num_cpus} cpus available on SLURM.")
157
+ return int(num_cpus)
codecarbon/data/canada_provinces.geojson ADDED
The diff for this file is too large to render. See raw diff
 
codecarbon/data/cloud/impact.csv ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ provider,providerName,offsetRatio,region,regionName,country_name,countryIsoCode,state,city,impact,source,comment
2
+ gcp,Google Cloud Platform,100,africa-south1,,South Africa,ZAF,,Johannesburg,646,https://cloud.google.com/sustainability/region-carbon#data,
3
+ gcp,Google Cloud Platform,100,asia-east1,,Taiwan,TWN,,Changhua County,451,https://cloud.google.com/sustainability/region-carbon#data,
4
+ gcp,Google Cloud Platform,100,asia-east2,,China,CHN,,Hong Kong,360,https://cloud.google.com/sustainability/region-carbon#data,
5
+ gcp,Google Cloud Platform,100,asia-northeast1,,Japan,JPN,,Tokyo,459,https://cloud.google.com/sustainability/region-carbon#data,
6
+ gcp,Google Cloud Platform,100,asia-northeast2,,Japan,JPN,,Osaka,385,https://cloud.google.com/sustainability/region-carbon#data,
7
+ gcp,Google Cloud Platform,100,asia-northeast3,,Korea,KOR,South Korea,Seoul,378,https://cloud.google.com/sustainability/region-carbon#data,
8
+ gcp,Google Cloud Platform,100,asia-south1,,India,IND,,Mumbai,648,https://cloud.google.com/sustainability/region-carbon#data,
9
+ gcp,Google Cloud Platform,100,asia-south2,,India,IND,,Delhi,529,https://cloud.google.com/sustainability/region-carbon#data,
10
+ gcp,Google Cloud Platform,100,asia-southeast1,,Singapore,SGP,,Jurong West,369,https://cloud.google.com/sustainability/region-carbon#data,
11
+ gcp,Google Cloud Platform,100,asia-southeast2,,Indonesia,IDN,,Jakarta,580,https://cloud.google.com/sustainability/region-carbon#data,
12
+ gcp,Google Cloud Platform,100,australia-southeast1,,Australia,AUS,,Sydney,501,https://cloud.google.com/sustainability/region-carbon#data,
13
+ gcp,Google Cloud Platform,100,australia-southeast2,,Australia,AUS,,Melbourne,456,https://cloud.google.com/sustainability/region-carbon#data,
14
+ gcp,Google Cloud Platform,100,europe-central2,,Poland,POL,,Warsaw,723,https://cloud.google.com/sustainability/region-carbon#data,
15
+ gcp,Google Cloud Platform,100,europe-north1,,Finland,FIN,,Hamina,46,https://cloud.google.com/sustainability/region-carbon#data,
16
+ gcp,Google Cloud Platform,100,europe-southwest1,,Spain,ESP,,Madrid,131,https://cloud.google.com/sustainability/region-carbon#data,
17
+ gcp,Google Cloud Platform,100,europe-west1,,Belgium,BEL,,St. Ghislain,122,https://cloud.google.com/sustainability/region-carbon#data,
18
+ gcp,Google Cloud Platform,100,europe-west2,,United Kingdom,GBR,England,London,136,https://cloud.google.com/sustainability/region-carbon#data,
19
+ gcp,Google Cloud Platform,100,europe-west3,,Germany,DEU,,Frankfurt,345,https://cloud.google.com/sustainability/region-carbon#data,
20
+ gcp,Google Cloud Platform,100,europe-west4,,Netherlands,NLD,,Eemshaven,236,https://cloud.google.com/sustainability/region-carbon#data,
21
+ gcp,Google Cloud Platform,100,europe-west6,,Switzerland,CHE,,Zurich,59,https://cloud.google.com/sustainability/region-carbon#data,
22
+ gcp,Google Cloud Platform,100,europe-west8,,Italy,ITA,,Milan,249,https://cloud.google.com/sustainability/region-carbon#data,
23
+ gcp,Google Cloud Platform,100,europe-west9,,France,FRA,,Paris,34,https://cloud.google.com/sustainability/region-carbon#data,
24
+ gcp,Google Cloud Platform,100,europe-west10,,Germany,DEU,,Berlin,345,https://cloud.google.com/sustainability/region-carbon#data,
25
+ gcp,Google Cloud Platform,100,europe-west12,,Italy,ITA,,Turin,249,https://cloud.google.com/sustainability/region-carbon#data,
26
+ gcp,Google Cloud Platform,100,me-cenrtal1,,Qatar,QAT,,Doha,575,https://cloud.google.com/sustainability/region-carbon#data,
27
+ gcp,Google Cloud Platform,100,me-central2,,Saudi Arabia,SAU,,Dammam,569,https://cloud.google.com/sustainability/region-carbon#data,
28
+ gcp,Google Cloud Platform,100,me-west1,,Israel,ISR,,Tel Aviv,463,https://cloud.google.com/sustainability/region-carbon#data,
29
+ gcp,Google Cloud Platform,100,northamerica-northeast1,,Canada,CAN,Quebec,Montreal,2,https://cloud.google.com/sustainability/region-carbon#data,
30
+ gcp,Google Cloud Platform,100,northamerica-northeast2,,Canada,CAN,,Toronto,47,https://cloud.google.com/sustainability/region-carbon#data,
31
+ gcp,Google Cloud Platform,100,southamerica-east1,,Brazil,BRA,,Sao Paulo,56,https://cloud.google.com/sustainability/region-carbon#data,
32
+ gcp,Google Cloud Platform,100,southamerica-west1,,Chile,CHL,,Santiago,138,https://cloud.google.com/sustainability/region-carbon#data,
33
+ gcp,Google Cloud Platform,100,us-central1,,USA,USA,Iowa,Council Bluffs,430,https://cloud.google.com/sustainability/region-carbon#data,
34
+ gcp,Google Cloud Platform,100,us-east1,,USA,USA,South Carolina,Moncks Corner,560,https://cloud.google.com/sustainability/region-carbon#data,
35
+ gcp,Google Cloud Platform,100,us-east4,,USA,USA,Northern Virginia,Ashburn,322,https://cloud.google.com/sustainability/region-carbon#data,
36
+ gcp,Google Cloud Platform,100,us-east5,,USA,USA,,Columbus,322,https://cloud.google.com/sustainability/region-carbon#data,
37
+ gcp,Google Cloud Platform,100,us-south1,,USA,USA,,Dallas,321,https://cloud.google.com/sustainability/region-carbon#data,
38
+ gcp,Google Cloud Platform,100,us-west1,,USA,USA,Oregon,The Dalles,94,https://cloud.google.com/sustainability/region-carbon#data,
39
+ gcp,Google Cloud Platform,100,us-west2,,USA,USA,California,Los Angeles,198,https://cloud.google.com/sustainability/region-carbon#data,
40
+ gcp,Google Cloud Platform,100,us-west3,,USA,USA,Utah,Salt Lake City,588,https://cloud.google.com/sustainability/region-carbon#data,
41
+ gcp,Google Cloud Platform,100,us-west4,,USA,USA,Nevada,Las Vegas,373,https://cloud.google.com/sustainability/region-carbon#data,
codecarbon/data/hardware/cpu_dataset_builder/CPU_Create_Dataset.ipynb ADDED
@@ -0,0 +1,1671 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "We want to build a CPU dataset.\n",
8
+ "There is pointer on https://github.com/felixsteinke/cpu-spec-dataset\n",
9
+ "\n",
10
+ "## AMD Dataset\n",
11
+ "\n",
12
+ "Manually Export Data as CSV/Excel from https://www.amd.com/en/products/specifications/processors\n",
13
+ "Website Screenshot\n",
14
+ "\n",
15
+ "blob:https://www.amd.com/fc70f2d3-27d4-4bf1-a466-9912927167de\n",
16
+ "\n",
17
+ "## Ampere Dataset\n",
18
+ "\n",
19
+ "Extracted from https://amperecomputing.com/briefs/ampere-altra-family-product-brief with the responsible Web Scraper.\n",
20
+ "\n",
21
+ "cd ampere-web-scraper\n",
22
+ "java -jar ./target/exectuable.jar\n",
23
+ "\n",
24
+ "## Intel Dataset\n",
25
+ "\n",
26
+ "Extracted from https://ark.intel.com/content/www/us/en/ark.html with the responsible Web Scraper.\n",
27
+ "\n",
28
+ "cd intel-web-scraper\n",
29
+ "java -jar ./target/exectuable.jar\n",
30
+ "\n",
31
+ "## CPU Benchmark Dataset\n",
32
+ "\n",
33
+ "Extracted from https://www.cpubenchmark.net/cpu_list.php with the responsible Web Scraper.\n",
34
+ "\n",
35
+ "cd benchmark-web-scraper\n",
36
+ "java -jar ./target/exectuable.jar\n",
37
+ "\n",
38
+ "## CPU World Dataset\n",
39
+ "\n",
40
+ "Extracted from https://www.cpu-world.com/CPUs/CPU.html with the responsible Web Scraper.\n",
41
+ "\n",
42
+ "cd cpuworld-web-scraper\n",
43
+ "mvn -jar ./target/exectuable.jar"
44
+ ]
45
+ },
46
+ {
47
+ "cell_type": "markdown",
48
+ "metadata": {},
49
+ "source": [
50
+ "test"
51
+ ]
52
+ },
53
+ {
54
+ "cell_type": "markdown",
55
+ "metadata": {},
56
+ "source": [
57
+ "Extraction from https://www.intel.com/content/www/us/en/ark/products/series/236644/5th-gen-intel-xeon-scalable-processors.html\n",
58
+ "```html\n",
59
+ "<table id=\"product-table\" class=\"table table-sorter sorting tablesorter tablesorter-default\">\n",
60
+ " <thead>\n",
61
+ " <tr class=\"tablesorter-headerRow\">\n",
62
+ " <th class=\"product-table-sortable-col product-name-col ark-product-name xlarge-column component header tablesorter-header\" data-component=\"wa_skip_track\" data-component-id=\"1\" data-col=\"productName\" data-sort-field=\"productName\" role=\"columnheader\" aria-sort=\"\" aria-rowindex=\"1\" data-column=\"0\"><div class=\"tablesorter-header-inner\">\n",
63
+ " <div class=\"header-additional-padding\">\n",
64
+ " <div class=\"header-text-space\">\n",
65
+ " Product Name\n",
66
+ " </div>\n",
67
+ " </div>\n",
68
+ " </div></th>\n",
69
+ " \n",
70
+ " \n",
71
+ " \n",
72
+ " <th class=\"product-table-sortable-col component medium-column descending tablesorter-header\" data-component=\"wa_skip_track\" data-component-id=\"1\" data-col=\"BornOnDate\" role=\"columnheader\" aria-sort=\"\" aria-rowindex=\"1\" data-column=\"1\"><div class=\"tablesorter-header-inner\">\n",
73
+ " <div class=\"header-additional-padding\">\n",
74
+ " <div class=\"header-text-space\">\n",
75
+ " Launch Date\n",
76
+ " </div>\n",
77
+ " </div>\n",
78
+ " </div></th>\n",
79
+ " \n",
80
+ " \n",
81
+ " \n",
82
+ " <th class=\"product-table-sortable-col component medium-column tablesorter-header\" data-component=\"wa_skip_track\" data-component-id=\"1\" data-col=\"CoreCount\" role=\"columnheader\" aria-sort=\"\" aria-rowindex=\"1\" data-column=\"2\"><div class=\"tablesorter-header-inner\">\n",
83
+ " <div class=\"header-additional-padding\">\n",
84
+ " <div class=\"header-text-space\">\n",
85
+ " Total Cores\n",
86
+ " </div>\n",
87
+ " </div>\n",
88
+ " </div></th>\n",
89
+ " \n",
90
+ " \n",
91
+ " \n",
92
+ " <th class=\"product-table-sortable-col component medium-column tablesorter-header\" data-component=\"wa_skip_track\" data-component-id=\"1\" data-col=\"ClockSpeedMax\" role=\"columnheader\" aria-sort=\"\" aria-rowindex=\"1\" data-column=\"3\"><div class=\"tablesorter-header-inner\">\n",
93
+ " <div class=\"header-additional-padding\">\n",
94
+ " <div class=\"header-text-space\">\n",
95
+ " Max Turbo Frequency\n",
96
+ " </div>\n",
97
+ " </div>\n",
98
+ " </div></th>\n",
99
+ " \n",
100
+ " \n",
101
+ " \n",
102
+ " <th class=\"product-table-sortable-col component medium-column tablesorter-header\" data-component=\"wa_skip_track\" data-component-id=\"1\" data-col=\"ClockSpeed\" role=\"columnheader\" aria-sort=\"\" aria-rowindex=\"1\" data-column=\"4\"><div class=\"tablesorter-header-inner\">\n",
103
+ " <div class=\"header-additional-padding\">\n",
104
+ " <div class=\"header-text-space\">\n",
105
+ " Processor Base Frequency\n",
106
+ " </div>\n",
107
+ " </div>\n",
108
+ " </div></th>\n",
109
+ " \n",
110
+ " \n",
111
+ " \n",
112
+ " <th class=\"product-table-sortable-col component medium-column tablesorter-header\" data-component=\"wa_skip_track\" data-component-id=\"1\" data-col=\"Cache\" role=\"columnheader\" aria-sort=\"\" aria-rowindex=\"1\" data-column=\"5\"><div class=\"tablesorter-header-inner\">\n",
113
+ " <div class=\"header-additional-padding\">\n",
114
+ " <div class=\"header-text-space\">\n",
115
+ " Cache\n",
116
+ " </div>\n",
117
+ " </div>\n",
118
+ " </div></th>\n",
119
+ " \n",
120
+ " \n",
121
+ " \n",
122
+ " <th class=\"product-table-sortable-col component medium-column tablesorter-header\" data-component=\"wa_skip_track\" data-component-id=\"1\" data-col=\"MaxTDP\" role=\"columnheader\" aria-sort=\"\" aria-rowindex=\"1\" data-column=\"6\"><div class=\"tablesorter-header-inner\">\n",
123
+ " <div class=\"header-additional-padding\">\n",
124
+ " <div class=\"header-text-space\">\n",
125
+ " TDP\n",
126
+ " </div>\n",
127
+ " </div>\n",
128
+ " </div></th>\n",
129
+ " \n",
130
+ " \n",
131
+ " \n",
132
+ " </tr>\n",
133
+ " </thead>\n",
134
+ " <tbody>\n",
135
+ " \n",
136
+ " <tr class=\"blank-table-row seg-server seg-embedded seg-retailsku\" data-codename=\"Sapphire Rapids\" data-filter=\"Server\" data-product-id=\"236639\">\n",
137
+ "\n",
138
+ " \n",
139
+ " \n",
140
+ "\n",
141
+ " <td class=\"ark-product-name ark-accessible-color component\" data-value=\"1\" data-component=\"arkproductlink\" data-component-id=\"1\">\n",
142
+ " <div class=\"add-compare-wrap\">\n",
143
+ " <label class=\"containerCB component\" data-component=\"wa_skip_track\" data-component-id=\"1\">\n",
144
+ " <input class=\"compare-checkbox compare-toggle\" data-component=\"ark-component\" data-product-id=\"236639\" type=\"checkbox\">\n",
145
+ " <span class=\"checkmark\"></span>\n",
146
+ " </label>\n",
147
+ " <a href=\"/content/www/us/en/products/sku/236639/intel-xeon-bronze-3508u-processor-22-5m-cache-2-10-ghz/specifications.html\">Intel® Xeon® Bronze 3508U Processor</a>\n",
148
+ " </div>\n",
149
+ " </td>\n",
150
+ "\n",
151
+ " \n",
152
+ " \n",
153
+ " <td class=\"\" data-value=\"\">\n",
154
+ " \n",
155
+ " \n",
156
+ " \n",
157
+ " \n",
158
+ " \n",
159
+ " Q4'23\n",
160
+ " \n",
161
+ " \n",
162
+ " \n",
163
+ " </td>\n",
164
+ " \n",
165
+ " \n",
166
+ " \n",
167
+ " <td class=\"\" data-value=\"8\">\n",
168
+ " \n",
169
+ " \n",
170
+ " \n",
171
+ " \n",
172
+ " \n",
173
+ " 8\n",
174
+ " \n",
175
+ " \n",
176
+ " \n",
177
+ " </td>\n",
178
+ " \n",
179
+ " \n",
180
+ " \n",
181
+ " <td class=\"\" data-value=\"2200\">\n",
182
+ " \n",
183
+ " \n",
184
+ " \n",
185
+ " \n",
186
+ " \n",
187
+ " 2.2 GHz\n",
188
+ " \n",
189
+ " \n",
190
+ " \n",
191
+ " </td>\n",
192
+ " \n",
193
+ " \n",
194
+ " \n",
195
+ " <td class=\"\" data-value=\"2100\">\n",
196
+ " \n",
197
+ " \n",
198
+ " \n",
199
+ " \n",
200
+ " \n",
201
+ " 2.10 GHz\n",
202
+ " \n",
203
+ " \n",
204
+ " \n",
205
+ " </td>\n",
206
+ " \n",
207
+ " \n",
208
+ " \n",
209
+ " <td class=\"\" data-value=\"23040\">\n",
210
+ " \n",
211
+ " \n",
212
+ " \n",
213
+ " \n",
214
+ " \n",
215
+ " 22.5 MB\n",
216
+ " \n",
217
+ " \n",
218
+ " \n",
219
+ " </td>\n",
220
+ " \n",
221
+ " \n",
222
+ " \n",
223
+ " <td class=\"\" data-value=\"125\">\n",
224
+ " \n",
225
+ " \n",
226
+ " \n",
227
+ " \n",
228
+ " \n",
229
+ " 125 W\n",
230
+ " \n",
231
+ " \n",
232
+ " \n",
233
+ " </td>\n",
234
+ " \n",
235
+ " \n",
236
+ " </tr>\n",
237
+ " \n",
238
+ " ```"
239
+ ]
240
+ },
241
+ {
242
+ "cell_type": "markdown",
243
+ "metadata": {},
244
+ "source": [
245
+ "**AI Prompt**\n",
246
+ "\n",
247
+ "How to automate extraction ?"
248
+ ]
249
+ },
250
+ {
251
+ "cell_type": "markdown",
252
+ "metadata": {},
253
+ "source": [
254
+ "**AI Response**\n",
255
+ "\n",
256
+ "I see you're looking to extract CPU data from Intel's website. Before diving into the automation, I'd like to understand a few things:\n",
257
+ "\n",
258
+ "1. Are you comfortable with Python programming? \n",
259
+ "2. Have you tried web scraping before?\n",
260
+ "3. Would you prefer using a specific library (like BeautifulSoup, Scrapy, or Selenium)?\n",
261
+ "\n",
262
+ "This looks like a dynamic table with sortable columns, so we'll need to consider the best approach based on your experience level and requirements. Let me know your preferences, and I'll help guide you through the process."
263
+ ]
264
+ },
265
+ {
266
+ "cell_type": "markdown",
267
+ "metadata": {},
268
+ "source": [
269
+ "**AI Prompt**\n",
270
+ "\n",
271
+ "BeautifulSoup"
272
+ ]
273
+ },
274
+ {
275
+ "cell_type": "markdown",
276
+ "metadata": {},
277
+ "source": [
278
+ "**AI Response**\n",
279
+ "\n",
280
+ "Great choice! BeautifulSoup is perfect for this. Looking at the HTML you shared, we can extract the table data. Would you like me to:\n",
281
+ "\n",
282
+ "1. Help you write the code step by step, or\n",
283
+ "2. Provide a complete solution?\n",
284
+ "\n",
285
+ "Also, do you need to:\n",
286
+ "- Extract just this one page, or\n",
287
+ "- Navigate through multiple pages?\n",
288
+ "\n",
289
+ "Let me know your preference and I'll help accordingly."
290
+ ]
291
+ },
292
+ {
293
+ "cell_type": "markdown",
294
+ "metadata": {},
295
+ "source": [
296
+ "**AI Prompt**\n",
297
+ "\n",
298
+ "Extract just this one page"
299
+ ]
300
+ },
301
+ {
302
+ "cell_type": "markdown",
303
+ "metadata": {},
304
+ "source": [
305
+ "**AI Response**\n",
306
+ "\n",
307
+ "I'll help you extract data from this page. Let's break it down into steps:\n",
308
+ "\n",
309
+ "1. First, we'll need to set up BeautifulSoup and make the request. Would you like to start by writing the code to import the required libraries and fetch the page?\n",
310
+ "\n",
311
+ "The libraries we'll need are:\n",
312
+ "- `beautifulsoup4`\n",
313
+ "- `requests`\n",
314
+ "\n",
315
+ "Would you like to try writing this first part, or would you like me to show you how?"
316
+ ]
317
+ },
318
+ {
319
+ "cell_type": "markdown",
320
+ "metadata": {},
321
+ "source": [
322
+ "**AI Prompt**\n",
323
+ "\n",
324
+ "give me the code"
325
+ ]
326
+ },
327
+ {
328
+ "cell_type": "markdown",
329
+ "metadata": {},
330
+ "source": [
331
+ "**AI Response**\n",
332
+ "\n",
333
+ "Here's the code to get started:\n",
334
+ "\n",
335
+ "```python\n",
336
+ "import requests\n",
337
+ "from bs4 import BeautifulSoup\n",
338
+ "\n",
339
+ "url = \"https://www.intel.com/content/www/us/en/ark/products/series/236644/5th-gen-intel-xeon-scalable-processors.html\"\n",
340
+ "response = requests.get(url)\n",
341
+ "soup = BeautifulSoup(response.text, 'html.parser')\n",
342
+ "```\n",
343
+ "\n",
344
+ "Try running this code. Let me know if it works, and then we'll move on to extracting the table data. \n",
345
+ "\n",
346
+ "(Note: If you get any errors about missing libraries, you'll need to install them first using `pip install requests beautifulsoup4`)"
347
+ ]
348
+ },
349
+ {
350
+ "cell_type": "code",
351
+ "execution_count": null,
352
+ "metadata": {},
353
+ "outputs": [],
354
+ "source": [
355
+ "import requests\n",
356
+ "from bs4 import BeautifulSoup\n",
357
+ "\n",
358
+ "url = \"https://www.intel.com/content/www/us/en/ark/products/series/236644/5th-gen-intel-xeon-scalable-processors.html\"\n",
359
+ "response = requests.get(url)\n",
360
+ "soup = BeautifulSoup(response.text, \"html.parser\")"
361
+ ]
362
+ },
363
+ {
364
+ "cell_type": "markdown",
365
+ "metadata": {},
366
+ "source": [
367
+ "**AI Prompt**\n",
368
+ "\n",
369
+ "fine, give me the code to extract the data ?"
370
+ ]
371
+ },
372
+ {
373
+ "cell_type": "markdown",
374
+ "metadata": {},
375
+ "source": [
376
+ "**AI Response**\n",
377
+ "\n",
378
+ "Here's the code to extract the table data:\n",
379
+ "\n",
380
+ "```python\n",
381
+ "# Find the table\n",
382
+ "table = soup.find('table', id='product-table')\n",
383
+ "\n",
384
+ "# Extract headers\n",
385
+ "headers = []\n",
386
+ "for th in table.find_all('th'):\n",
387
+ " header_text = th.find('div', class_='header-text-space').text.strip()\n",
388
+ " headers.append(header_text)\n",
389
+ "\n",
390
+ "# Extract rows\n",
391
+ "data = []\n",
392
+ "for row in table.find('tbody').find_all('tr'):\n",
393
+ " row_data = {}\n",
394
+ " cells = row.find_all('td')\n",
395
+ " for i, cell in enumerate(cells):\n",
396
+ " row_data[headers[i]] = cell.text.strip()\n",
397
+ " data.append(row_data)\n",
398
+ "\n",
399
+ "# Convert to pandas DataFrame for easy viewing/export\n",
400
+ "import pandas as pd\n",
401
+ "df = pd.DataFrame(data)\n",
402
+ "print(df)\n",
403
+ "```\n",
404
+ "\n",
405
+ "Would you like me to explain how this code works, or would you prefer to see how to modify it for specific needs?"
406
+ ]
407
+ },
408
+ {
409
+ "cell_type": "code",
410
+ "execution_count": null,
411
+ "metadata": {},
412
+ "outputs": [
413
+ {
414
+ "name": "stdout",
415
+ "output_type": "stream",
416
+ "text": [
417
+ " Product Name Launch Date ... Cache TDP\n",
418
+ "0 Intel® Xeon® Bronze 3508U Processor Q4'23 ... 22.5 MB 125 W\n",
419
+ "1 Intel® Xeon® Gold 5512U Processor Q4'23 ... 52.5 MB 185 W\n",
420
+ "2 Intel® Xeon® Gold 5515+ Processor Q4'23 ... 22.5 MB 165 W\n",
421
+ "3 Intel® Xeon® Gold 5520+ Processor Q4'23 ... 52.5 MB 205 W\n",
422
+ "4 Intel® Xeon® Gold 6526Y Processor Q4'23 ... 37.5 MB 195 W\n",
423
+ "5 Intel® Xeon® Gold 6530 Processor Q4'23 ... 160 MB 270 W\n",
424
+ "6 Intel® Xeon® Gold 6534 Processor Q4'23 ... 22.5 MB 195 W\n",
425
+ "7 Intel® Xeon® Gold 6538N Processor Q4'23 ... 60 MB 205 W\n",
426
+ "8 Intel® Xeon® Gold 6538Y+ Processor Q4'23 ... 60 MB 225 W\n",
427
+ "9 Intel® Xeon® Gold 6542Y Processor Q4'23 ... 60 MB 250 W\n",
428
+ "10 Intel® Xeon® Gold 6544Y Processor Q4'23 ... 45 MB 270 W\n",
429
+ "11 Intel® Xeon® Gold 6548N Processor Q4'23 ... 60 MB 250 W\n",
430
+ "12 Intel® Xeon® Gold 6548Y+ Processor Q4'23 ... 60 MB 250 W\n",
431
+ "13 Intel® Xeon® Gold 6554S Processor Q4'23 ... 180 MB 270 W\n",
432
+ "14 Intel® Xeon® Gold 6558Q Processor Q4'23 ... 60 MB 350 W\n",
433
+ "15 Intel® Xeon® Platinum 8558 Processor Q4'23 ... 260 MB 330 W\n",
434
+ "16 Intel® Xeon® Platinum 8558P Processor Q4'23 ... 260 MB 350 W\n",
435
+ "17 Intel® Xeon® Platinum 8558U Processor Q4'23 ... 260 MB 300 W\n",
436
+ "18 Intel® Xeon® Platinum 8562Y+ Processor Q4'23 ... 60 MB 300 W\n",
437
+ "19 Intel® Xeon® Platinum 8568Y+ Processor Q4'23 ... 300 MB 350 W\n",
438
+ "20 Intel® Xeon® Platinum 8570 Processor Q4'23 ... 300 MB 350 W\n",
439
+ "21 Intel® Xeon® Platinum 8571N Processor Q4'23 ... 300 MB 300 W\n",
440
+ "22 Intel® Xeon® Platinum 8580 Processor Q4'23 ... 300 MB 350 W\n",
441
+ "23 Intel® Xeon® Platinum 8581V Processor Q4'23 ... 300 MB 270 W\n",
442
+ "24 Intel® Xeon® Platinum 8592+ Processor Q4'23 ... 320 MB 350 W\n",
443
+ "25 Intel® Xeon® Platinum 8592V Processor Q4'23 ... 320 MB 330 W\n",
444
+ "26 Intel® Xeon® Platinum 8593Q Processor Q4'23 ... 320 MB 385 W\n",
445
+ "27 Intel® Xeon® Silver 4509Y Processor Q4'23 ... 22.5 MB 125 W\n",
446
+ "28 Intel® Xeon® Silver 4510 Processor Q4'23 ... 30 MB 150 W\n",
447
+ "29 Intel® Xeon® Silver 4510T Processor Q4'23 ... 30 MB 115 W\n",
448
+ "30 Intel® Xeon® Silver 4514Y Processor Q4'23 ... 30 MB 150 W\n",
449
+ "31 Intel® Xeon® Silver 4516Y+ Processor Q4'23 ... 45 MB 185 W\n",
450
+ "\n",
451
+ "[32 rows x 7 columns]\n"
452
+ ]
453
+ }
454
+ ],
455
+ "source": [
456
+ "# Find the table\n",
457
+ "table = soup.find(\"table\", id=\"product-table\")\n",
458
+ "\n",
459
+ "# Extract headers\n",
460
+ "headers = []\n",
461
+ "for th in table.find_all(\"th\"):\n",
462
+ " header_text = th.find(\"div\", class_=\"header-text-space\").text.strip()\n",
463
+ " headers.append(header_text)\n",
464
+ "\n",
465
+ "# Extract rows\n",
466
+ "data = []\n",
467
+ "for row in table.find(\"tbody\").find_all(\"tr\"):\n",
468
+ " row_data = {}\n",
469
+ " cells = row.find_all(\"td\")\n",
470
+ " for i, cell in enumerate(cells):\n",
471
+ " row_data[headers[i]] = cell.text.strip()\n",
472
+ " data.append(row_data)\n",
473
+ "\n",
474
+ "# Convert to pandas DataFrame for easy viewing/export\n",
475
+ "import pandas as pd\n",
476
+ "\n",
477
+ "df = pd.DataFrame(data)\n",
478
+ "print(df)"
479
+ ]
480
+ },
481
+ {
482
+ "cell_type": "code",
483
+ "execution_count": null,
484
+ "metadata": {},
485
+ "outputs": [
486
+ {
487
+ "data": {
488
+ "text/plain": [
489
+ "0 125 W\n",
490
+ "1 185 W\n",
491
+ "2 165 W\n",
492
+ "3 205 W\n",
493
+ "4 195 W\n",
494
+ "5 270 W\n",
495
+ "6 195 W\n",
496
+ "7 205 W\n",
497
+ "8 225 W\n",
498
+ "9 250 W\n",
499
+ "10 270 W\n",
500
+ "11 250 W\n",
501
+ "12 250 W\n",
502
+ "13 270 W\n",
503
+ "14 350 W\n",
504
+ "15 330 W\n",
505
+ "16 350 W\n",
506
+ "17 300 W\n",
507
+ "18 300 W\n",
508
+ "19 350 W\n",
509
+ "20 350 W\n",
510
+ "21 300 W\n",
511
+ "22 350 W\n",
512
+ "23 270 W\n",
513
+ "24 350 W\n",
514
+ "25 330 W\n",
515
+ "26 385 W\n",
516
+ "27 125 W\n",
517
+ "28 150 W\n",
518
+ "29 115 W\n",
519
+ "30 150 W\n",
520
+ "31 185 W\n",
521
+ "Name: TDP, dtype: object"
522
+ ]
523
+ },
524
+ "execution_count": null,
525
+ "metadata": {},
526
+ "output_type": "execute_result"
527
+ }
528
+ ],
529
+ "source": [
530
+ "df[\"TDP\"].replace(\"W\", \"\")"
531
+ ]
532
+ },
533
+ {
534
+ "cell_type": "markdown",
535
+ "metadata": {},
536
+ "source": [
537
+ "## AMD"
538
+ ]
539
+ },
540
+ {
541
+ "cell_type": "code",
542
+ "execution_count": 24,
543
+ "metadata": {},
544
+ "outputs": [
545
+ {
546
+ "name": "stdout",
547
+ "output_type": "stream",
548
+ "text": [
549
+ "Average TDP per core from AMD dataset: 4.73 W\n"
550
+ ]
551
+ }
552
+ ],
553
+ "source": [
554
+ "import pandas as pd\n",
555
+ "\n",
556
+ "# Path to your manually exported AMD CPU dataset.\n",
557
+ "# (Adjust the file path as needed.)\n",
558
+ "amd_csv_path = \"./AMD_CPU_desktop_laptop.csv\"\n",
559
+ "\n",
560
+ "try:\n",
561
+ " amd_df = pd.read_csv(amd_csv_path)\n",
562
+ " amd_df = amd_df[amd_df[\"Launch Date\"].str.contains(\"2024|2025\", na=False)]\n",
563
+ " amd_df = amd_df[amd_df[\"Form Factor\"].str.contains(\"Desktops\", na=False)]\n",
564
+ "\n",
565
+ " # Convert columns to numeric, forcing errors to NaN\n",
566
+ " # amd_df['Default TDP'] = amd_df['Default TDP'].str.replace('W', '').astype(float)\n",
567
+ " amd_df[\"TDP\"] = pd.to_numeric(\n",
568
+ " amd_df[\"Default TDP\"].str.replace(\"W\", \"\"), errors=\"coerce\"\n",
569
+ " )\n",
570
+ " amd_df[\"# of Threads\"] = pd.to_numeric(amd_df[\"# of Threads\"], errors=\"coerce\")\n",
571
+ "\n",
572
+ " # It is assumed the CSV contains columns named 'TDP' (in Watts) and 'Total Cores'\n",
573
+ " # Adjust the column names if they differ.\n",
574
+ " amd_df[\"TDP_per_core\"] = amd_df[\"TDP\"] / amd_df[\"# of Threads\"]\n",
575
+ "\n",
576
+ " average_tdp_per_core = amd_df[\"TDP_per_core\"].mean()\n",
577
+ " print(\n",
578
+ " \"Average TDP per core from AMD dataset: {:.2f} W\".format(average_tdp_per_core)\n",
579
+ " )\n",
580
+ "except Exception as e:\n",
581
+ " print(\"Error loading or processing AMD dataset:\", e)"
582
+ ]
583
+ },
584
+ {
585
+ "cell_type": "code",
586
+ "execution_count": 28,
587
+ "metadata": {},
588
+ "outputs": [
589
+ {
590
+ "name": "stdout",
591
+ "output_type": "stream",
592
+ "text": [
593
+ "Average TDP per core from AMD dataset: 3.61 W\n"
594
+ ]
595
+ }
596
+ ],
597
+ "source": [
598
+ "# https://www.amd.com/en/products/specifications/server-processor.html\n",
599
+ "import pandas as pd\n",
600
+ "\n",
601
+ "# Path to your manually exported AMD CPU dataset.\n",
602
+ "# (Adjust the file path as needed.)\n",
603
+ "amd_csv_path = \"./AMD_Server_Processor_Specifications.csv\"\n",
604
+ "\n",
605
+ "try:\n",
606
+ " amd_df = pd.read_csv(amd_csv_path)\n",
607
+ " amd_df = amd_df[amd_df[\"Launch Date\"].str.contains(\"2024|2025\", na=False)]\n",
608
+ "\n",
609
+ " # Convert columns to numeric, forcing errors to NaN\n",
610
+ " # amd_df['Default TDP'] = amd_df['Default TDP'].str.replace('W', '').astype(float)\n",
611
+ " amd_df[\"TDP\"] = pd.to_numeric(\n",
612
+ " amd_df[\"Default TDP\"].str.replace(\"W\", \"\"), errors=\"coerce\"\n",
613
+ " )\n",
614
+ " amd_df[\"# of Threads\"] = pd.to_numeric(amd_df[\"# of Threads\"], errors=\"coerce\")\n",
615
+ "\n",
616
+ " # It is assumed the CSV contains columns named 'TDP' (in Watts) and 'Total Cores'\n",
617
+ " # Adjust the column names if they differ.\n",
618
+ " amd_df[\"TDP_per_core\"] = amd_df[\"TDP\"] / amd_df[\"# of Threads\"]\n",
619
+ "\n",
620
+ " average_tdp_per_core = amd_df[\"TDP_per_core\"].mean()\n",
621
+ " print(\n",
622
+ " \"Average TDP per core from AMD dataset: {:.2f} W\".format(average_tdp_per_core)\n",
623
+ " )\n",
624
+ "except Exception as e:\n",
625
+ " print(\"Error loading or processing AMD dataset:\", e)"
626
+ ]
627
+ },
628
+ {
629
+ "cell_type": "code",
630
+ "execution_count": 11,
631
+ "metadata": {},
632
+ "outputs": [
633
+ {
634
+ "data": {
635
+ "text/plain": [
636
+ "Index(['Name', 'Family', 'Series', 'Form Factor', '# of CPU Cores',\n",
637
+ " '# of Threads', 'Max. Boost Clock', 'Base Clock', 'L2 Cache',\n",
638
+ " 'L3 Cache', 'Default TDP', 'L1 Cache', 'AMD Configurable TDP (cTDP)',\n",
639
+ " 'Processor Technology for CPU Cores', 'Unlocked for Overclocking',\n",
640
+ " 'CPU Socket', 'Thermal Solution (PIB)', 'Recommended Cooler',\n",
641
+ " 'Thermal Solution (MPK)', 'Max. Operating Temperature (Tjmax)',\n",
642
+ " 'Launch Date', '*OS Support', 'PCI Express® Version',\n",
643
+ " 'System Memory Type', 'Memory Channels', 'System Memory Specification',\n",
644
+ " 'Graphics Model', 'Graphics Core Count', 'Graphics Frequency',\n",
645
+ " 'AMD Ryzen™ AI', 'Product ID Boxed', 'Product ID Tray',\n",
646
+ " 'Product ID MPK', 'Supported Technologies', 'TDP_per_core'],\n",
647
+ " dtype='object')"
648
+ ]
649
+ },
650
+ "execution_count": 11,
651
+ "metadata": {},
652
+ "output_type": "execute_result"
653
+ }
654
+ ],
655
+ "source": [
656
+ "amd_df.columns"
657
+ ]
658
+ },
659
+ {
660
+ "cell_type": "code",
661
+ "execution_count": 26,
662
+ "metadata": {},
663
+ "outputs": [
664
+ {
665
+ "data": {
666
+ "text/html": [
667
+ "<div>\n",
668
+ "<style scoped>\n",
669
+ " .dataframe tbody tr th:only-of-type {\n",
670
+ " vertical-align: middle;\n",
671
+ " }\n",
672
+ "\n",
673
+ " .dataframe tbody tr th {\n",
674
+ " vertical-align: top;\n",
675
+ " }\n",
676
+ "\n",
677
+ " .dataframe thead th {\n",
678
+ " text-align: right;\n",
679
+ " }\n",
680
+ "</style>\n",
681
+ "<table border=\"1\" class=\"dataframe\">\n",
682
+ " <thead>\n",
683
+ " <tr style=\"text-align: right;\">\n",
684
+ " <th></th>\n",
685
+ " <th>Name</th>\n",
686
+ " <th>TDP</th>\n",
687
+ " <th># of Threads</th>\n",
688
+ " <th>TDP_per_core</th>\n",
689
+ " <th>Launch Date</th>\n",
690
+ " </tr>\n",
691
+ " </thead>\n",
692
+ " <tbody>\n",
693
+ " <tr>\n",
694
+ " <th>34</th>\n",
695
+ " <td>AMD Ryzen™ 9 9950X</td>\n",
696
+ " <td>170</td>\n",
697
+ " <td>32.0</td>\n",
698
+ " <td>5.312500</td>\n",
699
+ " <td>08/15/2024</td>\n",
700
+ " </tr>\n",
701
+ " <tr>\n",
702
+ " <th>36</th>\n",
703
+ " <td>AMD Ryzen™ 9 9900X</td>\n",
704
+ " <td>120</td>\n",
705
+ " <td>24.0</td>\n",
706
+ " <td>5.000000</td>\n",
707
+ " <td>08/15/2024</td>\n",
708
+ " </tr>\n",
709
+ " <tr>\n",
710
+ " <th>38</th>\n",
711
+ " <td>AMD Ryzen™ 7 9800X3D</td>\n",
712
+ " <td>120</td>\n",
713
+ " <td>16.0</td>\n",
714
+ " <td>7.500000</td>\n",
715
+ " <td>11/07/2024</td>\n",
716
+ " </tr>\n",
717
+ " <tr>\n",
718
+ " <th>39</th>\n",
719
+ " <td>AMD Ryzen™ 7 9700X</td>\n",
720
+ " <td>65</td>\n",
721
+ " <td>16.0</td>\n",
722
+ " <td>4.062500</td>\n",
723
+ " <td>08/08/2024</td>\n",
724
+ " </tr>\n",
725
+ " <tr>\n",
726
+ " <th>40</th>\n",
727
+ " <td>AMD Ryzen™ 5 9600X</td>\n",
728
+ " <td>65</td>\n",
729
+ " <td>12.0</td>\n",
730
+ " <td>5.416667</td>\n",
731
+ " <td>08/08/2024</td>\n",
732
+ " </tr>\n",
733
+ " <tr>\n",
734
+ " <th>44</th>\n",
735
+ " <td>AMD Ryzen™ 7 PRO 8845HS</td>\n",
736
+ " <td>45</td>\n",
737
+ " <td>16.0</td>\n",
738
+ " <td>2.812500</td>\n",
739
+ " <td>04/16/2024</td>\n",
740
+ " </tr>\n",
741
+ " <tr>\n",
742
+ " <th>46</th>\n",
743
+ " <td>AMD Ryzen™ 7 PRO 8700GE</td>\n",
744
+ " <td>35</td>\n",
745
+ " <td>16.0</td>\n",
746
+ " <td>2.187500</td>\n",
747
+ " <td>4/16/2024</td>\n",
748
+ " </tr>\n",
749
+ " <tr>\n",
750
+ " <th>47</th>\n",
751
+ " <td>AMD Ryzen™ 7 PRO 8700G</td>\n",
752
+ " <td>65</td>\n",
753
+ " <td>16.0</td>\n",
754
+ " <td>4.062500</td>\n",
755
+ " <td>4/16/2024</td>\n",
756
+ " </tr>\n",
757
+ " <tr>\n",
758
+ " <th>51</th>\n",
759
+ " <td>AMD Ryzen™ 5 PRO 8600GE</td>\n",
760
+ " <td>35</td>\n",
761
+ " <td>12.0</td>\n",
762
+ " <td>2.916667</td>\n",
763
+ " <td>4/16/2024</td>\n",
764
+ " </tr>\n",
765
+ " <tr>\n",
766
+ " <th>52</th>\n",
767
+ " <td>AMD Ryzen™ 5 PRO 8600G</td>\n",
768
+ " <td>65</td>\n",
769
+ " <td>12.0</td>\n",
770
+ " <td>5.416667</td>\n",
771
+ " <td>4/16/2024</td>\n",
772
+ " </tr>\n",
773
+ " <tr>\n",
774
+ " <th>54</th>\n",
775
+ " <td>AMD Ryzen™ 5 PRO 8500GE</td>\n",
776
+ " <td>35</td>\n",
777
+ " <td>12.0</td>\n",
778
+ " <td>2.916667</td>\n",
779
+ " <td>4/16/2024</td>\n",
780
+ " </tr>\n",
781
+ " <tr>\n",
782
+ " <th>55</th>\n",
783
+ " <td>AMD Ryzen™ 5 PRO 8500G</td>\n",
784
+ " <td>65</td>\n",
785
+ " <td>12.0</td>\n",
786
+ " <td>5.416667</td>\n",
787
+ " <td>4/16/2024</td>\n",
788
+ " </tr>\n",
789
+ " <tr>\n",
790
+ " <th>57</th>\n",
791
+ " <td>AMD Ryzen™ 3 PRO 8300GE</td>\n",
792
+ " <td>35</td>\n",
793
+ " <td>8.0</td>\n",
794
+ " <td>4.375000</td>\n",
795
+ " <td>4/16/2024</td>\n",
796
+ " </tr>\n",
797
+ " <tr>\n",
798
+ " <th>58</th>\n",
799
+ " <td>AMD Ryzen™ 3 PRO 8300G</td>\n",
800
+ " <td>65</td>\n",
801
+ " <td>8.0</td>\n",
802
+ " <td>8.125000</td>\n",
803
+ " <td>4/16/2024</td>\n",
804
+ " </tr>\n",
805
+ " <tr>\n",
806
+ " <th>62</th>\n",
807
+ " <td>AMD Ryzen™ 7 8700G</td>\n",
808
+ " <td>65</td>\n",
809
+ " <td>16.0</td>\n",
810
+ " <td>4.062500</td>\n",
811
+ " <td>1/31/2024</td>\n",
812
+ " </tr>\n",
813
+ " <tr>\n",
814
+ " <th>63</th>\n",
815
+ " <td>AMD Ryzen™ 7 8700F</td>\n",
816
+ " <td>65</td>\n",
817
+ " <td>16.0</td>\n",
818
+ " <td>4.062500</td>\n",
819
+ " <td>04/01/2024</td>\n",
820
+ " </tr>\n",
821
+ " <tr>\n",
822
+ " <th>67</th>\n",
823
+ " <td>AMD Ryzen™ 5 8600G</td>\n",
824
+ " <td>65</td>\n",
825
+ " <td>12.0</td>\n",
826
+ " <td>5.416667</td>\n",
827
+ " <td>1/31/2024</td>\n",
828
+ " </tr>\n",
829
+ " <tr>\n",
830
+ " <th>69</th>\n",
831
+ " <td>AMD Ryzen™ 5 8500GE</td>\n",
832
+ " <td>35</td>\n",
833
+ " <td>12.0</td>\n",
834
+ " <td>2.916667</td>\n",
835
+ " <td>4/16/2024</td>\n",
836
+ " </tr>\n",
837
+ " <tr>\n",
838
+ " <th>70</th>\n",
839
+ " <td>AMD Ryzen™ 5 8500G</td>\n",
840
+ " <td>65</td>\n",
841
+ " <td>12.0</td>\n",
842
+ " <td>5.416667</td>\n",
843
+ " <td>1/31/2024</td>\n",
844
+ " </tr>\n",
845
+ " <tr>\n",
846
+ " <th>72</th>\n",
847
+ " <td>AMD Ryzen™ 3 8300GE</td>\n",
848
+ " <td>35</td>\n",
849
+ " <td>8.0</td>\n",
850
+ " <td>4.375000</td>\n",
851
+ " <td>4/16/2024</td>\n",
852
+ " </tr>\n",
853
+ " <tr>\n",
854
+ " <th>73</th>\n",
855
+ " <td>AMD Ryzen™ 5 8400F</td>\n",
856
+ " <td>65</td>\n",
857
+ " <td>12.0</td>\n",
858
+ " <td>5.416667</td>\n",
859
+ " <td>04/01/2024</td>\n",
860
+ " </tr>\n",
861
+ " <tr>\n",
862
+ " <th>74</th>\n",
863
+ " <td>AMD Ryzen™ 3 8300G</td>\n",
864
+ " <td>65</td>\n",
865
+ " <td>8.0</td>\n",
866
+ " <td>8.125000</td>\n",
867
+ " <td>1/31/2024</td>\n",
868
+ " </tr>\n",
869
+ " <tr>\n",
870
+ " <th>105</th>\n",
871
+ " <td>AMD Ryzen™ 9 7940HX</td>\n",
872
+ " <td>55</td>\n",
873
+ " <td>32.0</td>\n",
874
+ " <td>1.718750</td>\n",
875
+ " <td>1/17/2024</td>\n",
876
+ " </tr>\n",
877
+ " <tr>\n",
878
+ " <th>111</th>\n",
879
+ " <td>AMD Ryzen™ 7 7840HX</td>\n",
880
+ " <td>55</td>\n",
881
+ " <td>24.0</td>\n",
882
+ " <td>2.291667</td>\n",
883
+ " <td>1/17/2024</td>\n",
884
+ " </tr>\n",
885
+ " <tr>\n",
886
+ " <th>124</th>\n",
887
+ " <td>AMD Ryzen™ 5 7600X3D</td>\n",
888
+ " <td>65</td>\n",
889
+ " <td>12.0</td>\n",
890
+ " <td>5.416667</td>\n",
891
+ " <td>9/5/2024</td>\n",
892
+ " </tr>\n",
893
+ " <tr>\n",
894
+ " <th>138</th>\n",
895
+ " <td>AMD Ryzen™ 5 7400F</td>\n",
896
+ " <td>65</td>\n",
897
+ " <td>12.0</td>\n",
898
+ " <td>5.416667</td>\n",
899
+ " <td>1/9/2025</td>\n",
900
+ " </tr>\n",
901
+ " <tr>\n",
902
+ " <th>178</th>\n",
903
+ " <td>AMD Ryzen™ 7 PRO 5755GE</td>\n",
904
+ " <td>35</td>\n",
905
+ " <td>16.0</td>\n",
906
+ " <td>2.187500</td>\n",
907
+ " <td>9/5/2024</td>\n",
908
+ " </tr>\n",
909
+ " <tr>\n",
910
+ " <th>179</th>\n",
911
+ " <td>AMD Ryzen™ 7 PRO 5755G</td>\n",
912
+ " <td>65</td>\n",
913
+ " <td>16.0</td>\n",
914
+ " <td>4.062500</td>\n",
915
+ " <td>9/5/2024</td>\n",
916
+ " </tr>\n",
917
+ " <tr>\n",
918
+ " <th>183</th>\n",
919
+ " <td>AMD Ryzen™ 5 PRO 5655GE</td>\n",
920
+ " <td>35</td>\n",
921
+ " <td>12.0</td>\n",
922
+ " <td>2.916667</td>\n",
923
+ " <td>5/7/2024</td>\n",
924
+ " </tr>\n",
925
+ " <tr>\n",
926
+ " <th>184</th>\n",
927
+ " <td>AMD Ryzen™ 5 PRO 5655G</td>\n",
928
+ " <td>65</td>\n",
929
+ " <td>12.0</td>\n",
930
+ " <td>5.416667</td>\n",
931
+ " <td>5/7/2024</td>\n",
932
+ " </tr>\n",
933
+ " <tr>\n",
934
+ " <th>191</th>\n",
935
+ " <td>AMD Ryzen™ 3 PRO 5355GE</td>\n",
936
+ " <td>35</td>\n",
937
+ " <td>8.0</td>\n",
938
+ " <td>4.375000</td>\n",
939
+ " <td>9/5/2024</td>\n",
940
+ " </tr>\n",
941
+ " <tr>\n",
942
+ " <th>192</th>\n",
943
+ " <td>AMD Ryzen™ 3 PRO 5355G</td>\n",
944
+ " <td>65</td>\n",
945
+ " <td>8.0</td>\n",
946
+ " <td>8.125000</td>\n",
947
+ " <td>9/5/2024</td>\n",
948
+ " </tr>\n",
949
+ " <tr>\n",
950
+ " <th>198</th>\n",
951
+ " <td>AMD Ryzen™ 9 5900XT</td>\n",
952
+ " <td>105</td>\n",
953
+ " <td>32.0</td>\n",
954
+ " <td>3.281250</td>\n",
955
+ " <td>07/31/2024</td>\n",
956
+ " </tr>\n",
957
+ " <tr>\n",
958
+ " <th>206</th>\n",
959
+ " <td>AMD Ryzen™ 7 5800XT</td>\n",
960
+ " <td>105</td>\n",
961
+ " <td>16.0</td>\n",
962
+ " <td>6.562500</td>\n",
963
+ " <td>07/31/2024</td>\n",
964
+ " </tr>\n",
965
+ " <tr>\n",
966
+ " <th>214</th>\n",
967
+ " <td>AMD Ryzen™ 7 5700X3D</td>\n",
968
+ " <td>105</td>\n",
969
+ " <td>16.0</td>\n",
970
+ " <td>6.562500</td>\n",
971
+ " <td>01/08/2024</td>\n",
972
+ " </tr>\n",
973
+ " <tr>\n",
974
+ " <th>219</th>\n",
975
+ " <td>AMD Ryzen™ 7 5700</td>\n",
976
+ " <td>65</td>\n",
977
+ " <td>16.0</td>\n",
978
+ " <td>4.062500</td>\n",
979
+ " <td>01/31/2024</td>\n",
980
+ " </tr>\n",
981
+ " <tr>\n",
982
+ " <th>229</th>\n",
983
+ " <td>AMD Ryzen™ 5 5600XT</td>\n",
984
+ " <td>65</td>\n",
985
+ " <td>12.0</td>\n",
986
+ " <td>5.416667</td>\n",
987
+ " <td>10/31/2024</td>\n",
988
+ " </tr>\n",
989
+ " <tr>\n",
990
+ " <th>230</th>\n",
991
+ " <td>AMD Ryzen™ 5 5600T</td>\n",
992
+ " <td>65</td>\n",
993
+ " <td>12.0</td>\n",
994
+ " <td>5.416667</td>\n",
995
+ " <td>10/31/2024</td>\n",
996
+ " </tr>\n",
997
+ " <tr>\n",
998
+ " <th>231</th>\n",
999
+ " <td>AMD Ryzen™ 5 5600GT</td>\n",
1000
+ " <td>65</td>\n",
1001
+ " <td>12.0</td>\n",
1002
+ " <td>5.416667</td>\n",
1003
+ " <td>01/08/2024</td>\n",
1004
+ " </tr>\n",
1005
+ " <tr>\n",
1006
+ " <th>238</th>\n",
1007
+ " <td>AMD Ryzen™ 5 5500GT</td>\n",
1008
+ " <td>65</td>\n",
1009
+ " <td>12.0</td>\n",
1010
+ " <td>5.416667</td>\n",
1011
+ " <td>01/08/2024</td>\n",
1012
+ " </tr>\n",
1013
+ " </tbody>\n",
1014
+ "</table>\n",
1015
+ "</div>"
1016
+ ],
1017
+ "text/plain": [
1018
+ " Name TDP # of Threads TDP_per_core Launch Date\n",
1019
+ "34 AMD Ryzen™ 9 9950X 170 32.0 5.312500 08/15/2024\n",
1020
+ "36 AMD Ryzen™ 9 9900X 120 24.0 5.000000 08/15/2024\n",
1021
+ "38 AMD Ryzen™ 7 9800X3D 120 16.0 7.500000 11/07/2024\n",
1022
+ "39 AMD Ryzen™ 7 9700X 65 16.0 4.062500 08/08/2024\n",
1023
+ "40 AMD Ryzen™ 5 9600X 65 12.0 5.416667 08/08/2024\n",
1024
+ "44 AMD Ryzen™ 7 PRO 8845HS 45 16.0 2.812500 04/16/2024\n",
1025
+ "46 AMD Ryzen™ 7 PRO 8700GE 35 16.0 2.187500 4/16/2024\n",
1026
+ "47 AMD Ryzen™ 7 PRO 8700G 65 16.0 4.062500 4/16/2024\n",
1027
+ "51 AMD Ryzen™ 5 PRO 8600GE 35 12.0 2.916667 4/16/2024\n",
1028
+ "52 AMD Ryzen™ 5 PRO 8600G 65 12.0 5.416667 4/16/2024\n",
1029
+ "54 AMD Ryzen™ 5 PRO 8500GE 35 12.0 2.916667 4/16/2024\n",
1030
+ "55 AMD Ryzen™ 5 PRO 8500G 65 12.0 5.416667 4/16/2024\n",
1031
+ "57 AMD Ryzen™ 3 PRO 8300GE 35 8.0 4.375000 4/16/2024\n",
1032
+ "58 AMD Ryzen™ 3 PRO 8300G 65 8.0 8.125000 4/16/2024\n",
1033
+ "62 AMD Ryzen™ 7 8700G 65 16.0 4.062500 1/31/2024\n",
1034
+ "63 AMD Ryzen™ 7 8700F 65 16.0 4.062500 04/01/2024\n",
1035
+ "67 AMD Ryzen™ 5 8600G 65 12.0 5.416667 1/31/2024\n",
1036
+ "69 AMD Ryzen™ 5 8500GE 35 12.0 2.916667 4/16/2024\n",
1037
+ "70 AMD Ryzen™ 5 8500G 65 12.0 5.416667 1/31/2024\n",
1038
+ "72 AMD Ryzen™ 3 8300GE 35 8.0 4.375000 4/16/2024\n",
1039
+ "73 AMD Ryzen™ 5 8400F 65 12.0 5.416667 04/01/2024\n",
1040
+ "74 AMD Ryzen™ 3 8300G 65 8.0 8.125000 1/31/2024\n",
1041
+ "105 AMD Ryzen™ 9 7940HX 55 32.0 1.718750 1/17/2024\n",
1042
+ "111 AMD Ryzen™ 7 7840HX 55 24.0 2.291667 1/17/2024\n",
1043
+ "124 AMD Ryzen™ 5 7600X3D 65 12.0 5.416667 9/5/2024\n",
1044
+ "138 AMD Ryzen™ 5 7400F 65 12.0 5.416667 1/9/2025\n",
1045
+ "178 AMD Ryzen™ 7 PRO 5755GE 35 16.0 2.187500 9/5/2024\n",
1046
+ "179 AMD Ryzen™ 7 PRO 5755G 65 16.0 4.062500 9/5/2024\n",
1047
+ "183 AMD Ryzen™ 5 PRO 5655GE 35 12.0 2.916667 5/7/2024\n",
1048
+ "184 AMD Ryzen™ 5 PRO 5655G 65 12.0 5.416667 5/7/2024\n",
1049
+ "191 AMD Ryzen™ 3 PRO 5355GE 35 8.0 4.375000 9/5/2024\n",
1050
+ "192 AMD Ryzen™ 3 PRO 5355G 65 8.0 8.125000 9/5/2024\n",
1051
+ "198 AMD Ryzen™ 9 5900XT 105 32.0 3.281250 07/31/2024\n",
1052
+ "206 AMD Ryzen™ 7 5800XT 105 16.0 6.562500 07/31/2024\n",
1053
+ "214 AMD Ryzen™ 7 5700X3D 105 16.0 6.562500 01/08/2024\n",
1054
+ "219 AMD Ryzen™ 7 5700 65 16.0 4.062500 01/31/2024\n",
1055
+ "229 AMD Ryzen™ 5 5600XT 65 12.0 5.416667 10/31/2024\n",
1056
+ "230 AMD Ryzen™ 5 5600T 65 12.0 5.416667 10/31/2024\n",
1057
+ "231 AMD Ryzen™ 5 5600GT 65 12.0 5.416667 01/08/2024\n",
1058
+ "238 AMD Ryzen™ 5 5500GT 65 12.0 5.416667 01/08/2024"
1059
+ ]
1060
+ },
1061
+ "execution_count": 26,
1062
+ "metadata": {},
1063
+ "output_type": "execute_result"
1064
+ }
1065
+ ],
1066
+ "source": [
1067
+ "amd_df[[\"Name\", \"TDP\", \"# of Threads\", \"TDP_per_core\", \"Launch Date\"]]"
1068
+ ]
1069
+ },
1070
+ {
1071
+ "cell_type": "markdown",
1072
+ "metadata": {},
1073
+ "source": [
1074
+ "# Update the static CodeCarbon database"
1075
+ ]
1076
+ },
1077
+ {
1078
+ "cell_type": "code",
1079
+ "execution_count": 64,
1080
+ "metadata": {},
1081
+ "outputs": [
1082
+ {
1083
+ "data": {
1084
+ "text/html": [
1085
+ "<div>\n",
1086
+ "<style scoped>\n",
1087
+ " .dataframe tbody tr th:only-of-type {\n",
1088
+ " vertical-align: middle;\n",
1089
+ " }\n",
1090
+ "\n",
1091
+ " .dataframe tbody tr th {\n",
1092
+ " vertical-align: top;\n",
1093
+ " }\n",
1094
+ "\n",
1095
+ " .dataframe thead th {\n",
1096
+ " text-align: right;\n",
1097
+ " }\n",
1098
+ "</style>\n",
1099
+ "<table border=\"1\" class=\"dataframe\">\n",
1100
+ " <thead>\n",
1101
+ " <tr style=\"text-align: right;\">\n",
1102
+ " <th></th>\n",
1103
+ " <th>Name</th>\n",
1104
+ " <th>TDP</th>\n",
1105
+ " </tr>\n",
1106
+ " </thead>\n",
1107
+ " <tbody>\n",
1108
+ " <tr>\n",
1109
+ " <th>0</th>\n",
1110
+ " <td>1075T</td>\n",
1111
+ " <td>95</td>\n",
1112
+ " </tr>\n",
1113
+ " <tr>\n",
1114
+ " <th>1</th>\n",
1115
+ " <td>255e</td>\n",
1116
+ " <td>45</td>\n",
1117
+ " </tr>\n",
1118
+ " <tr>\n",
1119
+ " <th>2</th>\n",
1120
+ " <td>3260 HE</td>\n",
1121
+ " <td>45</td>\n",
1122
+ " </tr>\n",
1123
+ " <tr>\n",
1124
+ " <th>3</th>\n",
1125
+ " <td>3280</td>\n",
1126
+ " <td>65</td>\n",
1127
+ " </tr>\n",
1128
+ " <tr>\n",
1129
+ " <th>4</th>\n",
1130
+ " <td>3320 EE</td>\n",
1131
+ " <td>25</td>\n",
1132
+ " </tr>\n",
1133
+ " <tr>\n",
1134
+ " <th>...</th>\n",
1135
+ " <td>...</td>\n",
1136
+ " <td>...</td>\n",
1137
+ " </tr>\n",
1138
+ " <tr>\n",
1139
+ " <th>3923</th>\n",
1140
+ " <td>TL-52</td>\n",
1141
+ " <td>31</td>\n",
1142
+ " </tr>\n",
1143
+ " <tr>\n",
1144
+ " <th>3924</th>\n",
1145
+ " <td>TL-60</td>\n",
1146
+ " <td>31</td>\n",
1147
+ " </tr>\n",
1148
+ " <tr>\n",
1149
+ " <th>3925</th>\n",
1150
+ " <td>TL-64</td>\n",
1151
+ " <td>35</td>\n",
1152
+ " </tr>\n",
1153
+ " <tr>\n",
1154
+ " <th>3926</th>\n",
1155
+ " <td>X1150</td>\n",
1156
+ " <td>17</td>\n",
1157
+ " </tr>\n",
1158
+ " <tr>\n",
1159
+ " <th>3927</th>\n",
1160
+ " <td>X940</td>\n",
1161
+ " <td>45</td>\n",
1162
+ " </tr>\n",
1163
+ " </tbody>\n",
1164
+ "</table>\n",
1165
+ "<p>3928 rows × 2 columns</p>\n",
1166
+ "</div>"
1167
+ ],
1168
+ "text/plain": [
1169
+ " Name TDP\n",
1170
+ "0 1075T 95\n",
1171
+ "1 255e 45\n",
1172
+ "2 3260 HE 45\n",
1173
+ "3 3280 65\n",
1174
+ "4 3320 EE 25\n",
1175
+ "... ... ..\n",
1176
+ "3923 TL-52 31\n",
1177
+ "3924 TL-60 31\n",
1178
+ "3925 TL-64 35\n",
1179
+ "3926 X1150 17\n",
1180
+ "3927 X940 45\n",
1181
+ "\n",
1182
+ "[3928 rows x 2 columns]"
1183
+ ]
1184
+ },
1185
+ "execution_count": 64,
1186
+ "metadata": {},
1187
+ "output_type": "execute_result"
1188
+ }
1189
+ ],
1190
+ "source": [
1191
+ "df = pd.read_csv(\"cpu_power.csv\")\n",
1192
+ "df"
1193
+ ]
1194
+ },
1195
+ {
1196
+ "cell_type": "code",
1197
+ "execution_count": 65,
1198
+ "metadata": {},
1199
+ "outputs": [
1200
+ {
1201
+ "data": {
1202
+ "text/html": [
1203
+ "<div>\n",
1204
+ "<style scoped>\n",
1205
+ " .dataframe tbody tr th:only-of-type {\n",
1206
+ " vertical-align: middle;\n",
1207
+ " }\n",
1208
+ "\n",
1209
+ " .dataframe tbody tr th {\n",
1210
+ " vertical-align: top;\n",
1211
+ " }\n",
1212
+ "\n",
1213
+ " .dataframe thead th {\n",
1214
+ " text-align: right;\n",
1215
+ " }\n",
1216
+ "</style>\n",
1217
+ "<table border=\"1\" class=\"dataframe\">\n",
1218
+ " <thead>\n",
1219
+ " <tr style=\"text-align: right;\">\n",
1220
+ " <th></th>\n",
1221
+ " <th>Name</th>\n",
1222
+ " <th>TDP</th>\n",
1223
+ " </tr>\n",
1224
+ " </thead>\n",
1225
+ " <tbody>\n",
1226
+ " <tr>\n",
1227
+ " <th>0</th>\n",
1228
+ " <td>AMD EPYC 9965</td>\n",
1229
+ " <td>500.0</td>\n",
1230
+ " </tr>\n",
1231
+ " <tr>\n",
1232
+ " <th>1</th>\n",
1233
+ " <td>AMD EPYC 9845</td>\n",
1234
+ " <td>390.0</td>\n",
1235
+ " </tr>\n",
1236
+ " <tr>\n",
1237
+ " <th>2</th>\n",
1238
+ " <td>AMD EPYC 9825</td>\n",
1239
+ " <td>390.0</td>\n",
1240
+ " </tr>\n",
1241
+ " </tbody>\n",
1242
+ "</table>\n",
1243
+ "</div>"
1244
+ ],
1245
+ "text/plain": [
1246
+ " Name TDP\n",
1247
+ "0 AMD EPYC 9965 500.0\n",
1248
+ "1 AMD EPYC 9845 390.0\n",
1249
+ "2 AMD EPYC 9825 390.0"
1250
+ ]
1251
+ },
1252
+ "execution_count": 65,
1253
+ "metadata": {},
1254
+ "output_type": "execute_result"
1255
+ }
1256
+ ],
1257
+ "source": [
1258
+ "amd_csv_path = \"./AMD_Server_Processor_Specifications.csv\"\n",
1259
+ "amd_df = pd.read_csv(amd_csv_path)\n",
1260
+ "amd_df[\"TDP\"] = pd.to_numeric(\n",
1261
+ " amd_df[\"Default TDP\"].str.replace(\"W\", \"\"), errors=\"coerce\"\n",
1262
+ ")\n",
1263
+ "amd_df[\"Name\"] = amd_df[\"Name\"].str.replace(\"™\", \"\")\n",
1264
+ "amd_server = amd_df[[\"Name\", \"TDP\"]]\n",
1265
+ "amd_server = amd_server.dropna(subset=[\"TDP\"])\n",
1266
+ "amd_server.head(3)"
1267
+ ]
1268
+ },
1269
+ {
1270
+ "cell_type": "code",
1271
+ "execution_count": 66,
1272
+ "metadata": {},
1273
+ "outputs": [
1274
+ {
1275
+ "name": "stderr",
1276
+ "output_type": "stream",
1277
+ "text": [
1278
+ "/tmp/ipykernel_52381/4222190993.py:6: SettingWithCopyWarning: \n",
1279
+ "A value is trying to be set on a copy of a slice from a DataFrame.\n",
1280
+ "Try using .loc[row_indexer,col_indexer] = value instead\n",
1281
+ "\n",
1282
+ "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
1283
+ " new_cpus['TDP'] = new_cpus['TDP_AMD']\n"
1284
+ ]
1285
+ },
1286
+ {
1287
+ "data": {
1288
+ "text/html": [
1289
+ "<div>\n",
1290
+ "<style scoped>\n",
1291
+ " .dataframe tbody tr th:only-of-type {\n",
1292
+ " vertical-align: middle;\n",
1293
+ " }\n",
1294
+ "\n",
1295
+ " .dataframe tbody tr th {\n",
1296
+ " vertical-align: top;\n",
1297
+ " }\n",
1298
+ "\n",
1299
+ " .dataframe thead th {\n",
1300
+ " text-align: right;\n",
1301
+ " }\n",
1302
+ "</style>\n",
1303
+ "<table border=\"1\" class=\"dataframe\">\n",
1304
+ " <thead>\n",
1305
+ " <tr style=\"text-align: right;\">\n",
1306
+ " <th></th>\n",
1307
+ " <th>Name</th>\n",
1308
+ " <th>TDP</th>\n",
1309
+ " <th>TDP_AMD</th>\n",
1310
+ " <th>_merge</th>\n",
1311
+ " </tr>\n",
1312
+ " </thead>\n",
1313
+ " <tbody>\n",
1314
+ " <tr>\n",
1315
+ " <th>505</th>\n",
1316
+ " <td>AMD EPYC 4124P</td>\n",
1317
+ " <td>65</td>\n",
1318
+ " <td>65</td>\n",
1319
+ " <td>right_only</td>\n",
1320
+ " </tr>\n",
1321
+ " <tr>\n",
1322
+ " <th>506</th>\n",
1323
+ " <td>AMD EPYC 4244P</td>\n",
1324
+ " <td>65</td>\n",
1325
+ " <td>65</td>\n",
1326
+ " <td>right_only</td>\n",
1327
+ " </tr>\n",
1328
+ " <tr>\n",
1329
+ " <th>507</th>\n",
1330
+ " <td>AMD EPYC 4344P</td>\n",
1331
+ " <td>65</td>\n",
1332
+ " <td>65</td>\n",
1333
+ " <td>right_only</td>\n",
1334
+ " </tr>\n",
1335
+ " <tr>\n",
1336
+ " <th>508</th>\n",
1337
+ " <td>AMD EPYC 4364P</td>\n",
1338
+ " <td>105</td>\n",
1339
+ " <td>105</td>\n",
1340
+ " <td>right_only</td>\n",
1341
+ " </tr>\n",
1342
+ " <tr>\n",
1343
+ " <th>509</th>\n",
1344
+ " <td>AMD EPYC 4464P</td>\n",
1345
+ " <td>65</td>\n",
1346
+ " <td>65</td>\n",
1347
+ " <td>right_only</td>\n",
1348
+ " </tr>\n",
1349
+ " <tr>\n",
1350
+ " <th>...</th>\n",
1351
+ " <td>...</td>\n",
1352
+ " <td>...</td>\n",
1353
+ " <td>...</td>\n",
1354
+ " <td>...</td>\n",
1355
+ " </tr>\n",
1356
+ " <tr>\n",
1357
+ " <th>752</th>\n",
1358
+ " <td>AMD Opteron 6328</td>\n",
1359
+ " <td>115</td>\n",
1360
+ " <td>115</td>\n",
1361
+ " <td>right_only</td>\n",
1362
+ " </tr>\n",
1363
+ " <tr>\n",
1364
+ " <th>753</th>\n",
1365
+ " <td>AMD Opteron 6338P</td>\n",
1366
+ " <td>99</td>\n",
1367
+ " <td>99</td>\n",
1368
+ " <td>right_only</td>\n",
1369
+ " </tr>\n",
1370
+ " <tr>\n",
1371
+ " <th>754</th>\n",
1372
+ " <td>AMD Opteron 6344</td>\n",
1373
+ " <td>115</td>\n",
1374
+ " <td>115</td>\n",
1375
+ " <td>right_only</td>\n",
1376
+ " </tr>\n",
1377
+ " <tr>\n",
1378
+ " <th>757</th>\n",
1379
+ " <td>AMD Opteron 6370P</td>\n",
1380
+ " <td>99</td>\n",
1381
+ " <td>99</td>\n",
1382
+ " <td>right_only</td>\n",
1383
+ " </tr>\n",
1384
+ " <tr>\n",
1385
+ " <th>807</th>\n",
1386
+ " <td>AMD Opteron X2170 APU</td>\n",
1387
+ " <td>25</td>\n",
1388
+ " <td>25</td>\n",
1389
+ " <td>right_only</td>\n",
1390
+ " </tr>\n",
1391
+ " </tbody>\n",
1392
+ "</table>\n",
1393
+ "<p>113 rows × 4 columns</p>\n",
1394
+ "</div>"
1395
+ ],
1396
+ "text/plain": [
1397
+ " Name TDP TDP_AMD _merge\n",
1398
+ "505 AMD EPYC 4124P 65 65 right_only\n",
1399
+ "506 AMD EPYC 4244P 65 65 right_only\n",
1400
+ "507 AMD EPYC 4344P 65 65 right_only\n",
1401
+ "508 AMD EPYC 4364P 105 105 right_only\n",
1402
+ "509 AMD EPYC 4464P 65 65 right_only\n",
1403
+ ".. ... ... ... ...\n",
1404
+ "752 AMD Opteron 6328 115 115 right_only\n",
1405
+ "753 AMD Opteron 6338P 99 99 right_only\n",
1406
+ "754 AMD Opteron 6344 115 115 right_only\n",
1407
+ "757 AMD Opteron 6370P 99 99 right_only\n",
1408
+ "807 AMD Opteron X2170 APU 25 25 right_only\n",
1409
+ "\n",
1410
+ "[113 rows x 4 columns]"
1411
+ ]
1412
+ },
1413
+ "execution_count": 66,
1414
+ "metadata": {},
1415
+ "output_type": "execute_result"
1416
+ }
1417
+ ],
1418
+ "source": [
1419
+ "# Merge df with amd_server, avoiding duplicates\n",
1420
+ "amd_server[\"TDP\"] = amd_server[\"TDP\"].astype(int).astype(str)\n",
1421
+ "merged_df = df.merge(\n",
1422
+ " amd_server, on=\"Name\", how=\"outer\", suffixes=(\"\", \"_AMD\"), indicator=True\n",
1423
+ ")\n",
1424
+ "# Filter for new entries that are only in amd_server\n",
1425
+ "new_cpus = merged_df[merged_df[\"_merge\"] == \"right_only\"]\n",
1426
+ "new_cpus[\"TDP\"] = new_cpus[\"TDP_AMD\"]\n",
1427
+ "new_cpus"
1428
+ ]
1429
+ },
1430
+ {
1431
+ "cell_type": "code",
1432
+ "execution_count": 67,
1433
+ "metadata": {},
1434
+ "outputs": [
1435
+ {
1436
+ "data": {
1437
+ "text/html": [
1438
+ "<div>\n",
1439
+ "<style scoped>\n",
1440
+ " .dataframe tbody tr th:only-of-type {\n",
1441
+ " vertical-align: middle;\n",
1442
+ " }\n",
1443
+ "\n",
1444
+ " .dataframe tbody tr th {\n",
1445
+ " vertical-align: top;\n",
1446
+ " }\n",
1447
+ "\n",
1448
+ " .dataframe thead th {\n",
1449
+ " text-align: right;\n",
1450
+ " }\n",
1451
+ "</style>\n",
1452
+ "<table border=\"1\" class=\"dataframe\">\n",
1453
+ " <thead>\n",
1454
+ " <tr style=\"text-align: right;\">\n",
1455
+ " <th></th>\n",
1456
+ " <th>Name</th>\n",
1457
+ " <th>TDP</th>\n",
1458
+ " </tr>\n",
1459
+ " </thead>\n",
1460
+ " <tbody>\n",
1461
+ " <tr>\n",
1462
+ " <th>505</th>\n",
1463
+ " <td>AMD EPYC 4124P</td>\n",
1464
+ " <td>65</td>\n",
1465
+ " </tr>\n",
1466
+ " <tr>\n",
1467
+ " <th>506</th>\n",
1468
+ " <td>AMD EPYC 4244P</td>\n",
1469
+ " <td>65</td>\n",
1470
+ " </tr>\n",
1471
+ " <tr>\n",
1472
+ " <th>507</th>\n",
1473
+ " <td>AMD EPYC 4344P</td>\n",
1474
+ " <td>65</td>\n",
1475
+ " </tr>\n",
1476
+ " <tr>\n",
1477
+ " <th>508</th>\n",
1478
+ " <td>AMD EPYC 4364P</td>\n",
1479
+ " <td>105</td>\n",
1480
+ " </tr>\n",
1481
+ " <tr>\n",
1482
+ " <th>509</th>\n",
1483
+ " <td>AMD EPYC 4464P</td>\n",
1484
+ " <td>65</td>\n",
1485
+ " </tr>\n",
1486
+ " <tr>\n",
1487
+ " <th>...</th>\n",
1488
+ " <td>...</td>\n",
1489
+ " <td>...</td>\n",
1490
+ " </tr>\n",
1491
+ " <tr>\n",
1492
+ " <th>752</th>\n",
1493
+ " <td>AMD Opteron 6328</td>\n",
1494
+ " <td>115</td>\n",
1495
+ " </tr>\n",
1496
+ " <tr>\n",
1497
+ " <th>753</th>\n",
1498
+ " <td>AMD Opteron 6338P</td>\n",
1499
+ " <td>99</td>\n",
1500
+ " </tr>\n",
1501
+ " <tr>\n",
1502
+ " <th>754</th>\n",
1503
+ " <td>AMD Opteron 6344</td>\n",
1504
+ " <td>115</td>\n",
1505
+ " </tr>\n",
1506
+ " <tr>\n",
1507
+ " <th>757</th>\n",
1508
+ " <td>AMD Opteron 6370P</td>\n",
1509
+ " <td>99</td>\n",
1510
+ " </tr>\n",
1511
+ " <tr>\n",
1512
+ " <th>807</th>\n",
1513
+ " <td>AMD Opteron X2170 APU</td>\n",
1514
+ " <td>25</td>\n",
1515
+ " </tr>\n",
1516
+ " </tbody>\n",
1517
+ "</table>\n",
1518
+ "<p>113 rows × 2 columns</p>\n",
1519
+ "</div>"
1520
+ ],
1521
+ "text/plain": [
1522
+ " Name TDP\n",
1523
+ "505 AMD EPYC 4124P 65\n",
1524
+ "506 AMD EPYC 4244P 65\n",
1525
+ "507 AMD EPYC 4344P 65\n",
1526
+ "508 AMD EPYC 4364P 105\n",
1527
+ "509 AMD EPYC 4464P 65\n",
1528
+ ".. ... ...\n",
1529
+ "752 AMD Opteron 6328 115\n",
1530
+ "753 AMD Opteron 6338P 99\n",
1531
+ "754 AMD Opteron 6344 115\n",
1532
+ "757 AMD Opteron 6370P 99\n",
1533
+ "807 AMD Opteron X2170 APU 25\n",
1534
+ "\n",
1535
+ "[113 rows x 2 columns]"
1536
+ ]
1537
+ },
1538
+ "execution_count": 67,
1539
+ "metadata": {},
1540
+ "output_type": "execute_result"
1541
+ }
1542
+ ],
1543
+ "source": [
1544
+ "# merged_df.query('Name.str.contains(\"EPYC\")')\n",
1545
+ "new_cpus_to_add = new_cpus.drop(columns=[\"_merge\"]).loc[:, df.columns]\n",
1546
+ "new_cpus_to_add"
1547
+ ]
1548
+ },
1549
+ {
1550
+ "cell_type": "code",
1551
+ "execution_count": 68,
1552
+ "metadata": {},
1553
+ "outputs": [
1554
+ {
1555
+ "data": {
1556
+ "text/html": [
1557
+ "<div>\n",
1558
+ "<style scoped>\n",
1559
+ " .dataframe tbody tr th:only-of-type {\n",
1560
+ " vertical-align: middle;\n",
1561
+ " }\n",
1562
+ "\n",
1563
+ " .dataframe tbody tr th {\n",
1564
+ " vertical-align: top;\n",
1565
+ " }\n",
1566
+ "\n",
1567
+ " .dataframe thead th {\n",
1568
+ " text-align: right;\n",
1569
+ " }\n",
1570
+ "</style>\n",
1571
+ "<table border=\"1\" class=\"dataframe\">\n",
1572
+ " <thead>\n",
1573
+ " <tr style=\"text-align: right;\">\n",
1574
+ " <th></th>\n",
1575
+ " <th>Name</th>\n",
1576
+ " <th>TDP</th>\n",
1577
+ " </tr>\n",
1578
+ " </thead>\n",
1579
+ " <tbody>\n",
1580
+ " <tr>\n",
1581
+ " <th>3928</th>\n",
1582
+ " <td>AMD EPYC 4124P</td>\n",
1583
+ " <td>65</td>\n",
1584
+ " </tr>\n",
1585
+ " </tbody>\n",
1586
+ "</table>\n",
1587
+ "</div>"
1588
+ ],
1589
+ "text/plain": [
1590
+ " Name TDP\n",
1591
+ "3928 AMD EPYC 4124P 65"
1592
+ ]
1593
+ },
1594
+ "execution_count": 68,
1595
+ "metadata": {},
1596
+ "output_type": "execute_result"
1597
+ }
1598
+ ],
1599
+ "source": [
1600
+ "# Option 2: Append the new CPUs to the original df\n",
1601
+ "df = pd.concat([df, new_cpus_to_add], ignore_index=True)\n",
1602
+ "df.sort_values(\"Name\", ascending=True, inplace=True)\n",
1603
+ "df.query('Name.str.contains(\"AMD EPYC 4124P\")')"
1604
+ ]
1605
+ },
1606
+ {
1607
+ "cell_type": "code",
1608
+ "execution_count": 69,
1609
+ "metadata": {},
1610
+ "outputs": [],
1611
+ "source": [
1612
+ "df.to_csv(\"cpu_power.csv\", index=False)"
1613
+ ]
1614
+ },
1615
+ {
1616
+ "cell_type": "markdown",
1617
+ "metadata": {},
1618
+ "source": [
1619
+ "# Remove with..."
1620
+ ]
1621
+ },
1622
+ {
1623
+ "cell_type": "code",
1624
+ "execution_count": 1,
1625
+ "metadata": {},
1626
+ "outputs": [],
1627
+ "source": [
1628
+ "import pandas as pd\n",
1629
+ "# Load the existing dataset\n",
1630
+ "df = pd.read_csv(\"../cpu_power.csv\")\n",
1631
+ "# Replace with re.sub(r\" with.*\", \"\", name)\n",
1632
+ "def clean_cpu_name(name):\n",
1633
+ " import re\n",
1634
+ " # Remove \"with\" and everything after it\n",
1635
+ " name = re.sub(r\" with.*\", \"\", name)\n",
1636
+ " # Remove \"™\" symbol\n",
1637
+ " name = name.replace(\"™\", \"\")\n",
1638
+ " return name.strip()\n",
1639
+ "df[\"Name\"] = df[\"Name\"].apply(clean_cpu_name)\n",
1640
+ "# Save the cleaned dataset\n",
1641
+ "df.to_csv(\"../cpu_power.csv\", index=False)"
1642
+ ]
1643
+ },
1644
+ {
1645
+ "cell_type": "markdown",
1646
+ "metadata": {},
1647
+ "source": []
1648
+ }
1649
+ ],
1650
+ "metadata": {
1651
+ "kernelspec": {
1652
+ "display_name": "3.10.5",
1653
+ "language": "python",
1654
+ "name": "python3"
1655
+ },
1656
+ "language_info": {
1657
+ "codemirror_mode": {
1658
+ "name": "ipython",
1659
+ "version": 3
1660
+ },
1661
+ "file_extension": ".py",
1662
+ "mimetype": "text/x-python",
1663
+ "name": "python",
1664
+ "nbconvert_exporter": "python",
1665
+ "pygments_lexer": "ipython3",
1666
+ "version": "3.10.5"
1667
+ }
1668
+ },
1669
+ "nbformat": 4,
1670
+ "nbformat_minor": 4
1671
+ }
codecarbon/data/hardware/cpu_dataset_builder/README.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # How to update the CPU database
2
+
3
+ To update the CPU database, you have to run:
4
+
5
+ ```bash
6
+ cd codecarbon/data/hardware/cpu_dataset_builder
7
+ hatch run pip install playwright beautifulsoup4
8
+ hatch run python intel_cpu_scrapper.py
9
+ hatch run python amd_cpu_scrapper.py
10
+ hatch run python merge_scrapped_cpu_power.py
11
+ ```
12
+
13
+ Then commit the changes to the CSV files.
14
+
15
+ CodeCarbon only use the `cpu_power.csv` file, but we keep the other files for reference and to allow someone else to use them if needed.
codecarbon/data/hardware/cpu_dataset_builder/amd_cpu_desktop_dataset.csv ADDED
The diff for this file is too large to render. See raw diff
 
codecarbon/data/hardware/cpu_dataset_builder/amd_cpu_scrapper.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This script uses Playwright to scrape AMD CPU data from their website and save it as a CSV file.
3
+
4
+ hatch run pip install playwright
5
+ hatch run python amd_cpu_scrapper.py
6
+ """
7
+
8
+ import asyncio
9
+
10
+ from playwright.async_api import Page, async_playwright
11
+
12
+
13
+ async def handle_cookie_banner(page: Page):
14
+ """Attempts to find and click a 'Reject All' button for cookie consent."""
15
+ try:
16
+ reject_button_selectors = [
17
+ "button:has-text('Reject All')",
18
+ "button:has-text('Decline All')",
19
+ "button[id*='reject']",
20
+ "button[class*='reject']",
21
+ "//button[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'reject all')]",
22
+ "//button[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'decline all')]",
23
+ ]
24
+
25
+ reject_button = None
26
+ for selector in reject_button_selectors:
27
+ try:
28
+ button = page.locator(selector).first
29
+ if await button.is_visible(
30
+ timeout=2000
31
+ ): # Short timeout for visibility check
32
+ reject_button = button
33
+ print(f"Found cookie consent button with selector: {selector}")
34
+ break
35
+ except Exception:
36
+ pass # Selector not found or button not visible, try next
37
+
38
+ if reject_button:
39
+ await reject_button.click()
40
+ print("Clicked 'Reject All' on cookie banner.")
41
+ await page.wait_for_timeout(1000) # Wait a bit for the banner to disappear
42
+ else:
43
+ print(
44
+ "Cookie banner 'Reject All' button not found or not visible after trying common selectors."
45
+ )
46
+
47
+ except Exception as cookie_error:
48
+ print(f"Could not handle cookie banner: {cookie_error}")
49
+
50
+
51
+ async def download_csv_from_url(page: Page, url: str, output_filename: str):
52
+ """Navigates to a URL, handles cookie banner, and downloads a CSV file."""
53
+ print(f"Attempting to download from: {url}")
54
+ retries = 2
55
+ for attempt in range(retries):
56
+ try:
57
+ await page.goto(url, timeout=30000) # Increased timeout for page load
58
+ await handle_cookie_banner(page)
59
+ break # If goto is successful, break the loop
60
+ except Exception as e:
61
+ print(f"Attempt {attempt + 1} to navigate to {url} failed: {e}")
62
+ if attempt < retries - 1:
63
+ await asyncio.sleep(5) # Wait for 5 seconds before retrying
64
+ else:
65
+ print(f"All retries failed for {url}.")
66
+ return # Exit if all retries fail
67
+
68
+ try:
69
+ # Wait for the download to start after clicking the button
70
+ async with page.expect_download(
71
+ timeout=30000
72
+ ) as download_info: # Increased timeout for download
73
+ # Click the button with the class "buttons-csv"
74
+ await page.locator(".buttons-csv").click()
75
+ print(f"Clicked download button for {url}")
76
+
77
+ download = await download_info.value
78
+
79
+ # Save the downloaded file
80
+ file_path = f"{output_filename}"
81
+ await download.save_as(file_path)
82
+ print(f"File downloaded from {url} and saved as {file_path}")
83
+
84
+ except Exception as e:
85
+ print(f"An error occurred while downloading from {url}: {e}")
86
+
87
+
88
+ async def main():
89
+ async with async_playwright() as p:
90
+ browser = await p.chromium.launch(
91
+ headless=False, # Set to True for production
92
+ args=[
93
+ "--no-sandbox",
94
+ "--disable-setuid-sandbox",
95
+ "--disable-dev-shm-usage",
96
+ "--disable-gpu",
97
+ ],
98
+ )
99
+ page = await browser.new_page()
100
+
101
+ urls_to_download = [
102
+ {
103
+ "url": "https://www.amd.com/en/products/specifications/server-processor.html",
104
+ "filename": "amd_cpu_server_dataset.csv",
105
+ },
106
+ {
107
+ "url": "https://www.amd.com/en/products/specifications/processors.html",
108
+ "filename": "amd_cpu_desktop_dataset.csv",
109
+ },
110
+ ]
111
+
112
+ for item in urls_to_download:
113
+ await download_csv_from_url(page, item["url"], item["filename"])
114
+ await asyncio.sleep(2) # Small delay between downloads
115
+
116
+ await browser.close()
117
+
118
+
119
+ if __name__ == "__main__":
120
+ asyncio.run(main())
codecarbon/data/hardware/cpu_dataset_builder/amd_cpu_server_dataset.csv ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Name","Series","# of CPU Cores","# of Threads","Max. Boost Clock","All Core Boost Speed","Base Clock","L3 Cache","1kU Pricing","Default TDP","AMD Configurable TDP (cTDP)","CPU Socket","Socket Count","Launch Date","PCI Express® Version","System Memory Type","Memory Channels","System Memory Specification","Per Socket Mem BW","Product ID Boxed","Product ID Tray","AMD Infinity Guard","Supported Technologies","Workload Affinity"
2
+ "AMD EPYC™ 9965","EPYC 9005 Series","192","384","Up to 3.7 GHz","3.35 GHz","2.25 GHz","384 MB","14813 USD","500W","450-500W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000000976","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , Content mgmt , HPC , Media streaming , Networking|NFV , Security , VDI , VM Density , Web Serving , CDC"
3
+ "AMD EPYC™ 9845","EPYC 9005 Series","160","320","Up to 3.7 GHz","3.25 GHz","2.1 GHz","320 MB","13564 USD","390W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001458","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CDC , Content mgmt , HPC , Media streaming , Networking|NFV , Security , VDI , VM Density , Web Serving"
4
+ "AMD EPYC™ 9825","EPYC 9005 Series","144","288","Up to 3.7 GHz","3.3 GHz","2.2 GHz","384 MB","13006 USD","390W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000000837","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CDC , Content mgmt , HPC , Media streaming , Networking|NFV , Security , VDI , VM Density , Web Serving"
5
+ "AMD EPYC™ 9755","EPYC 9005 Series","128","256","Up to 4.1 GHz","4.1 GHz","2.7 GHz","512 MB","12984 USD","500W","450-500W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001443","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , Content mgmt , HPC , Media streaming , Networking|NFV , Security , VDI , VM Density , Web Serving , CDC"
6
+ "AMD EPYC™ 9745","EPYC 9005 Series","128","256","Up to 3.7 GHz","3.45 GHz","2.4 GHz","256 MB","12141 USD","400W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001460","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , Content mgmt , HPC , Media streaming , Networking|NFV , Security , VDI , VM Density , Web Serving , CDC"
7
+ "AMD EPYC™ 9655P","EPYC 9005 Series","96","192","Up to 4.5 GHz","4.1 GHz","2.6 GHz","384 MB","10811 USD","400W","320-400W","SP5","1P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001522","","AMD Infinity Guard , AMD Infinity Architecture","CAE|CFD|FEA , High capacity data mgmt (NR|RDBMS) , HPC"
8
+ "AMD EPYC™ 9655","EPYC 9005 Series","96","192","Up to 4.5 GHz","4.1 GHz","2.6 GHz","384 MB","11852 USD","400W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000000674","","AMD Infinity Guard , AMD Infinity Architecture","CAE|CFD|FEA , High capacity data mgmt (NR|RDBMS) , HPC"
9
+ "AMD EPYC™ 9645","EPYC 9005 Series","96","192","Up to 3.7 GHz","3.3 GHz","2.3 GHz","256 MB","11048 USD","320W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001461","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , Consumer-Oriented Digital Services , Content mgmt , ERM|SCM|CRM apps"
10
+ "AMD EPYC™ 9575F","EPYC 9005 Series","64","128","Up to 5 GHz","4.5 GHz","3.3 GHz","256 MB","11791 USD","400W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001554","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
11
+ "AMD EPYC™ 9565","EPYC 9005 Series","72","144","Up to 4.3 GHz","4.2 GHz","3.15 GHz","384 MB","10486 USD","400W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001447","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , HPC , VM Density"
12
+ "AMD EPYC™ 9555P","EPYC 9005 Series","64","128","Up to 4.4 GHz","4.2 GHz","3.2 GHz","256 MB","7983 USD","360W","320-400W","SP5","1P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001523","","AMD Infinity Guard , 4th Gen AMD Infinity Architecture","App dev|test , ERM|SCM|CRM apps , Value data mgmt (NR|RDBMS) , VDI , VM Density"
13
+ "AMD EPYC™ 9555","EPYC 9005 Series","64","128","Up to 4.4 GHz","4.2 GHz","3.2 GHz","256 MB","9826 USD","360W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001142","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , HPC , VM Density"
14
+ "AMD EPYC™ 9535","EPYC 9005 Series","64","128","Up to 4.3 GHz","3.5 GHz","2.4 GHz","256 MB","8992 USD","300W","240-300W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001147","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
15
+ "AMD EPYC™ 9475F","EPYC 9005 Series","48","96","Up to 4.8 GHz","4.4 GHz","3.65 GHz","256 MB","7592 USD","400W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001143","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
16
+ "AMD EPYC™ 9455P","EPYC 9005 Series","48","96","Up to 4.4 GHz","4.1 GHz","3.15 GHz","256 MB","4819 USD","300W","240-300W","SP5","1P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001563","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
17
+ "AMD EPYC™ 9455","EPYC 9005 Series","48","96","Up to 4.4 GHz","4.1 GHz","3.15 GHz","256 MB","5412 USD","300W","240-300W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001542","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
18
+ "AMD EPYC™ 9375F","EPYC 9005 Series","32","64","Up to 4.8 GHz","4.4 GHz","3.8 GHz","256 MB","5306 USD","320W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001197","","AMD Infinity Guard , AMD Infinity Architecture","EDA , HCI , High performance VM Density , Per core CAE|CFD|FEA , VDI"
19
+ "AMD EPYC™ 9365","EPYC 9005 Series","36","72","Up to 4.3 GHz","4.15 GHz","3.4 GHz","192 MB","4341 USD","300W","240-300W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001448","","AMD Infinity Guard , AMD Infinity Architecture","Content mgmt , ERM|SCM|CRM apps , General Purpose , CDN"
20
+ "AMD EPYC™ 9355P","EPYC 9005 Series","32","64","Up to 4.4 GHz","4.2 GHz","3.55 GHz","256 MB","2998 USD","280W","240-300W","SP5","1P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001521","","AMD Infinity Guard , AMD Infinity Architecture","ERM|SCM|CRM apps , Value data mgmt (NR|RDBMS) , VDI , VM Density"
21
+ "AMD EPYC™ 9355","EPYC 9005 Series","32","64","Up to 4.4 GHz","4.2 GHz","3.55 GHz","256 MB","3694 USD","280W","240-300W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001148","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , Media streaming , Medium capacity data mgmt (NR|RDBMS) , VDI , VM Density"
22
+ "AMD EPYC™ 9335","EPYC 9005 Series","32","64","Up to 4.4 GHz","4 GHz","3 GHz","128 MB","3178 USD","210W","200-240W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001149","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , Media streaming , Medium capacity data mgmt (NR|RDBMS) , VDI , VM Density"
23
+ "AMD EPYC™ 9275F","EPYC 9005 Series","24","48","Up to 4.8 GHz","4.5 GHz","4.1 GHz","256 MB","3439 USD","320W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001144","","AMD Infinity Architecture , AMD Infinity Guard","General Purpose , GPU|FPGA Accelerated , Per core CAE|CFD|FEA , SW-defined storage"
24
+ "AMD EPYC™ 9255","EPYC 9005 Series","24","48","Up to 4.3 GHz","4 GHz","3.2 GHz","128 MB","2495 USD","200W","200-240W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000000694","","AMD Infinity Architecture , AMD Infinity Guard","ERM|SCM|CRM apps , General Purpose , Networking|NFV , Web Serving"
25
+ "AMD EPYC™ 9175F","EPYC 9005 Series","16","32","Up to 5 GHz","4.55 GHz","4.2 GHz","512 MB","4256 USD","320W","320-400W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001145","","AMD Infinity Architecture , AMD Infinity Guard","CAE|CFD|FEA , EDA , HPC"
26
+ "AMD EPYC™ 9135","EPYC 9005 Series","16","32","Up to 4.3 GHz","4.25 GHz","3.65 GHz","64 MB","1214 USD","200W","200-240W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001150","","AMD Infinity Architecture , AMD Infinity Guard","EDA , High-speed data mgmt (NR|RDBMS) , Per core CAE|CFD|FEA"
27
+ "AMD EPYC™ 9115","EPYC 9005 Series","16","32","Up to 4.1 GHz","3.3 GHz","2.6 GHz","64 MB","726 USD","125W","120-155W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001552","","AMD Infinity Architecture , AMD Infinity Guard","Media streaming , Per core CAE|CFD|FEA , Value"
28
+ "AMD EPYC™ 9015","EPYC 9005 Series","8","16","Up to 4.1 GHz","3.95 GHz","3.6 GHz","64 MB","527 USD","125W","120-155W","SP5","1P / 2P","10/10/2024","PCIe® 5.0 x128","DDR5","12","Up to 6400 MT/s","614 GB/s","","100-000001553","","AMD Infinity Architecture , AMD Infinity Guard","Collaborative , ERM|SCM|CRM apps , General Purpose"
29
+ "AMD EPYC™ 9754S","EPYC 9004 Series","128","128","Up to 3.1 GHz","3.1 GHz","2.25 GHz","256 MB","10200 USD","360W","320-400W","SP5","1P / 2P","06/13/2023","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000001371","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , Collaborative , Consumer-Oriented Digital Services , Content mgmt , General Purpose , HPC , Media streaming , VDI , VM Density , Web Serving"
30
+ "AMD EPYC™ 9754","EPYC 9004 Series","128","256","Up to 3.1 GHz","3.1 GHz","2.25 GHz","256 MB","11900 USD","360W","320-400W","SP5","1P / 2P","06/13/2023","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000001234","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , Collaborative , Consumer-Oriented Digital Services , Content mgmt , General Purpose , HPC , Media streaming , VDI , VM Density , Web Serving"
31
+ "AMD EPYC™ 9734","EPYC 9004 Series","112","224","Up to 3 GHz","3 GHz","2.2 GHz","256 MB","9600 USD","340W","320-400W","SP5","1P / 2P","06/13/2023","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000001235","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , Collaborative , Consumer-Oriented Digital Services , Content mgmt , General Purpose , HPC , Media streaming , VDI , VM Density , Web Serving"
32
+ "AMD EPYC™ 9684X","EPYC 9004 Series","96","192","Up to 3.7 GHz","3.42 GHz","2.55 GHz","1152 MB","14756 USD","400W","320-400W","SP5","1P / 2P","06/13/2023","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000001254","","AMD 3D V-Cache™ Technology , AMD Infinity Guard , AMD Infinity Architecture","CAE|CFD|FEA , High capacity data mgmt (NR|RDBMS) , HPC"
33
+ "AMD EPYC™ 9654P","EPYC 9004 Series","96","192","Up to 3.7 GHz","3.55 GHz","2.4 GHz","384 MB","10625 USD","360W","320-400W","SP5","1P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000803","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , Consumer-Oriented Digital Services , Content mgmt , ERM|SCM|CRM apps"
34
+ "AMD EPYC™ 9654","EPYC 9004 Series","96","192","Up to 3.7 GHz","3.55 GHz","2.4 GHz","384 MB","11805 USD","360W","320-400W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000789","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , Consumer-Oriented Digital Services , Content mgmt , ERM|SCM|CRM apps"
35
+ "AMD EPYC™ 9634","EPYC 9004 Series","84","168","Up to 3.7 GHz","3.1 GHz","2.25 GHz","384 MB","10304 USD","290W","240-300W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000797","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , Consumer-Oriented Digital Services , Content mgmt , ERM|SCM|CRM apps"
36
+ "AMD EPYC™ 9554P","EPYC 9004 Series","64","128","Up to 3.75 GHz","3.75 GHz","3.1 GHz","256 MB","7104 USD","360W","320-400W","SP5","1P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000804","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , ERM|SCM|CRM apps , Value data mgmt (NR|RDBMS) , VDI , VM Density"
37
+ "AMD EPYC™ 9554","EPYC 9004 Series","64","128","Up to 3.75 GHz","3.75 GHz","3.1 GHz","256 MB","9087 USD","360W","320-400W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000790","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , HPC , VM Density"
38
+ "AMD EPYC™ 9534","EPYC 9004 Series","64","128","Up to 3.7 GHz","3.55 GHz","2.45 GHz","256 MB","8803 USD","280W","240-300W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000799","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
39
+ "AMD EPYC™ 9474F","EPYC 9004 Series","48","96","Up to 4.1 GHz","3.95 GHz","3.6 GHz","256 MB","6780 USD","360W","320-400W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000788","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
40
+ "AMD EPYC™ 9454P","EPYC 9004 Series","48","96","Up to 3.8 GHz","3.65 GHz","2.75 GHz","256 MB","4598 USD","290W","240-300W","SP5","1P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000873","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
41
+ "AMD EPYC™ 9454","EPYC 9004 Series","48","96","Up to 3.8 GHz","3.65 GHz","2.75 GHz","256 MB","5225 USD","290W","240-300W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000478","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
42
+ "AMD EPYC™ 9384X","EPYC 9004 Series","32","64","Up to 3.9 GHz","3.5 GHz","3.1 GHz","768 MB","5529 USD","320W","320-400W","SP5","1P / 2P","06/13/2023","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000001256","","AMD 3D V-Cache™ Technology , AMD Infinity Guard , AMD Infinity Architecture","CAE|CFD|FEA , EDA , HPC"
43
+ "AMD EPYC™ 9374F","EPYC 9004 Series","32","64","Up to 4.3 GHz","4.1 GHz","3.85 GHz","256 MB","4850 USD","320W","320-400W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000792","","AMD Infinity Guard , AMD Infinity Architecture","EDA , HCI , High performance VM Density , Per core CAE|CFD|FEA , VDI"
44
+ "AMD EPYC™ 9354P","EPYC 9004 Series","32","64","Up to 3.8 GHz","3.75 GHz","3.25 GHz","256 MB","2730 USD","280W","240-300W","SP5","1P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000805","","AMD Infinity Guard , AMD Infinity Architecture","ERM|SCM|CRM apps , Value data mgmt (NR|RDBMS) , VDI , VM Density"
45
+ "AMD EPYC™ 9354","EPYC 9004 Series","32","64","Up to 3.8 GHz","3.75 GHz","3.25 GHz","256 MB","3420 USD","280W","240-300W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000798","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , Media streaming , Medium capacity data mgmt (NR|RDBMS) , VDI , VM Density"
46
+ "AMD EPYC™ 9334","EPYC 9004 Series","32","64","Up to 3.9 GHz","3.85 GHz","2.7 GHz","128 MB","2990 USD","210W","200-240W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000800","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , Media streaming , Medium capacity data mgmt (NR|RDBMS) , VDI , VM Density"
47
+ "AMD EPYC™ 9274F","EPYC 9004 Series","24","48","Up to 4.3 GHz","4.1 GHz","4.05 GHz","256 MB","3060 USD","320W","320-400W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000794","","AMD Infinity Guard , AMD Infinity Architecture","EDA , HCI , High performance VM Density , Per core CAE|CFD|FEA , VDI"
48
+ "AMD EPYC™ 9254","EPYC 9004 Series","24","48","Up to 4.15 GHz","3.9 GHz","2.9 GHz","128 MB","2299 USD","200W","200-240W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000480","","AMD Infinity Guard , AMD Infinity Architecture","General Purpose , GPU|FPGA Accelerated , Per core CAE|CFD|FEA , SW-defined storage"
49
+ "AMD EPYC™ 9224","EPYC 9004 Series","24","48","Up to 3.7 GHz","3.65 GHz","2.5 GHz","64 MB","1825 USD","200W","200-240W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000939","","AMD Infinity Guard , AMD Infinity Architecture","ERM|SCM|CRM apps , General Purpose , Networking|NFV , Web Serving"
50
+ "AMD EPYC™ 9184X","EPYC 9004 Series","16","32","Up to 4.2 GHz","3.85 GHz","3.55 GHz","768 MB","4928 USD","320W","320-400W","SP5","1P / 2P","06/13/2023","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000001255","","AMD 3D V-Cache™ Technology , AMD Infinity Guard , AMD Infinity Architecture","CAE|CFD|FEA , EDA , HPC"
51
+ "AMD EPYC™ 9174F","EPYC 9004 Series","16","32","Up to 4.4 GHz","4.15 GHz","4.1 GHz","256 MB","3850 USD","320W","320-400W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000796","","AMD Infinity Guard , AMD Infinity Architecture","EDA , High-speed data mgmt (NR|RDBMS) , Per core CAE|CFD|FEA"
52
+ "AMD EPYC™ 9124","EPYC 9004 Series","16","32","Up to 3.7 GHz","3.6 GHz","3 GHz","64 MB","1083 USD","200W","200-240W","SP5","1P / 2P","11/10/2022","PCIe® 5.0 x128","DDR5","12","Up to 4800 MT/s","460.8 GB/s","","100-000000802","","AMD Infinity Guard , AMD Infinity Architecture","Media streaming , Per core CAE|CFD|FEA , Value"
53
+ "AMD EPYC™ 8534PN","EPYC 8004 Series","64","128","Up to 3.1 GHz","3.05 GHz","2 GHz","128 MB","5450 USD","175W","","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000001172","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage , Telco"
54
+ "AMD EPYC™ 8534P","EPYC 8004 Series","64","128","Up to 3.1 GHz","3.1 GHz","2.3 GHz","128 MB","4950 USD","200W","155-225W","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000000875","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage"
55
+ "AMD EPYC™ 8434PN","EPYC 8004 Series","48","96","Up to 3 GHz","3 GHz","2 GHz","128 MB","3150 USD","155W","","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000001174","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage , Telco"
56
+ "AMD EPYC™ 8434P","EPYC 8004 Series","48","96","Up to 3.1 GHz","3.1 GHz","2.5 GHz","128 MB","2700 USD","200W","155-225W","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000000877","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage"
57
+ "AMD EPYC™ 8324PN","EPYC 8004 Series","32","64","Up to 3 GHz","3 GHz","2.05 GHz","128 MB","2125 USD","130W","","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000001162","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , SW-defined storage , Telco"
58
+ "AMD EPYC™ 8324P","EPYC 8004 Series","32","64","Up to 3 GHz","3 GHz","2.65 GHz","128 MB","1895 USD","180W","155-225W","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000001133","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage"
59
+ "AMD EPYC™ 8224PN","EPYC 8004 Series","24","48","Up to 3 GHz","2.9 GHz","2 GHz","64 MB","1015 USD","120W","","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000001164","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage , Telco"
60
+ "AMD EPYC™ 8224P","EPYC 8004 Series","24","48","Up to 3 GHz","3 GHz","2.55 GHz","64 MB","855 USD","160W","155-225W","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000001134","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage"
61
+ "AMD EPYC™ 8124PN","EPYC 8004 Series","16","32","Up to 3 GHz","2.9 GHz","2 GHz","64 MB","790 USD","100W","","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000001166","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage , Telco"
62
+ "AMD EPYC™ 8124P","EPYC 8004 Series","16","32","Up to 3 GHz","2.95 GHz","2.45 GHz","64 MB","639 USD","125W","120-150W","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000001135","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage"
63
+ "AMD EPYC™ 8024PN","EPYC 8004 Series","8","16","Up to 3 GHz","2.95 GHz","2.05 GHz","32 MB","525 USD","80W","","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000001170","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage , Telco"
64
+ "AMD EPYC™ 8024P","EPYC 8004 Series","8","16","Up to 3 GHz","2.95 GHz","2.4 GHz","32 MB","409 USD","90W","70-100W","SP6","1P","09/18/2023","PCIe® 5.0 x96","DDR5","6","Up to 4800 MT/s","230.4 GB/s","","100-000001136","","AMD Infinity Guard , AMD Infinity Architecture","Client-Middleware Computing , HCI , Media streaming , Networking|NFV , SW-defined storage"
65
+ "AMD EPYC™ 7203P","EPYC 7003 Series","8","16","Up to 3.4 GHz","","2.8 GHz","64 MB","338 USD","120W","120-150W","SP3","1P","09/05/2023","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-000001287WOF","100-000001287","","AMD Infinity Guard , AMD Infinity Architecture","General Purpose"
66
+ "AMD EPYC™ 7203","EPYC 7003 Series","8","16","Up to 3.4 GHz","","2.8 GHz","64 MB","348 USD","120W","120-150W","SP3","1P / 2P","09/05/2023","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-000001286WOF","100-000001286","","AMD Infinity Guard , AMD Infinity Architecture","General Purpose"
67
+ "AMD EPYC™ 7303P","EPYC 7003 Series","16","32","Up to 3.4 GHz","","2.4 GHz","64 MB","594 USD","130W","120-150W","SP3","1P","09/05/2023","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-000001289WOF","100-000001289","","AMD Infinity Guard , AMD Infinity Architecture","Cost-optimized , General Purpose"
68
+ "AMD EPYC™ 7303","EPYC 7003 Series","16","32","Up to 3.4 GHz","","2.4 GHz","64 MB","604 USD","130W","120-150W","SP3","1P / 2P","09/05/2023","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-000001288WOF","100-000001288","","AMD Infinity Guard , AMD Infinity Architecture","Cost-optimized , General Purpose"
69
+ "AMD EPYC™ 7643P","EPYC 7003 Series","48","96","Up to 3.6 GHz","","2.3 GHz","256 MB","2722 USD","225W","225-240W","SP3","1P","09/05/2023","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000001285","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
70
+ "AMD EPYC™ 7773X","EPYC 7003 Series","64","128","Up to 3.5 GHz","","2.2 GHz","768 MB","8800 USD","280W","225-280W","SP3","1P / 2P","03/22/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000504​","","AMD 3D V-Cache™ Technology , AMD Infinity Guard , AMD Infinity Architecture","Cache-sensitive scale-up|out , CFD , FEA Solvers"
71
+ "AMD EPYC™ 7763","EPYC 7003 Series","64","128","Up to 3.5 GHz","","2.45 GHz","256 MB","7890 USD","280W","225-280W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000312WOF","100-000000312","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , Cache-sensitive scale-up|out , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VM Density"
72
+ "AMD EPYC™ 7713P","EPYC 7003 Series","64","128","Up to 3.67 GHz","","2 GHz","256 MB","5010 USD","225W","225-240W","SP3","1P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000337","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , ERM|SCM|CRM apps , Value data mgmt (NR|RDBMS) , VDI , VM Density"
73
+ "AMD EPYC™ 7713","EPYC 7003 Series","64","128","Up to 3.67 GHz","","2 GHz","256 MB","7060 USD","225W","225-240W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000344WOF","100-000000344","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
74
+ "AMD EPYC™ 7663","EPYC 7003 Series","56","112","Up to 3.5 GHz","","2 GHz","256 MB","6366 USD","240W","225-240W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000318","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
75
+ "AMD EPYC™ 7643","EPYC 7003 Series","48","96","Up to 3.6 GHz","","2.3 GHz","256 MB","4995 USD","225W","225-240W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000326","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
76
+ "AMD EPYC™ 7663P","EPYC 7003 Series","56","112","Up to 3.5 GHz","","2 GHz","256 MB","3139 USD","240W","225-280W","SP3","1P","09/05/2023","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000001284","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
77
+ "AMD EPYC™ 75F3","EPYC 7003 Series","32","64","Up to 4 GHz","","2.95 GHz","256 MB","4860 USD","280W","225-280W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000313","","AMD Infinity Guard , AMD Infinity Architecture","EDA , HCI , High performance VM Density , Per core CAE|CFD|FEA , VDI"
78
+ "AMD EPYC™ 7573X","EPYC 7003 Series","32","64","Up to 3.6 GHz","","2.8 GHz","768 MB","5590 USD","280W","225-280W","SP3","1P / 2P","03/22/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000506​","","AMD 3D V-Cache™ Technology , AMD Infinity Guard , AMD Infinity Architecture","CFD , FEA Solvers"
79
+ "AMD EPYC™ 7543P","EPYC 7003 Series","32","64","Up to 3.7 GHz","","2.8 GHz","256 MB","2730 USD","225W","225-240W","SP3","1P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000341WOF","100-000000341","","AMD Infinity Guard , AMD Infinity Architecture","ERM|SCM|CRM apps , Value data mgmt (NR|RDBMS) , VDI , VM Density"
80
+ "AMD EPYC™ 7543","EPYC 7003 Series","32","64","Up to 3.7 GHz","","2.8 GHz","256 MB","3761 USD","225W","225-240W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000345WOF","100-000000345","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , Media streaming , Medium capacity data mgmt (NR|RDBMS) , VDI , VM Density"
81
+ "AMD EPYC™ 7513","EPYC 7003 Series","32","64","Up to 3.65 GHz","","2.6 GHz","128 MB","2840 USD","200W","165-200W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000334WOF","100-000000334","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , Content mgmt , General Purpose"
82
+ "AMD EPYC™ 74F3","EPYC 7003 Series","24","48","Up to 4 GHz","","3.2 GHz","256 MB","2900 USD","240W","225-240W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000317","","AMD Infinity Guard , AMD Infinity Architecture","EDA , HCI , High performance VM Density , Per core CAE|CFD|FEA , VDI"
83
+ "AMD EPYC™ 7473X","EPYC 7003 Series","24","48","Up to 3.7 GHz","","2.8 GHz","768 MB","3900 USD","240W","225-280W","SP3","1P / 2P","03/22/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000507​","","AMD 3D V-Cache™ Technology , AMD Infinity Guard , AMD Infinity Architecture","CFD , EDA , FEA Solvers"
84
+ "AMD EPYC™ 7453","EPYC 7003 Series","28","56","Up to 3.45 GHz","","2.75 GHz","64 MB","1570 USD","225W","225-240W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000319","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , Content mgmt , General Purpose , Value , Value data mgmt (NR|RDBMS)"
85
+ "AMD EPYC™ 7443P","EPYC 7003 Series","24","48","Up to 4 GHz","","2.85 GHz","128 MB","1337 USD","200W","165-200W","SP3","1P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000342WOF","100-000000342","","AMD Infinity Guard , AMD Infinity Architecture","General Purpose , SW-defined storage , Value"
86
+ "AMD EPYC™ 7443","EPYC 7003 Series","24","48","Up to 4 GHz","","2.85 GHz","128 MB","2010 USD","200W","165-200W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000340","","AMD Infinity Guard , AMD Infinity Architecture","General Purpose , GPU|FPGA Accelerated , Per core CAE|CFD|FEA , SW-defined storage"
87
+ "AMD EPYC™ 7413","EPYC 7003 Series","24","48","Up to 3.6 GHz","","2.65 GHz","128 MB","1825 USD","180W","165-200W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000323WOF","100-000000323","","AMD Infinity Guard , AMD Infinity Architecture","ERM|SCM|CRM apps , General Purpose , Networking|NFV , Web Serving"
88
+ "AMD EPYC™ 73F3","EPYC 7003 Series","16","32","Up to 4 GHz","","3.5 GHz","256 MB","3521 USD","240W","225-240W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000321","","AMD Infinity Guard , AMD Infinity Architecture","EDA , High-speed data mgmt (NR|RDBMS) , Per core CAE|CFD|FEA"
89
+ "AMD EPYC™ 7373X","EPYC 7003 Series","16","32","Up to 3.8 GHz","","3.05 GHz","768 MB","4185 USD","240W","225-280W","SP3","1P / 2P","03/22/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000508​","","AMD 3D V-Cache™ Technology , AMD Infinity Guard , AMD Infinity Architecture","CFD , EDA , FEA Solvers"
90
+ "AMD EPYC™ 7343","EPYC 7003 Series","16","32","Up to 3.9 GHz","","3.2 GHz","128 MB","1565 USD","190W","165-200W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000338","","AMD Infinity Guard , AMD Infinity Architecture","EDA , General Purpose , Media streaming , Per core CAE|CFD|FEA , Value"
91
+ "AMD EPYC™ 7313P","EPYC 7003 Series","16","32","Up to 3.7 GHz","","3 GHz","128 MB","913 USD","155W","155-180W","SP3","1P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000339WOF","100-000000339","","AMD Infinity Guard , AMD Infinity Architecture","EDA , Media streaming , Value per core CAE|CFD|FEA"
92
+ "AMD EPYC™ 7313","EPYC 7003 Series","16","32","Up to 3.7 GHz","","3 GHz","128 MB","1083 USD","155W","155-180W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000329WOF","100-000000329","","AMD Infinity Guard , AMD Infinity Architecture","EDA , Media streaming , Per core CAE|CFD|FEA"
93
+ "AMD EPYC™ 72F3","EPYC 7003 Series","8","16","Up to 4.1 GHz","","3.7 GHz","256 MB","2468 USD","180W","165-200W","SP3","1P / 2P","03/15/2021","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","","100-000000327","","AMD Infinity Guard , AMD Infinity Architecture","Departmental CAE|CFD|FEA , EDA , FSI risk analysis , Licensed per core data mgmt (RDBMS)"
94
+ "AMD EPYC™ 7H12","EPYC 7002 Series","64","128","Up to 3.3 GHz","","2.6 GHz","256 MB","7250 USD","280W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000055WOF","100-000000055","","AMD Infinity Guard , AMD Infinity Architecture","Specialized CAE|CFD|FEA"
95
+ "AMD EPYC™ 7F72","EPYC 7002 Series","24","48","Up to 3.7 GHz","","3.2 GHz","192 MB","2450 USD","240W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-000000141WOF","100-000000141","","AMD Infinity Guard , AMD Infinity Architecture","EDA , HCI , High performance VM Density , Per core CAE|CFD|FEA , VDI"
96
+ "AMD EPYC™ 7F52","EPYC 7002 Series","16","32","Up to 3.9 GHz","","3.5 GHz","256 MB","3100 USD","240W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-000000140WOF","100-000000140","","AMD Infinity Guard , AMD Infinity Architecture","EDA , High-speed data mgmt (NR|RDBMS) , Per core CAE|CFD|FEA"
97
+ "AMD EPYC™ 7F32","EPYC 7002 Series","8","16","Up to 3.9 GHz","","3.7 GHz","128 MB","2100 USD","180W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-000000139WOF","100-000000139","","AMD Infinity Guard , AMD Infinity Architecture","Departmental CAE|CFD|FEA , EDA , FSI risk analysis , Licensed per core data mgmt (RDBMS)"
98
+ "AMD EPYC™ 4585PX","EPYC 4005 Series","16","32","Up to 5.7 GHz","","4.3 GHz","128 MB","699 USD","170W","","AM5","1P","5/13/2025","PCIe® 5.0 x28","DDR5","2","Up to 5600 MT/s","89.6 GB/s","100-100001561WOF","100-000001561","","AMD Infinity Guard , AMD Infinity Architecture",""
99
+ "AMD EPYC™ 7742","EPYC 7002 Series","64","128","Up to 3.4 GHz","","2.25 GHz","256 MB","6950 USD","225W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000053WOF","100-000000053","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , Cache-sensitive scale-up|out , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VM Density"
100
+ "AMD EPYC™ 4565P","EPYC 4005 Series","16","32","Up to 5.7 GHz","","4.3 GHz","64 MB","589 USD","170W","","AM5","1P","5/13/2025","PCIe® 5.0 x28","DDR5","2","Up to 5600 MT/s","89.6 GB/s","100-100001559WOF","100-000001559","","AMD Infinity Architecture , AMD Infinity Guard",""
101
+ "AMD EPYC™ 4545P","EPYC 4005 Series","16","32","Up to 5.4 GHz","","3 GHz","64 MB","549 USD","65W","","AM5","1P","5/13/2025","PCIe® 5.0 x28","DDR5","2","Up to 5600 MT/s","89.6 GB/s","100-100001764WOF","100-000001764","","AMD Infinity Guard , AMD Infinity Architecture",""
102
+ "AMD EPYC™ 7702P","EPYC 7002 Series","64","128","Up to 3.35 GHz","","2 GHz","256 MB","4425 USD","200W","","SP3","1P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000047WOF","100-000000047","","AMD Infinity Guard , AMD Infinity Architecture","ERM|SCM|CRM apps , Security , Value data mgmt (NR|RDBMS) , VM Density"
103
+ "AMD EPYC™ 4465P","EPYC 4005 Series","12","24","Up to 5.4 GHz","","3.4 GHz","64 MB","399 USD","65W","","AM5","1P","5/13/2025","PCIe® 5.0 x28","DDR5","2","Up to 5600 MT/s","89.6 GB/s","100-100001558WOF","100-000001558","","AMD Infinity Guard , AMD Infinity Architecture",""
104
+ "AMD EPYC™ 4345P","EPYC 4005 Series","8","16","Up to 5.5 GHz","","3.8 GHz","32 MB","329 USD","65W","","AM5","1P","5/13/2025","PCIe® 5.0 x28","DDR5","2","Up to 5600 MT/s","89.6 GB/s","100-100001556WOF","100-000001556","","AMD Infinity Guard , AMD Infinity Architecture",""
105
+ "AMD EPYC™ 7702","EPYC 7002 Series","64","128","Up to 3.35 GHz","","2 GHz","256 MB","6450 USD","200W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000038WOF","100-000000038","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , Cache-sensitive scale-up|out , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VM Density"
106
+ "AMD EPYC™ 4245P","EPYC 4005 Series","6","12","Up to 5.4 GHz","","3.9 GHz","32 MB","239 USD","65W","","AM5","1P","5/13/2025","PCIe® 5.0 x28","DDR5","2","Up to 5600 MT/s","89.6 GB/s","100-100001555WOF","100-000001555","","AMD Infinity Guard , AMD Infinity Architecture",""
107
+ "AMD EPYC™ 7662","EPYC 7002 Series","64","128","Up to 3.3 GHz","","2 GHz","256 MB","6150 USD","225W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-000000137WOF","100-000000137","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
108
+ "AMD EPYC™ 7642","EPYC 7002 Series","48","96","Up to 3.3 GHz","","2.3 GHz","256 MB","4775 USD","225W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000074WOF","100-000000074","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
109
+ "AMD EPYC™ 7552","EPYC 7002 Series","48","96","Up to 3.3 GHz","","2.2 GHz","192 MB","4025 USD","200W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000076WOF","100-000000076","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
110
+ "AMD EPYC™ 7542","EPYC 7002 Series","32","64","Up to 3.4 GHz","","2.9 GHz","128 MB","3400 USD","225W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000075WOF","100-000000075","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , Media streaming , Medium capacity data mgmt (NR|RDBMS) , VDI , VM Density"
111
+ "AMD EPYC™ 7532","EPYC 7002 Series","32","64","Up to 3.3 GHz","","2.4 GHz","256 MB","2380 USD","200W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-000000136WOF","100-000000136","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , Media streaming , Medium capacity data mgmt (NR|RDBMS) , VDI , VM Density"
112
+ "AMD EPYC™ 7502P","EPYC 7002 Series","32","64","Up to 3.35 GHz","","2.5 GHz","128 MB","2300 USD","180W","","SP3","1P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000045WOF","100-000000045","","AMD Infinity Guard , AMD Infinity Architecture","ERM|SCM|CRM apps , Value data mgmt (NR|RDBMS) , VDI , VM Density"
113
+ "AMD EPYC™ 7502","EPYC 7002 Series","32","64","Up to 3.35 GHz","","2.5 GHz","128 MB","2600 USD","180W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000054WOF","100-000000054","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , Media streaming , Medium capacity data mgmt (NR|RDBMS) , VDI , VM Density"
114
+ "AMD EPYC™ 7452","EPYC 7002 Series","32","64","Up to 3.35 GHz","","2.35 GHz","128 MB","2025 USD","155W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000057WOF","100-000000057","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , Content mgmt , General Purpose"
115
+ "AMD EPYC™ 7402P","EPYC 7002 Series","24","48","Up to 3.35 GHz","","2.8 GHz","128 MB","1250 USD","180W","","SP3","1P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000048WOF","100-000000048","","AMD Infinity Guard , AMD Infinity Architecture","General Purpose , SW-defined storage , Value"
116
+ "AMD EPYC™ 7402","EPYC 7002 Series","24","48","Up to 3.35 GHz","","2.8 GHz","128 MB","1783 USD","180W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000046WOF","100-000000046","","AMD Infinity Guard , AMD Infinity Architecture","General Purpose , GPU|FPGA Accelerated , Per core CAE|CFD|FEA , SW-defined storage"
117
+ "AMD EPYC™ 7352","EPYC 7002 Series","24","48","Up to 3.2 GHz","","2.3 GHz","128 MB","1080 USD","155W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000077WOF","100-000000077","","AMD Infinity Guard , AMD Infinity Architecture","ERM|SCM|CRM apps , Networking|NFV , Web Serving"
118
+ "AMD EPYC™ 7302P","EPYC 7002 Series","16","32","Up to 3.3 GHz","","3 GHz","128 MB","825 USD","155W","","SP3","1P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000049WOF","100-000000049","","AMD Infinity Guard , AMD Infinity Architecture","EDA , Media streaming , Value per core CAE|CFD|FEA"
119
+ "AMD EPYC™ 7302","EPYC 7002 Series","16","32","Up to 3.3 GHz","","3 GHz","128 MB","978 USD","155W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000043WOF","100-000000043","","AMD Infinity Guard , AMD Infinity Architecture","EDA , Media streaming , Per core CAE|CFD|FEA"
120
+ "AMD EPYC™ 7282","EPYC 7002 Series","16","32","Up to 3.2 GHz","","2.8 GHz","64 MB","604 USD","120W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","85.3 GB/s","100-100000078WOF","100-000000078","","AMD Infinity Guard , AMD Infinity Architecture","Cost-optimized , General Purpose , SW-defined storage"
121
+ "AMD EPYC™ 7272","EPYC 7002 Series","12","24","Up to 3.2 GHz","","2.9 GHz","64 MB","549 USD","120W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","85.3 GB/s","100-100000079WOF","100-000000079","","AMD Infinity Guard , AMD Infinity Architecture","Content mgmt , Cost-optimized , General Purpose"
122
+ "AMD EPYC™ 7262","EPYC 7002 Series","8","16","Up to 3.4 GHz","","3.2 GHz","128 MB","505 USD","155W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","204.8 GB/s","100-100000041WOF","100-000000041","","AMD Infinity Guard , AMD Infinity Architecture","Collaborative , Cost-optimized , Departmental CAE|CFD|FEA , EDA , Licensed per core data mgmt (RDBMS)"
123
+ "AMD EPYC™ 7252","EPYC 7002 Series","8","16","Up to 3.2 GHz","","3.1 GHz","64 MB","348 USD","120W","","SP3","1P / 2P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","85.3 GB/s","100-100000080WOF","100-000000080","","AMD Infinity Guard , AMD Infinity Architecture","Collaborative , Cost-optimized , Departmental CAE|CFD|FEA , EDA , Licensed per core data mgmt (RDBMS)"
124
+ "AMD EPYC™ 7232P","EPYC 7002 Series","8","16","Up to 3.2 GHz","","3.1 GHz","32 MB","338 USD","120W","","SP3","1P","","PCIe® 4.0 x128","DDR4","8","Up to 3200 MT/s","85.3 GB/s","100-100000081WOF","100-000000081","","AMD Infinity Guard , AMD Infinity Architecture","Cost-optimized , Per core license , Value"
125
+ "AMD EPYC™ 7601","EPYC 7001 Series","32","64","Up to 3.2 GHz","","2.2 GHz","64 MB","3270 USD","180W","","SP3","1P / 2P","","PCIe® 3.0 x128","DDR4","8","Up to 2666 MT/s","170.6 GB/s","PS7601BDAFWOF","PS7601BDVIHAF","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , Cache-sensitive scale-up|out , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS)"
126
+ "AMD EPYC™ 7551P","EPYC 7001 Series","32","64","Up to 3 GHz","","2 GHz","64 MB","1830 USD","180W","","SP3","1P","","PCIe® 3.0 x128","DDR4","8","Up to 2666 MT/s","170.6 GB/s","PS755PBDAFWOF","PS755PBDVIHAF","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , Cache-sensitive scale-up|out , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
127
+ "AMD EPYC™ 7551","EPYC 7001 Series","32","64","Up to 3 GHz","","2 GHz","64 MB","2660 USD","180W","","SP3","1P / 2P","","PCIe® 3.0 x128","DDR4","8","Up to 2666 MT/s","170.6 GB/s","PS7551BDAFWOF","PS7551BDVIHAF","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , App dev|test , Cache-sensitive scale-up|out , CAE|CFD|FEA , ERM|SCM|CRM apps , High capacity data mgmt (NR|RDBMS) , VDI , VM Density"
128
+ "AMD EPYC™ 7501","EPYC 7001 Series","32","64","Up to 3 GHz","","2 GHz","64 MB","2870 USD","155W / 170W","","SP3","1P / 2P","","PCIe® 3.0 x128","DDR4","8","2400 MT/s / 2666 MT/s","153.6 GB/s / 170.6 GB/s","PS7501BEAFWOF","PS7501BEVIHAF","","AMD Infinity Guard , AMD Infinity Architecture","Analytics , CAE|CFD|FEA , ERM|SCM|CRM apps , Media streaming , Medium capacity data mgmt (NR|RDBMS) , VDI , VM Density"
129
+ "AMD EPYC™ 7451","EPYC 7001 Series","24","48","Up to 3.2 GHz","","2.3 GHz","64 MB","1880 USD","180W","","SP3","1P / 2P","","PCIe® 3.0 x128","DDR4","8","Up to 2666 MT/s","170.6 GB/s","PS7451BDAFWOF","PS7451BDVHCAF","","AMD Infinity Guard , AMD Infinity Architecture","App dev|test , Content mgmt , General Purpose"
130
+ "AMD EPYC™ 7401P","EPYC 7001 Series","24","48","Up to 3 GHz","","2 GHz","64 MB","920 USD","155W / 170W","","SP3","1P","","PCIe® 3.0 x128","DDR4","8","2400 MT/s / 2666 MT/s","153.6 GB/s / 170.6 GB/s","PS740PBEAFWOF","PS740PBEVHCAF","","AMD Infinity Guard , AMD Infinity Architecture","ERM|SCM|CRM apps , Value data mgmt (NR|RDBMS) , VDI , VM Density"
131
+ "AMD EPYC™ 7401","EPYC 7001 Series","24","48","Up to 3 GHz","","2 GHz","64 MB","1620 USD","155W / 170W","","SP3","1P / 2P","","PCIe® 3.0 x128","DDR4","8","2400 MT/s / 2666 MT/s","153.6 GB/s / 170.6 GB/s","PS7401BEAFWOF","PS7401BEVHCAF","","AMD Infinity Guard , AMD Infinity Architecture","General Purpose , GPU|FPGA Accelerated , SW-defined storage"
132
+ "AMD EPYC™ 7371","EPYC 7001 Series","16","32","Up to 3.8 GHz","","3.1 GHz","64 MB","1550 USD","200W","","SP3","1P / 2P","","PCIe® 3.0 x128","DDR4","8","Up to 2666 MT/s","170.6 GB/s","","","","AMD Infinity Guard , AMD Infinity Architecture","EDA , ERM|SCM|CRM apps , Media streaming , Networking|NFV , Per core CAE|CFD|FEA , Web Serving"
133
+ "AMD EPYC™ 7351P","EPYC 7001 Series","16","32","Up to 2.9 GHz","","2.4 GHz","64 MB","660 USD","155W / 170W","","SP3","1P","","PCIe® 3.0 x128","DDR4","8","2400 MT/s / 2666 MT/s","153.6 GB/s / 170.6 GB/s","PS735PBEAFWOF","PS735PBEVGPAF","","AMD Infinity Guard , AMD Infinity Architecture","Cost-optimized , EDA , General Purpose , Media streaming , Value per core CAE|CFD|FEA"
134
+ "AMD EPYC™ 7351","EPYC 7001 Series","16","32","Up to 2.9 GHz","","2.4 GHz","64 MB","890 USD","155W / 170W","","SP3","1P / 2P","","PCIe® 3.0 x128","DDR4","8","2400 MT/s / 2666 MT/s","153.6 GB/s / 170.6 GB/s","PS7351BEAFWOF","PS7351BEVGPAF","","AMD Infinity Guard , AMD Infinity Architecture","General Purpose , Media streaming , Per core CAE|CFD|FEA , Web Serving"
135
+ "AMD EPYC™ 7301","EPYC 7001 Series","16","32","Up to 2.7 GHz","","2.2 GHz","64 MB","740 USD","155W / 170W","","SP3","1P / 2P","","PCIe® 3.0 x128","DDR4","8","2400 MT/s / 2666 MT/s","153.6 GB/s / 170.6 GB/s","PS7301BEAFWOF","PS7301BEVGPAF","","AMD Infinity Guard , AMD Infinity Architecture","EDA , General Purpose , Media streaming , Per core CAE|CFD|FEA"
136
+ "AMD EPYC™ 7281","EPYC 7001 Series","16","32","Up to 2.7 GHz","","2.1 GHz","32 MB","580 USD","155W / 170W","","SP3","1P / 2P","","PCIe® 3.0 x128","DDR4","8","2400 MT/s / 2666 MT/s","153.6 GB/s / 170.6 GB/s","PS7281BEAFWOF","PS7281BEVGAAF","","AMD Infinity Guard , AMD Infinity Architecture","Cost-optimized , General Purpose , SW-defined storage"
137
+ "AMD EPYC™ 7261","EPYC 7001 Series","8","16","Up to 2.9 GHz","","2.5 GHz","64 MB","570 USD","155W / 170W","","SP3","1P / 2P","","","DDR4","8","2400 MT/s / 2666 MT/s","153.6 GB/s / 170.6 GB/s","","PS7261BEV8RAF","","AMD Infinity Guard , AMD Infinity Architecture","Collaborative , Cost-optimized , Departmental CAE|CFD|FEA , EDA , Per core license , Value data mgmt (NR|RDBMS)"
138
+ "AMD EPYC™ 7251","EPYC 7001 Series","8","16","Up to 2.9 GHz","","2.1 GHz","32 MB","400 USD","120W","","SP3","1P / 2P","","PCIe® 3.0 x128","DDR4","8","Up to 2400 MT/s","153.6 GB/s","PS7251BFAFWOF","PS7251BFV8SAF","","AMD Infinity Guard , AMD Infinity Architecture","Collaborative , Cost-optimized , Per core license , Value data mgmt (NR|RDBMS)"
139
+ "AMD EPYC™ 4584PX","EPYC 4004 Series","16","32","Up to 5.7 GHz","5.7 GHz","4.2 GHz","128 MB","699 USD","120W","","AM5","1P","","PCIe® 5.0 x28","DDR5","2","Up to 5200 MT/s","","100-100001481WOF","100-000001481","Yes","AMD Infinity Architecture",""
140
+ "AMD EPYC™ 4564P","EPYC 4004 Series","16","32","Up to 5.7 GHz","","4.5 GHz","64 MB","699 USD","170W","","AM5","1P","","PCIe® 5.0 x28","DDR5","2","Up to 5200 MT/s","","100-100001476WOF","100-000001476","Yes","AMD Infinity Architecture",""
141
+ "AMD EPYC™ 4484PX","EPYC 4004 Series","12","24","Up to 5.6 GHz","","4.4 GHz","128 MB","599 USD","120W","","AM5","1P","","PCIe® 5.0 x28","DDR5","2","Up to 5200 MT/s","","100-100001482WOF","100-000001482","Yes","AMD Infinity Architecture",""
142
+ "AMD EPYC™ 4464P","EPYC 4004 Series","12","24","Up to 5.4 GHz","","3.7 GHz","64 MB","429 USD","65W","","AM5","1P","","PCIe® 5.0 x28","DDR5","2","Up to 5200 MT/s","","100-100001478WOF","100-000001478","Yes","AMD Infinity Architecture",""
143
+ "AMD EPYC™ 4364P","EPYC 4004 Series","8","16","Up to 5.4 GHz","","4.5 GHz","32 MB","399 USD","105W","","AM5","1P","","PCIe® 5.0 x28","DDR5","2","Up to 5200 MT/s","","100-100001477WOF","100-000001477","Yes","AMD Infinity Architecture",""
144
+ "AMD EPYC™ 4344P","EPYC 4004 Series","8","16","Up to 5.3 GHz","","3.8 GHz","32 MB","329 USD","65W","","AM5","1P","","PCIe® 5.0 x28","DDR5","2","Up to 5200 MT/s","","100-100001479WOF","100-000001479","Yes","AMD Infinity Architecture",""
145
+ "AMD EPYC™ 4244P","EPYC 4004 Series","6","12","Up to 5.1 GHz","","3.8 GHz","32 MB","229 USD","65W","","AM5","1P","","PCIe® 5.0 x28","DDR5","2","Up to 5200 MT/s","","100-100001480WOF","100-000001480","Yes","AMD Infinity Architecture",""
146
+ "AMD EPYC™ 4124P","EPYC 4004 Series","4","8","Up to 5.1 GHz","","3.8 GHz","16 MB","149 USD","65W","","AM5","1P","","PCIe® 5.0 x28","DDR5","2","Up to 5200 MT/s","","100-100001570WOF","100-000001570","Yes","AMD Infinity Architecture",""
147
+ "AMD Opteron™ X2170 APU","Opteron X2100 Series APU","4","4","","","2.4 GHz","","","25W","","FT3","","","","DDR3","","Up to 1866 MT/s","","","","","Graphics Core Next Architecture , AMD X86 SoC Technology",""
148
+ "AMD Opteron™ X2150 APU","Opteron X2100 Series APU","4","4","","","1.9 GHz","","","22W","","FT3","","","","DDR3","","","","n/a","OX2150IAJ44HM","","Catalyst Software , AMD HD3D Technology",""
149
+ "AMD Opteron™ X1150","Opteron X1100 Series","4","4","","","2 GHz","","","17W","","FT3","","","","DDR3","","Up to 800 MT/s","","n/a","OX1150IPJ44HM","","",""
150
+ "AMD Opteron™ 6386 SE","Opteron 6300 Series","16","16","Up to 3.5 GHz","","2.8 GHz","16 MB","","140W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6386YETGGHK","","",""
151
+ "AMD Opteron™ 6370P","Opteron 6300 Series","16","16","Up to 2.5 GHz","","2 GHz","16 MB","","99W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6370WQTGGHK","","",""
152
+ "AMD Opteron™ 6366 HE","Opteron 6300 Series","16","16","Up to 3.1 GHz","","1.8 GHz","16 MB","","85W","","G34","","","","DDR3","","Up to 1800 MT/s","","n/a","OS6366VATGGHK","","",""
153
+ "AMD Opteron™ 6338P","Opteron 6300 Series","12","12","Up to 2.8 GHz","","2.3 GHz","16 MB","","99W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6338WQTCGHK","","",""
154
+ "AMD Opteron™ 6380","Opteron 6300 Series","16","16","Up to 3.4 GHz","","2.5 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6380WKTGGHK","","",""
155
+ "AMD Opteron™ 6378","Opteron 6300 Series","16","16","Up to 3.3 GHz","","2.4 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6378WKTGGHK","","",""
156
+ "AMD Opteron™ 6376","Opteron 6300 Series","16","16","Up to 2 GHz","","2.3 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6376WKTGGHK","","",""
157
+ "AMD Opteron™ 6348","Opteron 6300 Series","12","12","Up to 3.4 GHz","","2.8 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6348WKTCGHK","","",""
158
+ "AMD Opteron™ 6344","Opteron 6300 Series","12","12","Up to 2 GHz","","2.6 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6344WKTCGHK","","",""
159
+ "AMD Opteron™ 6328","Opteron 6300 Series","8","8","Up to 3.8 GHz","","3.2 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6328WKT8GHK","","",""
160
+ "AMD Opteron™ 6320","Opteron 6300 Series","8","8","Up to 3.3 GHz","","2.8 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6320WKT8GHK","","",""
161
+ "AMD Opteron™ 6308","Opteron 6300 Series","4","4","","","3.5 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6308WKT4GHK","","",""
162
+ "AMD Opteron™ 4376 HE","Opteron 4300 Series","8","8","Up to 3.6 GHz","","2.6 GHz","8 MB","","65W","","C32","","","","DDR3","","Up to 2000 MT/s","","n/a","OS4376OFU8KHK","","",""
163
+ "AMD Opteron™ 4332 HE","Opteron 4300 Series","6","6","Up to 3.7 GHz","","3 GHz","8 MB","","65W","","C32","","","","DDR3","","Up to 2000 MT/s","","n/a","OS4332OFU6KHK","","",""
164
+ "AMD Opteron™ 4310 EE","Opteron 4300 Series","6","6","Up to 3 GHz","","2.2 GHz","8 MB","","35W","","C32","","","","DDR3","","Up to 1600 MT/s","","n/a","OS4310HPU4KHK","","",""
165
+ "AMD Opteron™ 4386","Opteron 4300 Series","8","8","Up to 3.8 GHz","","3.1 GHz","8 MB","","95W","","C32","","","","DDR3","","Up to 2200 MT/s","","n/a","OS4386WLU8KHK","","",""
166
+ "AMD Opteron™ 4365","Opteron 4300 Series","8","8","Up to 2.8 GHz","","2 GHz","8 MB","","40W","","C32","","","","DDR3","","Up to 1600 MT/s","","n/a","n/a","","",""
167
+ "AMD Opteron™ 4340","Opteron 4300 Series","6","6","Up to 3.8 GHz","","3.5 GHz","8 MB","","95W","","C32","","","","DDR3","","Up to 2200 MT/s","","n/a","OS4340WLU6KHK","","",""
168
+ "AMD Opteron™ 4334","Opteron 4300 Series","6","6","Up to 3.5 GHz","","3.1 GHz","8 MB","","95W","","C32","","","","DDR3","","Up to 2000 MT/s","","n/a","OS4334WLU6KHK","","",""
169
+ "AMD Opteron™ 3350 HE","Opteron 3300 Series","4","4","Up to 3.8 GHz","","2.8 GHz","8 MB","","45W","","AM3+","","","","DDR3","","Up to 2000 MT/s","","n/a","OS3350HOW4KHK","","",""
170
+ "AMD Opteron™ 3320 EE","Opteron 3300 Series","4","4","Up to 2.5 GHz","","1.9 GHz","8 MB","","25W","","AM3+","","","","DDR3","","Up to 1400 MT/s","","n/a","OS3320SJW4KHK","","",""
171
+ "AMD Opteron™ 3380","Opteron 3300 Series","8","8","Up to 3.6 GHz","","2.6 GHz","8 MB","","65W","","AM3+","","","","DDR3","","Up to 2000 MT/s","","n/a","OS3380OLW8KHK","","",""
172
+ "AMD Opteron™ 3365","Opteron 3300 Series","8","8","Up to 3.3 GHz","","2.3 GHz","8 MB","","65W","","AM3+","","","","DDR3","","Up to 2000 MT/s","","n/a","OS3365OLW8KHK","","",""
173
+ "AMD Opteron™ 6284 SE","Opteron 6200 Series","16","16","Up to 3.4 GHz","","2.7 GHz","16 MB","","140W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6284YETGGGU","","",""
174
+ "AMD Opteron™ 6282 SE","Opteron 6200 Series","16","16","Up to 3.3 GHz","","2.6 GHz","16 MB","","140W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6282YETGGGU","","",""
175
+ "AMD Opteron™ 6262 HE","Opteron 6200 Series","16","16","Up to 2.9 GHz","","1.6 GHz","16 MB","","85W","","G34","","","","DDR3","","Up to 1800 MT/s","","n/a","OS6262VATGGGU","","",""
176
+ "AMD Opteron™ 6278","Opteron 6200 Series","16","16","Up to 3.3 GHz","","2.4 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6278WKTGGGU","","",""
177
+ "AMD Opteron™ 6276","Opteron 6200 Series","16","16","Up to 3.2 GHz","","2.3 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6276WKTGGGU","","",""
178
+ "AMD Opteron™ 6274","Opteron 6200 Series","16","16","Up to 3.1 GHz","","2.2 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6274WKTGGGU","","",""
179
+ "AMD Opteron™ 6272","Opteron 6200 Series","16","16","Up to 3 GHz","","2.1 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6272WKTGGGU","","",""
180
+ "AMD Opteron™ 6238","Opteron 6200 Series","12","12","Up to 3.2 GHz","","2.6 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6238WKTCGGU","","",""
181
+ "AMD Opteron™ 6234","Opteron 6200 Series","12","12","Up to 3 GHz","","2.4 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6234WKTCGGU","","",""
182
+ "AMD Opteron™ 6220","Opteron 6200 Series","8","8","Up to 3.6 GHz","","3 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6220WKT8GGU","","",""
183
+ "AMD Opteron™ 6212","Opteron 6200 Series","8","8","Up to 3.2 GHz","","2.6 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6212WKT8GGU","","",""
184
+ "AMD Opteron™ 6204","Opteron 6200 Series","4","4","","","3.3 GHz","16 MB","","115W","","G34","","","","DDR3","","Up to 2000 MT/s","","n/a","OS6204WKT4GGU","","",""
185
+ "AMD Opteron™ 4276 HE","Opteron 4200 Series","8","8","Up to 3.6 GHz","","2.6 GHz","8 MB","","65W","","C32","","","","DDR3","","Up to 2000 MT/s","","n/a","OS4276OFU8KGU","","",""
186
+ "AMD Opteron™ 4274 HE","Opteron 4200 Series","8","8","Up to 3.5 GHz","","2.5 GHz","8 MB","","65W","","C32","","","","DDR3","","Up to 2000 MT/s","","n/a","OS4274OFU8KGU","","",""
187
+ "AMD Opteron™ 4256 EE","Opteron 4200 Series","8","8","Up to 2.8 GHz","","1.6 GHz","8 MB","","35W","","C32","","","","DDR3","","Up to 1600 MT/s","","n/a","OS4256HJU8KGU","","",""
188
+ "AMD Opteron™ 4230 HE","Opteron 4200 Series","6","6","Up to 3.7 GHz","","2.9 GHz","8 MB","","65W","","C32","","","","DDR3","","Up to 2000 MT/s","","n/a","OS4230OFU6KGU","","",""
189
+ "AMD Opteron™ 4228 HE","Opteron 4200 Series","6","6","Up to 3.6 GHz","","2.8 GHz","8 MB","","65W","","C32","","","","DDR3","","Up to 2000 MT/s","","n/a","OS4228OFU6KGU","","",""
190
+ "AMD Opteron™ 4284","Opteron 4200 Series","8","8","Up to 3.7 GHz","","3 GHz","8 MB","","95W","","C32","","","","DDR3","","Up to 2200 MT/s","","n/a","OS4284WLU8KGU","","",""
191
+ "AMD Opteron™ 4280","Opteron 4200 Series","8","8","Up to 2.2 GHz","","2.8 GHz","8 MB","","95W","","C32","","","","DDR3","","Up to 2200 MT/s","","n/a","OS4280WLU8KGU","","",""
192
+ "AMD Opteron™ 4240","Opteron 4200 Series","6","6","Up to 3.8 GHz","","3.4 GHz","8 MB","","95W","","C32","","","","DDR3","","","","n/a","OS4240WLU6KGU","","",""
193
+ "AMD Opteron™ 4238","Opteron 4200 Series","6","6","Up to 3.7 GHz","","3.3 GHz","8 MB","","95W","","C32","","","","DDR3","","Up to 2200 MT/s","","n/a","OS4238WLU6KGU","","",""
194
+ "AMD Opteron™ 4234","Opteron 4200 Series","6","6","Up to 3.5 GHz","","3.1 GHz","8 MB","","95W","","C32","","","","DDR3","","Up to 2200 MT/s","","n/a","OS4234WLU6KGU","","",""
195
+ "AMD Opteron™ 4226","Opteron 4200 Series","6","6","Up to 3.1 GHz","","2.7 GHz","8 MB","","95W","","C32","","","","DDR3","","Up to 2000 MT/s","","n/a","OS4226WLU6KGU","","",""
196
+ "AMD Opteron™ 3260 HE","Opteron 3200 Series","4","4","Up to 3.7 GHz","","2.7 GHz","4 MB","","45W","","AM3+","","","","DDR3","","Up to 2000 MT/s","","OS3260HOW4MGUBOX","OS3260HOW4MGU","","",""
197
+ "AMD Opteron™ 3250 HE","Opteron 3200 Series","","","Up to 3.5 GHz","","2.5 GHz","4 MB","","45W","","AM3+","","","","DDR3","","Up to 2000 MT/s","","OS3250HOW4MGUBOX","OS3250HOW4MGU","","",""
198
+ "AMD Opteron™ 3280","Opteron 3200 Series","8","8","Up to 3.4 GHz","","2.4 GHz","8 MB","","65W","","AM3+","","","","DDR3","","Up to 2000 MT/s","","OS3280OLW8KGUBOX","OS3280OLW8KGU","","",""
199
+ "AMD Opteron™ 6180 SE","Opteron 6100 Series","12","12","","","2.5 GHz","12 MB","","140W","","G34","","","","DDR3","","Up to 1800 MT/s","","n/a","OS6180YETCEGO","","",""
200
+ "AMD Opteron™ 6166 HE","Opteron 6100 Series","12","12","","","1.8 GHz","12 MB","","85W","","G34","","","","DDR3","","Up to 1800 MT/s","","n/a","OS6166VATCEGO","","",""
201
+ "AMD Opteron™ 6132 HE","Opteron 6100 Series","8","8","","","2.2 GHz","12 MB","","85W","","G34","","","","DDR3","","Up to 1800 MT/s","","n/a","OS6132VAT8EGO","","",""
202
+ "AMD Opteron™ 6176","Opteron 6100 Series","12","12","","","2.3 GHz","12 MB","","115W","","G34","","","","DDR3","","Up to 1800 MT/s","","OS6176WKTCEGOWOF","OS6176WKTCEGO","","",""
203
+ "AMD Opteron™ 6140","Opteron 6100 Series","8","8","","","2.6 GHz","12 MB","","115W","","G34","","","","DDR3","","Up to 1800 MT/s","","OS6140WKT8EGOWOF","OS6140WKT8EGO","","",""
codecarbon/data/hardware/cpu_dataset_builder/intel_cpu_ark_dataset.csv ADDED
The diff for this file is too large to render. See raw diff
 
codecarbon/data/hardware/cpu_dataset_builder/intel_cpu_scrapper.py ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Intel CPU Scraper
4
+
5
+ This script uses requests and BeautifulSoup to scrape CPU names and their associated TDP values
6
+ from the Intel ARK website using the advanced filter search URL.
7
+
8
+ hatch run pip install beautifulsoup4
9
+ hatch run python intel_cpu_scrapper.py
10
+
11
+ """
12
+
13
+ import csv
14
+ import os
15
+ import re
16
+ import time
17
+
18
+ import requests
19
+ from bs4 import BeautifulSoup
20
+
21
+
22
+ class IntelCpuScraper:
23
+ """Scraper for Intel CPU data from ARK website."""
24
+
25
+ def __init__(self):
26
+ """Initialize the scraper."""
27
+ self.base_url = "https://www.intel.com/libs/apps/intel/support/ark/advancedFilterSearch?productType=873&3_MaxTDP-Min=0.03&3_MaxTDP-Max=500&forwardPath=/content/www/us/en/ark/featurefilter.html&pageNo={page_num}&sort=&sortType="
28
+ self.results = []
29
+ self.headers = {
30
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
31
+ }
32
+
33
+ def fetch_page(self, page_num):
34
+ """Fetch a single page of results."""
35
+ url = self.base_url.format(page_num=page_num)
36
+ print(f"Fetching URL: {url}")
37
+ try:
38
+ response = requests.get(url, headers=self.headers, timeout=30)
39
+ response.raise_for_status() # Raise an exception for bad status codes
40
+ return response.text
41
+ except requests.exceptions.RequestException as e:
42
+ print(f"Error fetching page {page_num}: {e}")
43
+ return None
44
+
45
+ def parse_html(self, html_content):
46
+ """Parse HTML content to extract CPU data."""
47
+ soup = BeautifulSoup(html_content, "html.parser")
48
+ # Prioritize rows with 'data-product-id' as they are likely the CPU entries
49
+ rows = soup.find_all("tr", {"data-product-id": True})
50
+
51
+ if not rows:
52
+ no_results_message = soup.find("div", class_="no-results-message")
53
+ if (
54
+ no_results_message
55
+ and "no results found" in no_results_message.text.lower()
56
+ ):
57
+ print("No results found on this page (no-results-message).")
58
+ return []
59
+ if "No products matching your selection were found" in html_content:
60
+ print("No results found on this page (No products matching text).")
61
+ return []
62
+ print("No CPU data rows with 'data-product-id' found on the page.")
63
+ return None # Indicate an issue or unexpected structure if no specific "no results" message
64
+
65
+ page_results = []
66
+ for row in rows:
67
+ try:
68
+ # Get all direct child <td> elements of the row
69
+ tds = row.find_all("td", recursive=False)
70
+
71
+ # Expected columns: Name, Launch, Cores, Max Turbo, Base Freq, Cache, TDP
72
+ if len(tds) < 7:
73
+ # print(f"Skipping row, expected at least 7 columns, got {len(tds)}.")
74
+ continue
75
+
76
+ # 1. Product Name
77
+ cpu_name_tag = tds[0].find("a")
78
+ if not cpu_name_tag:
79
+ # print("Skipping row: CPU name tag not found in first cell.")
80
+ continue
81
+ cpu_name = cpu_name_tag.text.strip()
82
+
83
+ # Helper to get text from a td cell
84
+ def get_cell_text(cell_index, tds):
85
+ if cell_index < len(tds) and tds[cell_index]:
86
+ return tds[cell_index].text.strip()
87
+ return ""
88
+
89
+ # 2. Launch Date (e.g., "Q2'25")
90
+ launch_date = get_cell_text(1, tds)
91
+
92
+ # 3. Total Cores (e.g., "40")
93
+ total_cores = get_cell_text(2, tds)
94
+
95
+ # 4. Max Turbo Frequency (e.g., "3.5 GHz")
96
+ max_turbo_frequency = get_cell_text(3, tds)
97
+
98
+ # 5. Processor Base Frequency (e.g., "2.5 GHz")
99
+ processor_base_frequency = get_cell_text(4, tds)
100
+
101
+ # 6. Cache (e.g., "160 MB")
102
+ cache = get_cell_text(5, tds)
103
+
104
+ # 7. TDP (e.g., "235 W")
105
+ tdp_text_content = get_cell_text(6, tds)
106
+ tdp_data_value = (
107
+ tds[6].get("data-value") if len(tds) > 6 and tds[6] else None
108
+ )
109
+
110
+ tdp_numeric = None
111
+ if tdp_data_value and tdp_data_value.replace(".", "", 1).isdigit():
112
+ tdp_numeric = float(tdp_data_value)
113
+ elif "W" in tdp_text_content:
114
+ tdp_match = re.search(r"([\\d.]+)\\s*W", tdp_text_content)
115
+ if tdp_match:
116
+ tdp_numeric = float(tdp_match.group(1))
117
+
118
+ if not cpu_name: # Basic validation
119
+ # print("Skipping row: CPU name is empty.")
120
+ continue
121
+
122
+ result_item = {
123
+ "cpu_name": cpu_name,
124
+ "launch_date": launch_date,
125
+ "total_cores": total_cores,
126
+ "max_turbo_frequency": max_turbo_frequency,
127
+ "processor_base_frequency": processor_base_frequency,
128
+ "cache": cache,
129
+ "tdp": (
130
+ tdp_numeric if tdp_numeric is not None else ""
131
+ ), # Store numeric TDP in Watts
132
+ }
133
+ page_results.append(result_item)
134
+ # print(f"Processed: {cpu_name}, TDP: {tdp_numeric if tdp_numeric is not None else 'N/A'}")
135
+
136
+ except Exception as e:
137
+ print(f"Error parsing a row: {e}")
138
+ # print(f"Problematic row HTML snippet: {str(row)[:500]}")
139
+ return page_results
140
+
141
+ def scrape_all_cpus(self):
142
+ """Scrape all CPU data by iterating through pages."""
143
+ page_num = 1
144
+ consecutive_empty_pages = 0 # To detect end of results
145
+ max_consecutive_empty = (
146
+ 2 # Stop after 2 consecutive pages with no new valid entries
147
+ )
148
+
149
+ while True:
150
+ print(f"Processing page {page_num}...")
151
+ html_content = self.fetch_page(page_num)
152
+
153
+ if html_content is None:
154
+ print(f"Failed to fetch page {page_num} after retries. Stopping.")
155
+ break
156
+
157
+ page_results = self.parse_html(html_content)
158
+
159
+ if page_results is None: # Indicates an unexpected page structure or error
160
+ print(
161
+ f"Could not parse data from page {page_num} or unexpected structure. Stopping."
162
+ )
163
+ break
164
+
165
+ if not page_results:
166
+ consecutive_empty_pages += 1
167
+ print(
168
+ f"No results extracted from page {page_num}. Consecutive empty pages: {consecutive_empty_pages}"
169
+ )
170
+ if consecutive_empty_pages >= max_consecutive_empty:
171
+ print("Reached max consecutive empty pages. Assuming end of data.")
172
+ break
173
+ else:
174
+ consecutive_empty_pages = 0 # Reset counter if we found data
175
+ new_cpus_found_on_page = 0
176
+ for res in page_results:
177
+ if (
178
+ res not in self.results
179
+ ): # Avoid duplicates if any page re-processing happens
180
+ self.results.append(res)
181
+ new_cpus_found_on_page += 1
182
+ print(
183
+ f"Added {new_cpus_found_on_page} new CPUs from page {page_num}. Total CPUs: {len(self.results)}"
184
+ )
185
+ if new_cpus_found_on_page == 0 and len(page_results) > 0:
186
+ # This means all CPUs on this page were duplicates, could be an issue or end of new data
187
+ print(
188
+ f"All {len(page_results)} CPUs on page {page_num} are duplicates. Considering this as end of new data."
189
+ )
190
+ break
191
+
192
+ page_num += 1
193
+ time.sleep(1) # Be respectful to the server
194
+
195
+ print(f"Scraping complete. Found {len(self.results)} CPUs.")
196
+
197
+ def save_to_csv(self, filename="intel_cpu_ark_dataset.csv"):
198
+ """Save the scraped data to a CSV file."""
199
+ filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)
200
+ if not self.results:
201
+ print("No data to save to CSV.")
202
+ return
203
+
204
+ keys = self.results[0].keys()
205
+ with open(filepath, "w", newline="", encoding="utf-8") as f:
206
+ writer = csv.DictWriter(f, fieldnames=keys)
207
+ writer.writeheader()
208
+ writer.writerows(self.results)
209
+ print(f"Data saved to {filepath}")
210
+
211
+
212
+ def main():
213
+ """Main function to run the scraper."""
214
+ scraper = IntelCpuScraper()
215
+ scraper.scrape_all_cpus()
216
+
217
+ if scraper.results:
218
+ scraper.save_to_csv()
219
+ else:
220
+ print("No data was scraped.")
221
+
222
+
223
+ if __name__ == "__main__":
224
+ main()
225
+
226
+
227
+ """
228
+
229
+ Sample content from the Intel ARK page:
230
+
231
+ Product Name
232
+ Launch Date
233
+ Total Cores
234
+ Max Turbo Frequency
235
+ Processor Base Frequency
236
+ Cache
237
+ TDP
238
+
239
+ <tr class="blank-table-row seg-server seg-embedded "
240
+ data-codename="Granite Rapids-D"
241
+ data-filter="Server"
242
+ data-product-id="242908">
243
+ <td class="ark-product-name ark-accessible-color component"
244
+ data-value="4" data-component="arkproductlink"
245
+ data-component-id="1">
246
+ <div class="add-compare-wrap">
247
+ <label class="containerCB component" data-component="wa_skip_track"
248
+ data-component-id="1">
249
+ <input class="compare-checkbox compare-toggle"
250
+ data-component="ark-component"
251
+ data-product-id="242908" type="checkbox">
252
+ <span class="checkmark"></span>
253
+ </label>
254
+ <a href="/content/www/us/en/products/sku/242908/intel-xeon-6716pb-processor-160m-cache-2-50-ghz/specifications.html">Intel® Xeon® 6716P-B Processor</a>
255
+ </div>
256
+ </td>
257
+
258
+ <td class=""
259
+ data-value="">
260
+ Q2'25
261
+ </td>
262
+ <td class=""
263
+ data-value="40">
264
+
265
+ 40
266
+ </td>
267
+ <td class=""
268
+ data-value="3500">
269
+ 3.5 GHz
270
+ </td>
271
+ <td class=""
272
+ data-value="2500">
273
+ 2.5 GHz
274
+ </td>
275
+ <td class=""
276
+ data-value="163840">
277
+ 160 MB
278
+ </td>
279
+ <td class=""
280
+ data-value="235">
281
+ 235 W
282
+ </td>
283
+ </tr>
284
+ """
codecarbon/data/hardware/cpu_dataset_builder/merge_scrapped_cpu_power.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This script updates the CPU power data by reading from Intel and AMD CPU data file,
3
+ cleaning the CPU names, and merging the data into an existing CPU power CSV file.
4
+ It ensures that the TDP values are numeric and updates existing entries or adds new ones.
5
+
6
+ cd codecarbon/data/hardware/cpu_dataset_builder
7
+ hatch run python merge_scrapped_cpu_power.py
8
+
9
+ """
10
+
11
+ import re
12
+
13
+ import pandas as pd
14
+
15
+ # Define file paths
16
+ intel_cpu_file = "intel_cpu_ark_dataset.csv"
17
+ amd_desktop_cpu_file = "amd_cpu_desktop_dataset.csv"
18
+ amd_server_cpu_file = "amd_cpu_server_dataset.csv"
19
+ cpu_power_file = "../cpu_power.csv"
20
+
21
+ # Read Intel CPU data
22
+ try:
23
+ intel_df = pd.read_csv(intel_cpu_file)
24
+ amd_desktop_df = pd.read_csv(amd_desktop_cpu_file)
25
+ amd_server_df = pd.read_csv(amd_server_cpu_file)
26
+ except FileNotFoundError as e:
27
+ print(f"FATAL Error: Data file not found {e}")
28
+ exit(1)
29
+
30
+
31
+ # Clean Intel CPU names and select relevant columns
32
+ def clean_intel_cpu_name(name):
33
+ if pd.isna(name):
34
+ return None
35
+ name = re.sub(r"®", "", name)
36
+ name = name.replace(r"(R)", "")
37
+ name = name.replace(r"(TM)", "")
38
+ name = re.sub(r" Processor", "", name)
39
+ name = re.sub(r" Coprocessor", "", name)
40
+ name = re.sub(r"™", "", name)
41
+ name = re.sub(r" with.*", "", name)
42
+ name = name.strip()
43
+ if not name.startswith("Intel "):
44
+ name = "Intel " + name
45
+ return name
46
+
47
+
48
+ if not intel_df.empty:
49
+ intel_df["Name"] = intel_df["cpu_name"].apply(clean_intel_cpu_name)
50
+ intel_df = intel_df[["Name", "tdp"]].copy()
51
+ intel_df.rename(columns={"tdp": "TDP"}, inplace=True)
52
+ else:
53
+ intel_df = pd.DataFrame(columns=["Name", "TDP"])
54
+
55
+
56
+ # Clean AMD CPU names
57
+ def clean_amd_cpu_name(name):
58
+ if pd.isna(name):
59
+ return None
60
+ name = str(name) # Ensure name is a string
61
+ name = re.sub(r"®", "", name)
62
+ name = name.replace(r"(R)", "")
63
+ name = name.replace(r"(TM)", "")
64
+ name = re.sub(r" Processor", "", name)
65
+ name = re.sub(r"™", "", name)
66
+ name = re.sub(r" with.*", "", name)
67
+ name = name.strip()
68
+ if not name.startswith("AMD "):
69
+ name = "AMD " + name
70
+ return name
71
+
72
+
73
+ def extract_tdp_value(tdp_str):
74
+ if pd.isna(tdp_str):
75
+ return None
76
+ tdp_str = str(tdp_str).replace("W", "").strip()
77
+ # If it's a range like "15-54", take the upper value
78
+ if "-" in tdp_str:
79
+ try:
80
+ return float(tdp_str.split("-")[-1])
81
+ except ValueError:
82
+ return None
83
+ try:
84
+ return float(tdp_str)
85
+ except ValueError:
86
+ return None
87
+
88
+
89
+ amd_desktop_df["Name"] = amd_desktop_df["Name"].apply(clean_amd_cpu_name)
90
+ amd_desktop_df.rename(columns={"Default TDP": "TDP"}, inplace=True)
91
+ amd_desktop_df = amd_desktop_df[["Name", "TDP"]].copy()
92
+ amd_desktop_df["TDP"] = amd_desktop_df["TDP"].apply(extract_tdp_value)
93
+
94
+ amd_server_df["Name"] = amd_server_df["Name"].apply(clean_amd_cpu_name)
95
+ amd_server_df = amd_server_df[["Name", "Default TDP"]].copy()
96
+ amd_server_df.rename(columns={"Default TDP": "TDP"}, inplace=True)
97
+ amd_server_df["TDP"] = amd_server_df["TDP"].apply(extract_tdp_value)
98
+
99
+ # Concatenate all CPU data
100
+ all_cpus_df = pd.concat([intel_df, amd_desktop_df, amd_server_df], ignore_index=True)
101
+
102
+ print(
103
+ f"Total CPUs found: {len(all_cpus_df)} using Intel {len(intel_df)}, AMD Desktop {len(amd_desktop_df)}, and AMD Server {len(amd_server_df)} datasets."
104
+ )
105
+
106
+ # Ensure TDP is numeric, coercing errors to NaN (which will be dropped)
107
+ all_cpus_df["TDP"] = pd.to_numeric(all_cpus_df["TDP"], errors="coerce")
108
+ all_cpus_df.dropna(subset=["Name", "TDP"], inplace=True)
109
+ all_cpus_df["TDP"] = all_cpus_df["TDP"].astype(int)
110
+
111
+
112
+ # Read existing CPU power data
113
+ try:
114
+ cpu_power_df = pd.read_csv(cpu_power_file)
115
+ except FileNotFoundError:
116
+ print(f"FATAL ERROR: cpu_power.csv not found at {cpu_power_file}. Exiting.")
117
+ exit(1)
118
+
119
+
120
+ # Ensure 'Name' column is string type for merging
121
+ cpu_power_df["Name"] = cpu_power_df["Name"].astype(str)
122
+ all_cpus_df["Name"] = all_cpus_df["Name"].astype(str)
123
+
124
+ # Remove duplicates from cpu_power_df before setting index
125
+ cpu_power_df.drop_duplicates(subset=["Name"], keep="first", inplace=True)
126
+ # Remove duplicates from all_cpus_df before setting index to avoid issues if source data also has dupes
127
+ all_cpus_df.drop_duplicates(subset=["Name"], keep="first", inplace=True)
128
+
129
+ # Set 'Name' as index for easier update/merge
130
+ cpu_power_df.set_index("Name", inplace=True)
131
+ all_cpus_df.set_index("Name", inplace=True)
132
+
133
+ # Update existing entries and add new ones
134
+ # For CPUs in all_cpus_df, their TDP will overwrite existing TDP in cpu_power_df
135
+ # New CPUs from all_cpus_df will be added
136
+ cpu_power_df.update(all_cpus_df)
137
+ # Add CPUs from all_cpus_df that were not in cpu_power_df
138
+ new_cpus = all_cpus_df[~all_cpus_df.index.isin(cpu_power_df.index)]
139
+ combined_df = pd.concat([cpu_power_df, new_cpus])
140
+
141
+
142
+ # Reset index and sort
143
+ combined_df.reset_index(inplace=True)
144
+ combined_df.sort_values(by="Name", inplace=True, kind="mergesort")
145
+
146
+ # Drop duplicates, keeping the first occurrence (which would be the updated/new one if there were any issues)
147
+ combined_df.drop_duplicates(subset=["Name"], keep="first", inplace=True)
148
+
149
+
150
+ # Save the updated dataframe
151
+ try:
152
+ combined_df.to_csv(cpu_power_file, index=False)
153
+ print(
154
+ f"Successfully updated {cpu_power_file} with data from Intel and AMD CPU datasets."
155
+ )
156
+ except Exception as e:
157
+ print(f"Error writing to {cpu_power_file}: {e}")
158
+
159
+ print(f"Script finished. {cpu_power_file} has been updated.")
codecarbon/data/hardware/cpu_load_profiling/AMD_EPYC_8024P_8C/compare_cpu_load_and_RAPL-all_cores-AMD_EPYC_8024P_8-Core_Processor-2025-01-14-tasks.csv ADDED
@@ -0,0 +1 @@
 
 
1
+
codecarbon/data/hardware/cpu_load_profiling/AMD_EPYC_8024P_8C/compare_cpu_load_and_RAPL-all_cores-AMD_EPYC_8024P_8-Core_Processor-2025-01-14.csv ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_name,load_type,cpu_name,timestamp,cores_used,cpu_load,temperature,cpu_freq,rapl_power,rapl_energy,estimated_power,estimated_energy,tapo_power,tapo_energy,tapo_time_delta,duration
2
+ Load for 0 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870539.3604305,16,0.6,0,1588.8038125,0.5890910446092622,0.0001549484709031223,0.5283870967741936,4.483109622193541e-06,0,0,0,30.545820467999988
3
+ Load for 10 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870570.4132967,16,10.0,0,1499.2493125,18.614618427174943,0.0002482180077409144,9.351290322580647,7.94934203722469e-05,0,0,0,30.604371506000007
4
+ Load for 20 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870601.5247905,16,20.0,0,1710.87575,29.50062862301284,0.0003278735881319947,18.08709677419355,0.00015376875545155633,0,0,0,30.60747165600003
5
+ Load for 30 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870632.6398633,16,30.0,0,2275.4458125,38.665937352398046,0.00035451283138781577,26.628387096774198,0.000226326359785935,0,0,0,30.59898082199993
6
+ Load for 40 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870663.7467482,16,40.3,0,2005.7899375,41.7532422053059,0.000365986424177794,35.12903225806452,0.0002984793734458876,0,0,0,30.587945687
7
+ Load for 50 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870694.8418806,16,50.0,0,2995.3906875,43.218847417139216,0.0004040316335028266,43.96064516129032,0.00037339789414168585,0,0,0,30.579274994000002
8
+ Load for 60 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870725.9287038,16,64.6,0,2995.0565625,47.60235461601638,0.0004135376972187821,52.64709677419356,0.0004470785513329841,0,0,0,30.572279641000023
9
+ Load for 70 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870757.008383,16,70.2,0,2995.4159375,48.71374809013383,0.00041818504176998825,61.33064516129033,0.0005208395157953634,0,0,0,30.573280777000036
10
+ Load for 80 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870788.0900218,16,80.0,0,2995.0515,49.29431270782221,0.00043202708951028436,69.78193548387098,0.0005926033291364812,0,0,0,30.572722531999943
11
+ Load for 90 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870819.169809,16,89.4,0,2995.3314375,50.71795701044753,0.00039116028792797984,78.46548387096773,0.0006661357492079613,0,0,0,30.563372235000088
12
+ Load for 100 threads or % load on all_cores,all_cores,AMD EPYC 8024P 8-Core Processor,1736870850.241218,16,100.0,0,2960.06425,46.07999203334885,0.0003927146597270323,86.62645161290322,0.0007355714738463658,0,0,0,30.57010326000011
codecarbon/data/hardware/cpu_load_profiling/AMD_EPYC_8024P_8C/compare_cpu_load_and_RAPL-some_cores-AMD_EPYC_8024P_8-Core_Processor-2025-01-14-tasks.csv ADDED
@@ -0,0 +1 @@
 
 
1
+
codecarbon/data/hardware/cpu_load_profiling/AMD_EPYC_8024P_8C/compare_cpu_load_and_RAPL-some_cores-AMD_EPYC_8024P_8-Core_Processor-2025-01-14.csv ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_name,load_type,cpu_name,timestamp,cores_used,cpu_load,temperature,cpu_freq,rapl_power,rapl_energy,estimated_power,estimated_energy,tapo_power,tapo_energy,tapo_time_delta,duration
2
+ Load for 0 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736870885.4314823,0,0.0,0,1573.6895625,0.570341609175781,0.0001498387148708754,0.4006451612903227,3.3952651785241804e-06,0,0,0,30.509340853999902
3
+ Load for 1 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736870916.4484718,1,6.8,0,1674.0149375,18.32137992981586,0.0003186004209912441,6.143225806451613,5.213020505654175e-05,0,0,0,30.548963089000154
4
+ Load for 3 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736870947.5048661,3,18.6,0,1875.329125,37.67548313872943,0.00035289236703589175,16.79806451612903,0.00014253898582775382,0,0,0,30.54814376499985
5
+ Load for 4 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736870978.5606444,4,24.8,0,1917.428375,41.64788408234253,0.0003687826669703416,22.357741935483872,0.00018972382129295778,0,0,0,30.549244971999997
6
+ Load for 6 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736871009.6169264,6,37.3,0,2390.904875,43.577488003823284,0.00040014462511544363,33.12870967741936,0.0002811189356871732,0,0,0,30.54906796199998
7
+ Load for 8 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736871040.6735368,8,50.3,0,2577.975125,47.22484688134498,0.0004186007634914522,43.899677419354845,0.00037251962926638875,0,0,0,30.54776646800019
8
+ Load for 9 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736871071.7283158,9,56.2,0,2552.9630625,49.348595570337984,0.00042330994975879783,49.53193548387097,0.00042031326421113654,0,0,0,30.549575562999962
9
+ Load for 11 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736871102.7853847,11,71.6,0,2786.4235,49.929496571226025,0.0004353003696289052,60.29419354838709,0.0005116486368893932,0,0,0,30.549821148999854
10
+ Load for 12 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736871133.8423305,12,78.1,0,2864.8995625,51.11155331744621,0.0003866883171281862,65.8741935483871,0.0005590049861902901,0,0,0,30.550244901000042
11
+ Load for 14 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736871164.901577,14,87.5,0,2994.7883125,45.597339246911396,0.00039462264042008227,76.74677419354839,0.0006513229867146689,0,0,0,30.552348375000065
12
+ Load for 16 threads or % load on some_cores,some_cores,AMD EPYC 8024P 8-Core Processor,1736871195.9626908,16,100.0,0,2953.2051875,46.50666589353752,0.00039668247206794613,87.01548387096774,0.0007384650344527547,0,0,0,30.552532602999918
codecarbon/data/hardware/cpu_load_profiling/AMD_Threadripper/compare_cpu_load_and_RAPL-all_cores-AMD_Ryzen_Threadripper_1950X_16-Core_Processor-2025-01-14.csv ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_name,load_type,cpu_name,timestamp,cores_used,cpu_load,temperature,cpu_freq,rapl_power,rapl_energy,estimated_power,estimated_energy,tapo_power,tapo_energy,tapo_time_delta,duration
2
+ Load for 0 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861292.1865184,32,2.8,34.0,2332.872375,1.376693725703893,0.00036348698592824497,2.685483870967742,2.287107937566501e-05,115,0,25.784160137176514,30.67482220400052
3
+ Load for 10 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861323.3733351,32,13.9,39.0,2398.1069375,43.30157205175239,0.0005287301286782094,18.41632258064516,0.00015699294566882027,147,2,31.239955186843872,30.690144125997904
4
+ Load for 20 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861354.606225,32,23.2,49.0,2525.59284375,62.548275592287716,0.000667400991698144,51.95264516129033,0.0004430374025184006,198,1,31.248691082000732,30.67295572799776
5
+ Load for 30 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861385.796707,32,36.4,46.0,2797.5584375,79.17104774627222,0.0009009795239774861,82.75797881016943,0.0007061364594770959,226,2,31.160773754119873,30.710970439999073
6
+ Load for 40 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861417.028149,32,44.8,51.0,2821.1256562500002,106.32788732711822,0.0010895405520484095,121.69003144108179,0.001039181644778305,257,2,31.274537086486816,30.744163438001124
7
+ Load for 50 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861448.2934384,32,53.1,52.0,2987.12765625,128.12680031791092,0.0012224324344729436,150.75142340191675,0.0012868445490575916,219,2,31.180025577545166,30.71990360300333
8
+ Load for 60 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861479.5261245,32,66.0,56.0,3690.57340625,144.1489018144105,0.0014702612339858234,160.82284379438934,0.0013702119021750114,285,2,31.250231504440308,30.68199840700254
9
+ Load for 70 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861510.718988,32,72.1,57.0,3576.53553125,172.4348439188416,0.0014511648695420768,166.20343002665635,0.001415799954084005,278,3,31.177345514297485,30.66615740099951
10
+ Load for 80 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861541.892845,32,83.1,56.0,3418.62696875,170.32448690508448,0.0014419653435713518,169.0462755144238,0.001440005981082607,279,2,31.25270128250122,30.67268269300257
11
+ Load for 90 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861573.0767784,32,91.7,56.0,3357.159875,169.17512402821018,0.001424203854084394,170.99110652598637,0.0014592032859312692,277,2,31.135616064071655,30.722248964000755
12
+ Load for 100 threads or % load on all_cores,all_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861604.3297272,32,99.7,56.0,3323.42371875,166.8914474009169,0.0014241745394776087,172.01108915577154,0.0014670329755684629,278,3,31.260193586349487,30.684765958001663
codecarbon/data/hardware/cpu_load_profiling/AMD_Threadripper/compare_cpu_load_and_RAPL-some_cores-AMD_Ryzen_Threadripper_1950X_16-Core_Processor-2025-01-14.csv ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_name,load_type,cpu_name,timestamp,cores_used,cpu_load,temperature,cpu_freq,rapl_power,rapl_energy,estimated_power,estimated_energy,tapo_power,tapo_energy,tapo_time_delta,duration
2
+ Load for 0 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861645.8957796,0,5.0,44.0,2404.504125,1.4314313929445108,0.00037612030867378377,2.5403225806451615,2.1533075069456695e-05,161,2,41.54746890068054,30.50736453400168
3
+ Load for 3 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861676.92222,3,12.2,53.0,2470.4883125,45.38482572705677,0.000643388347349155,15.636774193548389,0.00013281317053516283,159,1,31.027068614959717,30.60917342099856
4
+ Load for 6 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861708.0628958,6,22.9,57.0,2782.765875,76.2361648967495,0.0007852407877754612,45.20264516129032,0.00038409021052205965,178,2,31.136895179748535,30.582065591002902
5
+ Load for 9 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861739.1693892,9,32.2,53.0,2985.71678125,93.3325909425021,0.0010383771248677017,79.43787901061218,0.0006748331769033504,266,2,31.1038601398468,30.566226797000127
6
+ Load for 12 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861770.2447922,12,41.4,56.0,3206.83459375,123.02110940943629,0.0012440137061823899,106.22233175845183,0.000901886908494226,278,2,31.06801199913025,30.572869749998063
7
+ Load for 16 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861801.3405495,16,52.0,59.0,3497.22140625,147.40291619865533,0.0014847857724110004,151.95548639522778,0.0012909726593646263,278,2,31.09264326095581,30.595551153000997
8
+ Load for 19 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861832.4449117,19,64.0,61.0,3411.51403125,174.78376979270854,0.001472625799905254,161.29498553839264,0.0013694488571545866,279,3,31.248048543930054,30.567659471998923
9
+ Load for 22 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861863.553106,22,73.1,60.0,3552.37396875,173.30973054466918,0.0014398759664831836,165.96767419530283,0.0014106243805873664,324,2,31.02893352508545,30.57063357000152
10
+ Load for 25 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861894.641952,25,80.1,60.0,3314.47165625,169.42739506124113,0.0014223668401147846,169.16041577918944,0.0014371547304600357,326,3,31.0912823677063,30.577015545000904
11
+ Load for 28 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861925.7400923,28,92.5,59.0,3611.6851875,167.4199618733835,0.0014106022938975976,170.8023391866958,0.0014508931444192387,280,3,31.036678552627563,30.5716582189998
12
+ Load for 32 threads or % load on some_cores,some_cores,AMD Ryzen Threadripper 1950X 16-Core Processor,1736861956.8230855,32,100.0,58.0,3399.25659375,166.03346252141944,0.0014042897956531592,172.11738734560865,0.0014619673561903947,290,2,31.138123273849487,30.579071764001128
codecarbon/data/hardware/cpu_load_profiling/E3-1240/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14-tasks.csv ADDED
@@ -0,0 +1 @@
 
 
1
+
codecarbon/data/hardware/cpu_load_profiling/E3-1240/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14.csv ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_name,load_type,cpu_name,timestamp,cores_used,cpu_load,temperature,cpu_freq,rapl_power,rapl_energy,estimated_power,estimated_energy,tapo_power,tapo_energy,tapo_time_delta,duration
2
+ Load for 0 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866099.9980605,8,2.5,49.0,1599.327875,0.1762793799621185,4.6355697362304715e-05,0.9059032258064517,7.684335073074023e-06,0,0,0,30.538775300999987
3
+ Load for 10 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866131.0446987,8,12.5,49.8,1599.292875,5.5088107550388195,5.799798473168395e-05,7.701290322580645,6.536165501667947e-05,0,0,0,30.556003262000104
4
+ Load for 20 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866162.1088045,8,21.8,49.8,1615.887,6.874427700098117,6.887324732077552e-05,14.45883870967742,0.00012281514661734017,0,0,0,30.5808577480002
5
+ Load for 30 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866193.198372,8,32.5,51.2,1608.707625,8.150962966608036,8.008787768136114e-05,21.122903225806454,0.00017917736530554418,0,0,0,30.538505429999987
6
+ Load for 40 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866224.2449238,8,41.2,52.6,1774.674,9.590357335248587,0.00011939784885153792,27.519870967741934,0.00023356720765311314,0,0,0,30.55596754599992
7
+ Load for 50 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866255.3088953,8,51.3,67.0,3691.3945,14.386126401140913,0.0002032038075629114,34.119387096774204,0.0002894370308469203,0,0,0,30.540959523999845
8
+ Load for 60 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866286.357926,8,60.8,67.8,3203.470375,24.131781439057242,0.0002502017190501027,40.80125806451613,0.00034607542561449563,0,0,0,30.536806867999985
9
+ Load for 70 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866317.402762,8,71.3,82.6,3592.053,29.980918434149974,0.0003775369217515201,47.27390322580646,0.0004010445097183033,0,0,0,30.541943295000237
10
+ Load for 80 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866348.452758,8,80.2,86.0,3594.7035,44.58692502781162,0.0004000440664238894,53.58183870967742,0.00045449143269400997,0,0,0,30.537735556999905
11
+ Load for 90 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866379.4978347,8,88.9,84.6,3591.723,47.199718258502074,0.0004102256151246736,60.172451612903224,0.0005103165358412896,0,0,0,30.533969553000134
12
+ Load for 100 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866410.5401917,8,100.0,85.2,3591.759875,48.40222176814008,0.00041915237032163,66.44032258064517,0.0005636082589397366,0,0,0,30.540446279000207
codecarbon/data/hardware/cpu_load_profiling/E3-1240/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14-tasks.csv ADDED
@@ -0,0 +1 @@
 
 
1
+
codecarbon/data/hardware/cpu_load_profiling/E3-1240/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14.csv ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ task_name,load_type,cpu_name,timestamp,cores_used,cpu_load,temperature,cpu_freq,rapl_power,rapl_energy,estimated_power,estimated_energy,tapo_power,tapo_energy,tapo_time_delta,duration
2
+ Load for 0 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866451.8262937,0,2.5,59.4,1622.370375,0.1829557095380892,4.8066226786283583e-05,1.175225806451613,9.959652394347182e-06,0,0,0,30.510028410999894
3
+ Load for 1 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866482.8443036,1,13.7,66.8,2909.180125,6.1681087430444785,0.00017863574624181477,8.820870967741937,7.480994601777782e-05,0,0,0,30.532809745000122
4
+ Load for 2 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866513.885087,2,25.3,74.4,3154.836875,21.330531392160513,0.0002490961023322788,17.167645161290324,0.00014560237809553166,0,0,0,30.533378567
5
+ Load for 3 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866544.926259,3,38.8,82.4,3379.551,29.60393014529158,0.000310693952443852,25.54335483870968,0.00021663643725879813,0,0,0,30.533274188000178
6
+ Load for 4 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866575.9672496,4,50.0,90.6,3093.732375,36.830415975414766,0.000362681275978122,33.9123870967742,0.00028761470732627394,0,0,0,30.533258208000007
7
+ Load for 5 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866607.008547,5,60.8,93.8,3591.593,42.818970213978986,0.00037760179374785995,41.602548387096775,0.0003528519844455608,0,0,0,30.534384863000014
8
+ Load for 6 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866638.0509386,6,76.2,90.0,3342.7835,44.592887191004166,0.0003967921685445921,50.56587096774194,0.00042885450421531923,0,0,0,30.533063157000015
9
+ Load for 7 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866669.0927322,7,88.7,83.0,3591.758125,46.8127764264249,0.0004043059895556436,59.023935483870964,0.0005006315188387323,0,0,0,30.53561314799981
10
+ Load for 8 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736866700.138663,8,100.0,84.2,3591.768875,47.73004219703574,0.0004210827754770616,66.56941935483871,0.0005645897030578939,0,0,0,30.5334539090004
codecarbon/data/hardware/cpu_load_profiling/E5-1240/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14-tasks.csv ADDED
@@ -0,0 +1 @@
 
 
1
+
codecarbon/data/hardware/cpu_load_profiling/E5-1240/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14.csv ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_name,load_type,cpu_name,timestamp,cores_used,cpu_load,temperature,cpu_freq,rapl_power,rapl_energy,estimated_power,estimated_energy,tapo_power,tapo_energy,tapo_time_delta,duration
2
+ Load for 0 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864264.566133,8,2.5,55.4,1597.2875,0.24045452886021762,6.321467779392322e-05,0.9437419354838712,8.00299163331743e-06,0,0,0,30.530655949999982
3
+ Load for 10 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864295.6047955,8,10.3,56.0,1608.7538749999999,7.538504597340449,8.54672550404164e-05,7.728000000000001,6.558665694214691e-05,0,0,0,30.552170786000033
4
+ Load for 20 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864326.6656816,8,21.3,56.6,1596.3545,10.155731937011202,0.00010787949074796827,14.314161290322582,0.00012158928507307066,0,0,0,30.58094489799987
5
+ Load for 30 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864357.7544494,8,31.6,57.4,1597.23125,12.777656622991184,0.00012821319923714356,21.04277419354839,0.0001784956265845537,0,0,0,30.539114385999937
6
+ Load for 40 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864388.8024442,8,41.3,58.6,2180.2647500000003,15.395214417842357,0.0002021824959125328,27.571064516129034,0.00023397646594410047,0,0,0,30.551980603000175
7
+ Load for 50 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864419.8624222,8,51.9,61.8,1793.815125,24.21258198840792,0.0003044742055236128,34.221774193548384,0.00029040600192907343,0,0,0,30.55149350800002
8
+ Load for 60 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864450.9216642,8,62.0,78.2,3588.65625,36.60190500045977,0.0004947912699993662,40.71445161290323,0.00034540601126875473,0,0,0,30.542951248999998
9
+ Load for 70 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864481.9730074,8,70.0,87.6,3591.77275,59.21681786864419,0.0007304884855014321,47.18487096774194,0.0004002782981833257,0,0,0,30.540747797999984
10
+ Load for 80 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864513.0216124,8,80.0,92.4,3591.752625,86.28703440247716,0.0007775349425830115,53.49503225806452,0.00045366902355707455,0,0,0,30.532312602000047
11
+ Load for 90 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864544.062235,8,89.6,93.8,3591.755875,91.60016243312562,0.0007568507235356488,58.56987096774195,0.0004968053414603382,0,0,0,30.538087567000048
12
+ Load for 100 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864575.1117647,8,84.6,93.4,3591.759375,89.35810683301246,0.0007923197952442191,63.940741935483864,0.0005423658388764648,0,0,0,30.537738765000086
codecarbon/data/hardware/cpu_load_profiling/E5-1240/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14-tasks.csv ADDED
@@ -0,0 +1 @@
 
 
1
+
codecarbon/data/hardware/cpu_load_profiling/E5-1240/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E3-1240_V2_@_3.40GHz-2025-01-14.csv ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ task_name,load_type,cpu_name,timestamp,cores_used,cpu_load,temperature,cpu_freq,rapl_power,rapl_energy,estimated_power,estimated_energy,tapo_power,tapo_energy,tapo_time_delta,duration
2
+ Load for 0 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864616.3802829,0,1.3,64.4,1722.9547499999999,0.24348604948238767,6.396986895363006e-05,0.9637741935483872,8.167858581407357e-06,0,0,0,30.510393207000106
3
+ Load for 1 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864647.3992167,1,13.8,71.8,2908.105125,8.546889319740076,0.00032664317798099946,8.972225806451613,7.609811727004668e-05,0,0,0,30.53422949700007
4
+ Load for 2 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864678.4420338,2,25.0,77.6,2677.836875,39.05248608945464,0.00046885920175372686,17.312322580645162,0.00014683093029187213,0,0,0,30.53335141499997
5
+ Load for 3 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864709.4832304,3,38.8,82.0,3093.805875,55.74034273843472,0.00058967813118657,25.610129032258065,0.0002172003980805138,0,0,0,30.53297458499992
6
+ Load for 4 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864740.5242574,4,51.3,89.4,3592.125625,69.91521339597362,0.000691733977831184,34.019225806451615,0.0002885280151346684,0,0,0,30.534353922000037
7
+ Load for 5 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864771.5664937,5,60.0,94.6,3591.77,81.68108269518869,0.0007244284862089941,41.13290322580646,0.0003488550486577481,0,0,0,30.533480329999975
8
+ Load for 6 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864802.6076632,6,70.9,92.6,3591.811375,85.51117470400919,0.0007499405605075199,49.79129032258064,0.0004222963451957981,0,0,0,30.534298728000067
9
+ Load for 7 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864833.6504998,7,88.9,90.6,3591.7715,88.5859467712891,0.000793641966024175,59.197548387096774,0.0005020658069015539,0,0,0,30.533413398999983
10
+ Load for 8 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz,1736864864.6926847,8,100.0,90.6,3591.7475,93.67184784435268,0.0008193529074262459,66.63396774193548,0.000565153702695967,0,0,0,30.53452582199975
codecarbon/data/hardware/cpu_load_profiling/E5-2620/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E5-2620_v3_@_2.40GHz-2025-01-14-tasks.csv ADDED
@@ -0,0 +1 @@
 
 
1
+
codecarbon/data/hardware/cpu_load_profiling/E5-2620/compare_cpu_load_and_RAPL-all_cores-Intel(R)_Xeon(R)_CPU_E5-2620_v3_@_2.40GHz-2025-01-14.csv ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_name,load_type,cpu_name,timestamp,cores_used,cpu_load,temperature,cpu_freq,rapl_power,rapl_energy,estimated_power,estimated_energy,tapo_power,tapo_energy,tapo_time_delta,duration
2
+ Load for 0 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736851743.3478487,24,0.0,32.92857142857143,1666.6777916666667,0.5133866472185064,0.00013516682896670684,0.13709677419354838,1.1643220985035955e-06,0,0,0,30.57596656700025
3
+ Load for 10 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736851774.4329672,24,10.0,34.0,1395.8670833333333,16.393231698147034,0.0002615093458739823,16.70387096774194,0.00014209152257347633,0,0,0,30.625665163999656
4
+ Load for 20 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736851805.5679224,24,20.0,35.214285714285715,1200.067875,30.981249858901204,0.00032480096234055456,33.150000000000006,0.00028184237688695906,0,0,0,30.609375409999302
5
+ Load for 30 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736851836.6865406,24,30.0,36.42857142857143,1200.0924166666666,38.4109895669274,0.0003803408392724292,49.54677419354839,0.00042138001590360423,0,0,0,30.619102634000228
6
+ Load for 40 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736851867.8147955,24,40.5,39.0,1359.3699583333334,45.28221173134997,0.0005286525493105876,65.92709677419354,0.000560481283428218,0,0,0,30.607923018999827
7
+ Load for 50 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736851898.9319813,24,50.2,40.07142857142857,1675.1815833333333,62.15733970891361,0.0005226188955947848,82.30741935483871,0.0006995284841773753,0,0,0,30.598696191000272
8
+ Load for 60 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736851930.0399046,24,60.0,42.42857142857143,2081.6238333333336,61.94885605758223,0.0006439153740207745,98.64935483870968,0.0008383901874825152,0,0,0,30.59755781199965
9
+ Load for 70 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736851961.1466608,24,69.9,47.42857142857143,2600.2822499999997,76.92334580239137,0.0009501084453639348,114.92,0.0009769654159054015,0,0,0,30.606379566000214
10
+ Load for 80 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736851992.2622006,24,80.8,49.714285714285715,2606.1148333333335,111.88460818853675,0.0009838415673504054,131.25645161290325,0.0011155469922320095,0,0,0,30.59841364100066
11
+ Load for 90 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852023.370749,24,89.7,51.642857142857146,2566.944875,115.80752337627442,0.0009980875206916026,147.63129032258067,0.0012548379009832316,0,0,0,30.60126471300009
12
+ Load for 100 threads or % load on all_cores,all_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852054.4802783,24,99.6,51.214285714285715,2400.266,117.01747308959027,0.0008921996457035876,163.77032258064517,0.001391876641844674,0,0,0,30.598267295999904
codecarbon/data/hardware/cpu_load_profiling/E5-2620/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E5-2620_v3_@_2.40GHz-2025-01-14-tasks.csv ADDED
@@ -0,0 +1 @@
 
 
1
+
codecarbon/data/hardware/cpu_load_profiling/E5-2620/compare_cpu_load_and_RAPL-some_cores-Intel(R)_Xeon(R)_CPU_E5-2620_v3_@_2.40GHz-2025-01-14.csv ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_name,load_type,cpu_name,timestamp,cores_used,cpu_load,temperature,cpu_freq,rapl_power,rapl_energy,estimated_power,estimated_energy,tapo_power,tapo_energy,tapo_time_delta,duration
2
+ Load for 0 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852095.9750729,0,0.0,42.142857142857146,1479.1971666666668,0.5065285278727721,0.00013308117646485332,0.10419354838709678,8.830525274655887e-07,0,0,0,30.511303407000014
3
+ Load for 2 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852126.9954355,2,8.7,41.0,1316.7375833333333,16.312251102677653,0.00029392221235980537,13.852258064516132,0.00011764077408649119,0,0,0,30.57471732799968
4
+ Load for 4 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852158.079285,4,17.0,40.142857142857146,1212.5389583333333,34.76638021452525,0.00033555079427375484,27.671612903225803,0.00023500116479415815,0,0,0,30.57451805099936
5
+ Load for 7 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852189.1629093,7,29.0,41.214285714285715,1361.3113333333333,39.833438799011766,0.0004206977390579236,48.15387096774193,0.00040898022458755426,0,0,0,30.57759773700036
6
+ Load for 9 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852220.2496197,9,37.9,41.0,1200.0558333333333,49.54412283036035,0.00042417380406099825,61.92387096774194,0.0005259465888520012,0,0,0,30.577943293000317
7
+ Load for 12 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852251.3367052,12,50.0,42.214285714285715,1254.2069583333334,50.48931782182756,0.0005688961442832166,82.45548387096774,0.0007003238567262363,0,0,0,30.577464056999816
8
+ Load for 14 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852282.4232924,14,58.7,43.642857142857146,1400.1012083333335,67.12624394179127,0.0006075904494053028,96.15419354838708,0.0008166565664626951,0,0,0,30.5767449519999
9
+ Load for 16 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852313.508811,16,66.7,44.642857142857146,1458.4309166666665,71.54867753236186,0.0006107800055680582,109.87483870967742,0.0009332072212445437,0,0,0,30.57744154000011
10
+ Load for 19 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852344.5952287,19,79.2,45.92857142857143,1721.068375,72.0308325399428,0.0006425051590037145,130.43387096774194,0.0011079623452897123,0,0,0,30.58129966099932
11
+ Load for 21 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852375.6856108,21,87.5,46.214285714285715,1712.7019166666666,75.74636452660306,0.0006716593131603499,144.1051612903226,0.001224281732537364,0,0,0,30.589186831000006
12
+ Load for 24 threads or % load on some_cores,some_cores,Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz,1736852406.785565,24,100.0,48.07142857142857,2250.244458333333,79.60567601760141,0.0008177076741656131,164.37354838709678,0.0013961793068869984,0,0,0,30.57898776299953
codecarbon/data/hardware/cpu_power.csv ADDED
The diff for this file is too large to render. See raw diff
 
codecarbon/data/private_infra/2016/canada_energy_mix.json ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "british columbia": {
3
+ "naturalGas": 1.1,
4
+ "nuclear": 0.0,
5
+ "petroleum": 0.7,
6
+ "biomass": 6.4,
7
+ "coal": 0.0,
8
+ "other": 0.0,
9
+ "solar": 0.0,
10
+ "tidal": 0.0,
11
+ "total": 100,
12
+ "wind": 1.3,
13
+ "hydro": 90.5
14
+ },
15
+ "newfoundland and labrador": {
16
+ "naturalGas": 0.7,
17
+ "nuclear": 0.0,
18
+ "petroleum": 4.8,
19
+ "biomass": 0.3,
20
+ "coal": 0.0,
21
+ "other": 0.0,
22
+ "solar": 0.0,
23
+ "tidal": 0.0,
24
+ "total": 100,
25
+ "wind": 0.5,
26
+ "hydro": 93.7
27
+ },
28
+ "saskatchewan": {
29
+ "naturalGas": 35.7,
30
+ "nuclear": 0.0,
31
+ "petroleum": 0.0,
32
+ "biomass": 0.0,
33
+ "coal": 46.6,
34
+ "other": 0.0,
35
+ "solar": 0.1,
36
+ "tidal": 0.0,
37
+ "total": 99.9,
38
+ "wind": 3.8,
39
+ "hydro": 13.7
40
+ },
41
+ "prince edward island": {
42
+ "naturalGas": 0.0,
43
+ "nuclear": 0.0,
44
+ "petroleum": 1.1,
45
+ "biomass": 0.7,
46
+ "coal": 0.0,
47
+ "other": 0.0,
48
+ "solar": 0.3,
49
+ "tidal": 0.0,
50
+ "total": 100,
51
+ "wind": 97.9,
52
+ "hydro": 0.0
53
+ },
54
+ "ontario": {
55
+ "naturalGas": 5.2,
56
+ "nuclear": 58.6,
57
+ "petroleum": 0.1,
58
+ "biomass": 1.3,
59
+ "coal": 0.0,
60
+ "other": 0.0,
61
+ "solar": 2.2,
62
+ "tidal": 0.0,
63
+ "total": 100,
64
+ "wind": 6.7,
65
+ "hydro": 25.9
66
+ },
67
+ "nova scotia": {
68
+ "naturalGas": 14.3,
69
+ "nuclear": 0.0,
70
+ "petroleum": 12.2,
71
+ "biomass": 4.9,
72
+ "coal": 47.9,
73
+ "other": 0.0,
74
+ "solar": 0.03,
75
+ "tidal": 0.2,
76
+ "total": 100.13,
77
+ "wind": 11.8,
78
+ "hydro": 8.8
79
+ },
80
+ "quebec": {
81
+ "naturalGas": 0.1,
82
+ "nuclear": 0.0,
83
+ "petroleum": 0.2,
84
+ "biomass": 0.8,
85
+ "coal": 0.0,
86
+ "other": 0.0,
87
+ "solar": 0.0,
88
+ "tidal": 0.0,
89
+ "total": 100,
90
+ "wind": 3.9,
91
+ "hydro": 95.0
92
+ },
93
+ "alberta": {
94
+ "naturalGas": 42.2,
95
+ "nuclear": 0.0,
96
+ "petroleum": 2.6,
97
+ "biomass": 2.2,
98
+ "coal": 44.9,
99
+ "other": 0.2,
100
+ "solar": 0.1,
101
+ "tidal": 0.0,
102
+ "total": 100.1,
103
+ "wind": 5.4,
104
+ "hydro": 2.5
105
+ },
106
+ "manitoba": {
107
+ "naturalGas": 0.0,
108
+ "nuclear": 0.0,
109
+ "petroleum": 0.2,
110
+ "biomass": 0.1,
111
+ "coal": 0.1,
112
+ "other": 0.0,
113
+ "solar": 0.0,
114
+ "tidal": 0.0,
115
+ "total": 99.9,
116
+ "wind": 2.7,
117
+ "hydro": 96.8
118
+ },
119
+ "northwest territories": {
120
+ "naturalGas": 4.0,
121
+ "nuclear": 0.0,
122
+ "petroleum": 55.3,
123
+ "biomass": 0.0,
124
+ "coal": 0.0,
125
+ "other": 0.0,
126
+ "solar": 0.2,
127
+ "tidal": 0.0,
128
+ "total": 100,
129
+ "wind": 2.0,
130
+ "hydro": 38.5
131
+ },
132
+ "new brunswick": {
133
+ "naturalGas": 9.9,
134
+ "nuclear": 36.1,
135
+ "petroleum": 7.6,
136
+ "biomass": 4.2,
137
+ "coal": 15.8,
138
+ "other": 0.0,
139
+ "solar": 0.0,
140
+ "tidal": 0.0,
141
+ "total": 99.8,
142
+ "wind": 6.6,
143
+ "hydro": 19.6
144
+ },
145
+ "nunavut": {
146
+ "naturalGas": 0.0,
147
+ "nuclear": 0.0,
148
+ "petroleum": 100.0,
149
+ "biomass": 0.0,
150
+ "coal": 0.0,
151
+ "other": 0.0,
152
+ "solar": 0.0,
153
+ "tidal": 0.0,
154
+ "total": 100,
155
+ "wind": 0.0,
156
+ "hydro": 0.0
157
+ },
158
+ "yukon": {
159
+ "naturalGas": 2.0,
160
+ "nuclear": 0.0,
161
+ "petroleum": 5.5,
162
+ "biomass": 0.0,
163
+ "coal": 0.0,
164
+ "other": 0.0,
165
+ "solar": 0.3,
166
+ "tidal": 0.0,
167
+ "total": 100,
168
+ "wind": 0.0,
169
+ "hydro": 92.2
170
+ }
171
+ }