codecarbon 3.2.9__tar.gz → 3.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codecarbon-3.2.9 → codecarbon-3.3.0}/PKG-INFO +46 -16
- {codecarbon-3.2.9 → codecarbon-3.3.0}/README.md +45 -15
- codecarbon-3.3.0/codecarbon/_version.py +1 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/cli/main.py +46 -15
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/api_client.py +52 -80
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/hardware_cache.py +5 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/powermetrics.py +2 -4
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/resource_tracker.py +26 -9
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/util.py +1 -1
- codecarbon-3.3.0/codecarbon/core/windows_emi.py +625 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/emissions_tracker.py +7 -4
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/external/hardware.py +13 -3
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/external/ram.py +1 -3
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon.egg-info/PKG-INFO +46 -16
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon.egg-info/SOURCES.txt +2 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/pyproject.toml +2 -2
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_api_call.py +203 -16
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_config.py +14 -28
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_core_util.py +22 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_cpu_load.py +2 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_electricitymaps_config_backward_compatibility.py +4 -8
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_hardware_cache.py +18 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_logger.py +1 -1
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_ram.py +21 -12
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_resource_tracker.py +53 -2
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_tracking_inference.py +4 -1
- codecarbon-3.3.0/tests/test_windows_emi.py +672 -0
- codecarbon-3.2.9/codecarbon/_version.py +0 -1
- {codecarbon-3.2.9 → codecarbon-3.3.0}/LICENSE +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/__init__.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/cli/__init__.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/cli/auth.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/cli/cli_utils.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/cli/monitor.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/__init__.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/cloud.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/config.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/cpu.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/electricitymaps_api.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/emissions.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/gpu.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/gpu_amd.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/gpu_device.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/gpu_nvidia.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/measure.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/rapl.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/schemas.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/telemetry_client.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/telemetry_schemas.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/core/units.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/canada_provinces.geojson +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/cloud/impact.csv +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/hardware/cpu_dataset_builder/amd_cpu_scrapper.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/hardware/cpu_dataset_builder/intel_cpu_scrapper.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/hardware/cpu_dataset_builder/merge_scrapped_cpu_power.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/hardware/cpu_power.csv +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/private_infra/2016/usa_emissions.json +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/private_infra/2023/canada_energy_mix.json +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/private_infra/carbon_intensity_per_source.json +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/private_infra/global_energy_mix.json +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/data/private_infra/nordic_emissions.json +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/external/__init__.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/external/geography.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/external/logger.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/external/scheduler.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/external/task.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/input.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/lock.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/__init__.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/base_output.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/boamps/__init__.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/boamps/mapper.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/boamps/models.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/boamps/output.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/emissions_data.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/file.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/http.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/logger.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/metrics/__init__.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/metrics/logfire.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/metrics/metric_docs.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/output_methods/metrics/prometheus.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/py.typed +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/viz/__init__.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/viz/assets/__init__.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/viz/assets/car_icon.png +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/viz/assets/house_icon.png +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/viz/assets/tv_icon.png +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/viz/carbonboard.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/viz/carbonboard_on_api.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/viz/components.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/viz/data.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon/viz/units.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon.egg-info/dependency_links.txt +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon.egg-info/entry_points.txt +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon.egg-info/requires.txt +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/codecarbon.egg-info/top_level.txt +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/setup.cfg +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_boamps_output.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_cloud.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_cpu.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_custom_handler.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_docs_examples.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_electricitymaps_api.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_electricitymaps_backward_compatibility.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_emissions.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_emissions_tracker.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_emissions_tracker_constant.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_emissions_tracker_flush.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_energy.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_geography.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_gpu.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_gpu_amd.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_gpu_nvidia.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_input.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_lock.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_logging_output.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_offline_emissions_tracker.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_package_integrity.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_powermetrics.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_rapl_mmio_scanning.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_rapl_parameters.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_rapl_permissions.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_telemetry_client.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_unsupported_gpu.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_utilization_tracking.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_viz_data.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/test_viz_units.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/testdata.py +0 -0
- {codecarbon-3.2.9 → codecarbon-3.3.0}/tests/testutils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codecarbon
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.0
|
|
4
4
|
Author: Mila, DataForGood, BCG GAMMA, Comet.ml, Haverford College
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Homepage, https://codecarbon.io/
|
|
@@ -137,18 +137,19 @@ You can visualize your experiment emissions on the [dashboard](https://dashboard
|
|
|
137
137
|
|
|
138
138
|
## Quick links
|
|
139
139
|
|
|
140
|
-
| Section
|
|
141
|
-
|
|
142
|
-
| [Quickstart](https://docs.codecarbon.io/latest/tutorials/first-tracking/)
|
|
143
|
-
| [Installation](https://docs.codecarbon.io/latest/how-to/installation/)
|
|
144
|
-
| [CLI Tutorial](https://docs.codecarbon.io/latest/tutorials/cli/)
|
|
145
|
-
| [Python API Tutorial](https://docs.codecarbon.io/latest/tutorials/python-api/)
|
|
140
|
+
| Section | Description |
|
|
141
|
+
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------ |
|
|
142
|
+
| [Quickstart](https://docs.codecarbon.io/latest/tutorials/first-tracking/) | Get started in 5 minutes |
|
|
143
|
+
| [Installation](https://docs.codecarbon.io/latest/how-to/installation/) | Install CodeCarbon |
|
|
144
|
+
| [CLI Tutorial](https://docs.codecarbon.io/latest/tutorials/cli/) | Track emissions from the command line |
|
|
145
|
+
| [Python API Tutorial](https://docs.codecarbon.io/latest/tutorials/python-api/) | Track emissions in Python code |
|
|
146
146
|
| [Comparing Model Efficiency](https://docs.codecarbon.io/latest/tutorials/comparing-model-efficiency/) | Measure carbon efficiency across ML models |
|
|
147
|
-
| [API Reference](https://docs.codecarbon.io/latest/reference/api/)
|
|
148
|
-
| [Framework examples (scikit-learn)](https://docs.codecarbon.io/latest/how-to/scikit-learn/)
|
|
149
|
-
| [Methodology](https://docs.codecarbon.io/latest/explanation/methodology/)
|
|
150
|
-
| [EcoLogits](https://
|
|
151
|
-
| [
|
|
147
|
+
| [API Reference](https://docs.codecarbon.io/latest/reference/api/) | Full parameter documentation |
|
|
148
|
+
| [Framework examples (scikit-learn)](https://docs.codecarbon.io/latest/how-to/scikit-learn/) | Task-oriented ML framework examples |
|
|
149
|
+
| [Methodology](https://docs.codecarbon.io/latest/explanation/methodology/) | How emissions are calculated |
|
|
150
|
+
| [When to use CodeCarbon vs EcoLogits](https://docs.codecarbon.io/latest/explanation/when-to-use/) | Choose the right tool |
|
|
151
|
+
| [EcoLogits](https://ecologits.ai/) | Track emissions from GenAI API calls |
|
|
152
|
+
| [Discord Community](https://discord.gg/GS9js2XkJR) | Chat with us and the community |
|
|
152
153
|
|
|
153
154
|
## Links
|
|
154
155
|
|
|
@@ -156,6 +157,7 @@ You can visualize your experiment emissions on the [dashboard](https://dashboard
|
|
|
156
157
|
- [Dashboard](https://dashboard.codecarbon.io/) to see your emissions.
|
|
157
158
|
- [Documentation](https://docs.codecarbon.io/) to learn how to use the package and our methodology.
|
|
158
159
|
- [EcoLogits](https://ecologits.ai/) to track emissions from GenAI API calls (OpenAI, Anthropic, etc.).
|
|
160
|
+
- [mlco2 on GitHub](https://github.com/mlco2) for our other open-source projects.
|
|
159
161
|
- [GitHub](https://github.com/mlco2/codecarbon) to look at the source code and contribute.
|
|
160
162
|
- [Discord](https://discord.gg/GS9js2XkJR) to chat with us.
|
|
161
163
|
|
|
@@ -210,7 +212,7 @@ If you find CodeCarbon useful for your research, you can find a citation under a
|
|
|
210
212
|
MinervaBooks},
|
|
211
213
|
title = {mlco2/codecarbon: v2.4.1},
|
|
212
214
|
month = may,
|
|
213
|
-
year = 2024,
|
|
215
|
+
year = {2024},
|
|
214
216
|
publisher = {Zenodo},
|
|
215
217
|
version = {v2.4.1},
|
|
216
218
|
doi = {10.5281/zenodo.11171501},
|
|
@@ -228,6 +230,34 @@ Codecarbon was formerly developed by volunteers from [**Mila**](http://mila.queb
|
|
|
228
230
|
|
|
229
231
|
Now CodeCarbon is supported by [**Code Carbon**](https://www.helloasso.com/associations/code-carbon), a French non-profit organization whose mission is to accelerate the development and adoption of CodeCarbon.
|
|
230
232
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
233
|
+
## Sponsors
|
|
234
|
+
|
|
235
|
+
<div align="center">
|
|
236
|
+
<a href="https://www.clever-cloud.com/">
|
|
237
|
+
<picture>
|
|
238
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mlco2/codecarbon-landing-page/main/public/assets/partners/clever_cloud.png">
|
|
239
|
+
<img src="https://cdn.clever-cloud.com/uploads/2023/03/logoonwhite.svg" alt="Clever Cloud" height="48">
|
|
240
|
+
</picture>
|
|
241
|
+
</a>
|
|
242
|
+
|
|
243
|
+
<a href="https://dataforgood.fr/">
|
|
244
|
+
<picture>
|
|
245
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mlco2/codecarbon-landing-page/main/public/assets/partners/dataforgood.png">
|
|
246
|
+
<img src="https://dataforgood.fr/images/dataforgood.svg" alt="Data For Good" height="48">
|
|
247
|
+
</picture>
|
|
248
|
+
</a>
|
|
249
|
+
|
|
250
|
+
<a href="https://github.com/">
|
|
251
|
+
<picture>
|
|
252
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mlco2/codecarbon-landing-page/main/public/assets/partners/GitHub.png">
|
|
253
|
+
<img src="https://github.githubassets.com/images/modules/logos_page/GitHub-Logo.png" alt="GitHub" height="48">
|
|
254
|
+
</picture>
|
|
255
|
+
</a>
|
|
256
|
+
|
|
257
|
+
<a href="https://www.mozilla.org/">
|
|
258
|
+
<picture>
|
|
259
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mlco2/codecarbon-landing-page/main/public/assets/partners/mozilla.svg">
|
|
260
|
+
<img src="https://upload.wikimedia.org/wikipedia/commons/d/df/Mozilla_2024_logo.svg" alt="Mozilla" height="48">
|
|
261
|
+
</picture>
|
|
262
|
+
</a>
|
|
263
|
+
</div>
|
|
@@ -90,18 +90,19 @@ You can visualize your experiment emissions on the [dashboard](https://dashboard
|
|
|
90
90
|
|
|
91
91
|
## Quick links
|
|
92
92
|
|
|
93
|
-
| Section
|
|
94
|
-
|
|
95
|
-
| [Quickstart](https://docs.codecarbon.io/latest/tutorials/first-tracking/)
|
|
96
|
-
| [Installation](https://docs.codecarbon.io/latest/how-to/installation/)
|
|
97
|
-
| [CLI Tutorial](https://docs.codecarbon.io/latest/tutorials/cli/)
|
|
98
|
-
| [Python API Tutorial](https://docs.codecarbon.io/latest/tutorials/python-api/)
|
|
93
|
+
| Section | Description |
|
|
94
|
+
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------ |
|
|
95
|
+
| [Quickstart](https://docs.codecarbon.io/latest/tutorials/first-tracking/) | Get started in 5 minutes |
|
|
96
|
+
| [Installation](https://docs.codecarbon.io/latest/how-to/installation/) | Install CodeCarbon |
|
|
97
|
+
| [CLI Tutorial](https://docs.codecarbon.io/latest/tutorials/cli/) | Track emissions from the command line |
|
|
98
|
+
| [Python API Tutorial](https://docs.codecarbon.io/latest/tutorials/python-api/) | Track emissions in Python code |
|
|
99
99
|
| [Comparing Model Efficiency](https://docs.codecarbon.io/latest/tutorials/comparing-model-efficiency/) | Measure carbon efficiency across ML models |
|
|
100
|
-
| [API Reference](https://docs.codecarbon.io/latest/reference/api/)
|
|
101
|
-
| [Framework examples (scikit-learn)](https://docs.codecarbon.io/latest/how-to/scikit-learn/)
|
|
102
|
-
| [Methodology](https://docs.codecarbon.io/latest/explanation/methodology/)
|
|
103
|
-
| [EcoLogits](https://
|
|
104
|
-
| [
|
|
100
|
+
| [API Reference](https://docs.codecarbon.io/latest/reference/api/) | Full parameter documentation |
|
|
101
|
+
| [Framework examples (scikit-learn)](https://docs.codecarbon.io/latest/how-to/scikit-learn/) | Task-oriented ML framework examples |
|
|
102
|
+
| [Methodology](https://docs.codecarbon.io/latest/explanation/methodology/) | How emissions are calculated |
|
|
103
|
+
| [When to use CodeCarbon vs EcoLogits](https://docs.codecarbon.io/latest/explanation/when-to-use/) | Choose the right tool |
|
|
104
|
+
| [EcoLogits](https://ecologits.ai/) | Track emissions from GenAI API calls |
|
|
105
|
+
| [Discord Community](https://discord.gg/GS9js2XkJR) | Chat with us and the community |
|
|
105
106
|
|
|
106
107
|
## Links
|
|
107
108
|
|
|
@@ -109,6 +110,7 @@ You can visualize your experiment emissions on the [dashboard](https://dashboard
|
|
|
109
110
|
- [Dashboard](https://dashboard.codecarbon.io/) to see your emissions.
|
|
110
111
|
- [Documentation](https://docs.codecarbon.io/) to learn how to use the package and our methodology.
|
|
111
112
|
- [EcoLogits](https://ecologits.ai/) to track emissions from GenAI API calls (OpenAI, Anthropic, etc.).
|
|
113
|
+
- [mlco2 on GitHub](https://github.com/mlco2) for our other open-source projects.
|
|
112
114
|
- [GitHub](https://github.com/mlco2/codecarbon) to look at the source code and contribute.
|
|
113
115
|
- [Discord](https://discord.gg/GS9js2XkJR) to chat with us.
|
|
114
116
|
|
|
@@ -163,7 +165,7 @@ If you find CodeCarbon useful for your research, you can find a citation under a
|
|
|
163
165
|
MinervaBooks},
|
|
164
166
|
title = {mlco2/codecarbon: v2.4.1},
|
|
165
167
|
month = may,
|
|
166
|
-
year = 2024,
|
|
168
|
+
year = {2024},
|
|
167
169
|
publisher = {Zenodo},
|
|
168
170
|
version = {v2.4.1},
|
|
169
171
|
doi = {10.5281/zenodo.11171501},
|
|
@@ -181,6 +183,34 @@ Codecarbon was formerly developed by volunteers from [**Mila**](http://mila.queb
|
|
|
181
183
|
|
|
182
184
|
Now CodeCarbon is supported by [**Code Carbon**](https://www.helloasso.com/associations/code-carbon), a French non-profit organization whose mission is to accelerate the development and adoption of CodeCarbon.
|
|
183
185
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
186
|
+
## Sponsors
|
|
187
|
+
|
|
188
|
+
<div align="center">
|
|
189
|
+
<a href="https://www.clever-cloud.com/">
|
|
190
|
+
<picture>
|
|
191
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mlco2/codecarbon-landing-page/main/public/assets/partners/clever_cloud.png">
|
|
192
|
+
<img src="https://cdn.clever-cloud.com/uploads/2023/03/logoonwhite.svg" alt="Clever Cloud" height="48">
|
|
193
|
+
</picture>
|
|
194
|
+
</a>
|
|
195
|
+
|
|
196
|
+
<a href="https://dataforgood.fr/">
|
|
197
|
+
<picture>
|
|
198
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mlco2/codecarbon-landing-page/main/public/assets/partners/dataforgood.png">
|
|
199
|
+
<img src="https://dataforgood.fr/images/dataforgood.svg" alt="Data For Good" height="48">
|
|
200
|
+
</picture>
|
|
201
|
+
</a>
|
|
202
|
+
|
|
203
|
+
<a href="https://github.com/">
|
|
204
|
+
<picture>
|
|
205
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mlco2/codecarbon-landing-page/main/public/assets/partners/GitHub.png">
|
|
206
|
+
<img src="https://github.githubassets.com/images/modules/logos_page/GitHub-Logo.png" alt="GitHub" height="48">
|
|
207
|
+
</picture>
|
|
208
|
+
</a>
|
|
209
|
+
|
|
210
|
+
<a href="https://www.mozilla.org/">
|
|
211
|
+
<picture>
|
|
212
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mlco2/codecarbon-landing-page/main/public/assets/partners/mozilla.svg">
|
|
213
|
+
<img src="https://upload.wikimedia.org/wikipedia/commons/d/df/Mozilla_2024_logo.svg" alt="Mozilla" height="48">
|
|
214
|
+
</picture>
|
|
215
|
+
</a>
|
|
216
|
+
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "3.3.0"
|
|
@@ -40,6 +40,20 @@ def main():
|
|
|
40
40
|
raise sys.exit(1)
|
|
41
41
|
|
|
42
42
|
|
|
43
|
+
def _api_call(action: str, func, *args, **kwargs):
|
|
44
|
+
"""
|
|
45
|
+
Run a call to the Code Carbon API, turning the errors it now raises into a
|
|
46
|
+
readable message and a clean exit instead of a traceback.
|
|
47
|
+
|
|
48
|
+
:action: what was being attempted, used as the first part of the message.
|
|
49
|
+
"""
|
|
50
|
+
try:
|
|
51
|
+
return func(*args, **kwargs)
|
|
52
|
+
except Exception as e:
|
|
53
|
+
print(f"[yellow]{action}[/yellow]. (error: {e})")
|
|
54
|
+
raise typer.Exit(1)
|
|
55
|
+
|
|
56
|
+
|
|
43
57
|
def _version_callback(value: bool) -> None:
|
|
44
58
|
if value:
|
|
45
59
|
print(f"{__app_name__} v{__version__}")
|
|
@@ -116,7 +130,7 @@ def api_get():
|
|
|
116
130
|
api_endpoint = get_api_endpoint()
|
|
117
131
|
api = ApiClient(endpoint_url=api_endpoint)
|
|
118
132
|
api.set_access_token(get_access_token())
|
|
119
|
-
organizations = api.get_list_organizations
|
|
133
|
+
organizations = _api_call("API request failed", api.get_list_organizations)
|
|
120
134
|
print(organizations)
|
|
121
135
|
|
|
122
136
|
|
|
@@ -130,7 +144,7 @@ def login():
|
|
|
130
144
|
api = ApiClient(endpoint_url=api_endpoint)
|
|
131
145
|
access_token = get_access_token()
|
|
132
146
|
api.set_access_token(access_token)
|
|
133
|
-
api.check_auth
|
|
147
|
+
_api_call("Authentication check failed", api.check_auth)
|
|
134
148
|
|
|
135
149
|
|
|
136
150
|
def get_api_key(project_id: str):
|
|
@@ -149,6 +163,7 @@ def get_api_key(project_id: str):
|
|
|
149
163
|
},
|
|
150
164
|
headers={"Authorization": f"Bearer {get_access_token()}"},
|
|
151
165
|
)
|
|
166
|
+
req.raise_for_status()
|
|
152
167
|
api_key = req.json()["token"]
|
|
153
168
|
return api_key
|
|
154
169
|
|
|
@@ -212,7 +227,10 @@ def config():
|
|
|
212
227
|
overwrite_local_config("api_endpoint", api_endpoint, path=file_path)
|
|
213
228
|
api = ApiClient(endpoint_url=api_endpoint)
|
|
214
229
|
api.set_access_token(get_access_token())
|
|
215
|
-
organizations =
|
|
230
|
+
organizations = _api_call(
|
|
231
|
+
"Could not list organizations from API. Please check your login and API endpoint",
|
|
232
|
+
api.get_list_organizations,
|
|
233
|
+
)
|
|
216
234
|
org = questionary_prompt(
|
|
217
235
|
"Pick existing organization from list or Create new organization ?",
|
|
218
236
|
[org["name"] for org in organizations] + ["Create New Organization"],
|
|
@@ -229,18 +247,23 @@ def config():
|
|
|
229
247
|
name=org_name,
|
|
230
248
|
description=org_description,
|
|
231
249
|
)
|
|
232
|
-
organization =
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
250
|
+
organization = _api_call(
|
|
251
|
+
"Could not create the organization",
|
|
252
|
+
api.create_organization,
|
|
253
|
+
organization=organization_create,
|
|
254
|
+
)
|
|
236
255
|
print(f"Created organization : {organization}")
|
|
237
256
|
else:
|
|
238
257
|
organization = [orga for orga in organizations if orga["name"] == org][0]
|
|
239
258
|
org_id = organization["id"]
|
|
240
259
|
overwrite_local_config("organization_id", org_id, path=file_path)
|
|
241
260
|
|
|
242
|
-
projects =
|
|
243
|
-
|
|
261
|
+
projects = _api_call(
|
|
262
|
+
"Could not list projects from API",
|
|
263
|
+
api.list_projects_from_organization,
|
|
264
|
+
org_id,
|
|
265
|
+
)
|
|
266
|
+
project_names = [project["name"] for project in projects]
|
|
244
267
|
project = questionary_prompt(
|
|
245
268
|
"Pick existing project from list or Create new project ?",
|
|
246
269
|
project_names + ["Create New Project"],
|
|
@@ -256,17 +279,21 @@ def config():
|
|
|
256
279
|
description=project_description,
|
|
257
280
|
organization_id=org_id,
|
|
258
281
|
)
|
|
259
|
-
project =
|
|
282
|
+
project = _api_call(
|
|
283
|
+
"Could not create the project", api.create_project, project=project_create
|
|
284
|
+
)
|
|
260
285
|
print(f"Created project : {project}")
|
|
261
286
|
else:
|
|
262
287
|
project = [p for p in projects if p["name"] == project][0]
|
|
263
288
|
project_id = project["id"]
|
|
264
289
|
overwrite_local_config("project_id", project_id, path=file_path)
|
|
265
290
|
|
|
266
|
-
experiments =
|
|
267
|
-
|
|
268
|
-
|
|
291
|
+
experiments = _api_call(
|
|
292
|
+
"Could not list experiments from API",
|
|
293
|
+
api.list_experiments_from_project,
|
|
294
|
+
project_id,
|
|
269
295
|
)
|
|
296
|
+
experiments_names = [experiment["name"] for experiment in experiments]
|
|
270
297
|
|
|
271
298
|
experiment = questionary_prompt(
|
|
272
299
|
"Pick existing experiment from list or Create new experiment ?",
|
|
@@ -313,13 +340,17 @@ def config():
|
|
|
313
340
|
cloud_provider=cloud_provider,
|
|
314
341
|
cloud_region=cloud_region,
|
|
315
342
|
)
|
|
316
|
-
experiment =
|
|
343
|
+
experiment = _api_call(
|
|
344
|
+
"Could not create the experiment",
|
|
345
|
+
api.add_experiment,
|
|
346
|
+
experiment=experiment_create,
|
|
347
|
+
)
|
|
317
348
|
|
|
318
349
|
else:
|
|
319
350
|
experiment = [e for e in experiments if e["name"] == experiment][0]
|
|
320
351
|
|
|
321
352
|
overwrite_local_config("experiment_id", experiment["id"], path=file_path)
|
|
322
|
-
api_key = get_api_key
|
|
353
|
+
api_key = _api_call("Could not get the project API key", get_api_key, project_id)
|
|
323
354
|
overwrite_local_config("api_key", api_key, path=file_path)
|
|
324
355
|
show_config(file_path)
|
|
325
356
|
print(
|
|
@@ -70,6 +70,21 @@ class ApiClient: # (AsyncClient)
|
|
|
70
70
|
headers["Authorization"] = f"Bearer {self.access_token}"
|
|
71
71
|
return headers
|
|
72
72
|
|
|
73
|
+
def _request(self, method, url, payload=None, expected_status=200):
|
|
74
|
+
"""
|
|
75
|
+
Call the API and return the response, raising on anything that is not
|
|
76
|
+
the status code the API answers on success.
|
|
77
|
+
|
|
78
|
+
:method: the requests function to call, for example requests.get
|
|
79
|
+
:payload: the JSON body to send, if any
|
|
80
|
+
:expected_status: the http code the API returns when the call succeeds
|
|
81
|
+
"""
|
|
82
|
+
headers = self._get_headers()
|
|
83
|
+
response = method(url=url, json=payload, timeout=2, headers=headers)
|
|
84
|
+
if response.status_code != expected_status:
|
|
85
|
+
self._raise_api_error(url, payload or {}, response)
|
|
86
|
+
return response
|
|
87
|
+
|
|
73
88
|
def set_access_token(self, token: str):
|
|
74
89
|
"""This method sets the access token to be used for the API.
|
|
75
90
|
Args:
|
|
@@ -82,32 +97,20 @@ class ApiClient: # (AsyncClient)
|
|
|
82
97
|
Check API access to user account
|
|
83
98
|
"""
|
|
84
99
|
url = self.url + "/auth/check"
|
|
85
|
-
|
|
86
|
-
r = requests.get(url=url, timeout=2, headers=headers)
|
|
87
|
-
if r.status_code != 200:
|
|
88
|
-
self._log_error(url, {}, r)
|
|
89
|
-
return None
|
|
90
|
-
return r.json()
|
|
100
|
+
return self._request(requests.get, url).json()
|
|
91
101
|
|
|
92
102
|
def get_list_organizations(self):
|
|
93
103
|
"""
|
|
94
104
|
List all organizations
|
|
95
105
|
"""
|
|
96
106
|
url = self.url + "/organizations"
|
|
97
|
-
|
|
98
|
-
r = requests.get(url=url, timeout=2, headers=headers)
|
|
99
|
-
if r.status_code != 200:
|
|
100
|
-
self._log_error(url, {}, r)
|
|
101
|
-
return None
|
|
102
|
-
return r.json()
|
|
107
|
+
return self._request(requests.get, url).json()
|
|
103
108
|
|
|
104
109
|
def check_organization_exists(self, organization_name: str):
|
|
105
110
|
"""
|
|
106
111
|
Check if an organization exists
|
|
107
112
|
"""
|
|
108
113
|
organizations = self.get_list_organizations()
|
|
109
|
-
if organizations is None:
|
|
110
|
-
return False
|
|
111
114
|
for organization in organizations:
|
|
112
115
|
if organization["name"] == organization_name:
|
|
113
116
|
return organization
|
|
@@ -125,49 +128,31 @@ class ApiClient: # (AsyncClient)
|
|
|
125
128
|
)
|
|
126
129
|
return organization
|
|
127
130
|
else:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
self._log_error(url, payload, r)
|
|
132
|
-
return None
|
|
133
|
-
return r.json()
|
|
131
|
+
return self._request(
|
|
132
|
+
requests.post, url, payload=payload, expected_status=201
|
|
133
|
+
).json()
|
|
134
134
|
|
|
135
135
|
def get_organization(self, organization_id):
|
|
136
136
|
"""
|
|
137
137
|
Get an organization
|
|
138
138
|
"""
|
|
139
|
-
headers = self._get_headers()
|
|
140
139
|
url = self.url + "/organizations/" + organization_id
|
|
141
|
-
|
|
142
|
-
if r.status_code != 200:
|
|
143
|
-
self._log_error(url, {}, r)
|
|
144
|
-
return None
|
|
145
|
-
return r.json()
|
|
140
|
+
return self._request(requests.get, url).json()
|
|
146
141
|
|
|
147
142
|
def update_organization(self, organization: OrganizationCreate):
|
|
148
143
|
"""
|
|
149
144
|
Update an organization
|
|
150
145
|
"""
|
|
151
146
|
payload = dataclasses.asdict(organization)
|
|
152
|
-
headers = self._get_headers()
|
|
153
147
|
url = self.url + "/organizations/" + organization.id
|
|
154
|
-
|
|
155
|
-
if r.status_code != 200:
|
|
156
|
-
self._log_error(url, payload, r)
|
|
157
|
-
return None
|
|
158
|
-
return r.json()
|
|
148
|
+
return self._request(requests.patch, url, payload=payload).json()
|
|
159
149
|
|
|
160
150
|
def list_projects_from_organization(self, organization_id):
|
|
161
151
|
"""
|
|
162
152
|
List all projects
|
|
163
153
|
"""
|
|
164
154
|
url = self.url + "/organizations/" + organization_id + "/projects"
|
|
165
|
-
|
|
166
|
-
r = requests.get(url=url, timeout=2, headers=headers)
|
|
167
|
-
if r.status_code != 200:
|
|
168
|
-
self._log_error(url, {}, r)
|
|
169
|
-
return None
|
|
170
|
-
return r.json()
|
|
155
|
+
return self._request(requests.get, url).json()
|
|
171
156
|
|
|
172
157
|
def create_project(self, project: ProjectCreate):
|
|
173
158
|
"""
|
|
@@ -175,24 +160,16 @@ class ApiClient: # (AsyncClient)
|
|
|
175
160
|
"""
|
|
176
161
|
payload = dataclasses.asdict(project)
|
|
177
162
|
url = self.url + "/projects"
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
self._log_error(url, payload, r)
|
|
182
|
-
return None
|
|
183
|
-
return r.json()
|
|
163
|
+
return self._request(
|
|
164
|
+
requests.post, url, payload=payload, expected_status=201
|
|
165
|
+
).json()
|
|
184
166
|
|
|
185
167
|
def get_project(self, project_id):
|
|
186
168
|
"""
|
|
187
169
|
Get a project
|
|
188
170
|
"""
|
|
189
171
|
url = self.url + "/projects/" + project_id
|
|
190
|
-
|
|
191
|
-
r = requests.get(url=url, timeout=2, headers=headers)
|
|
192
|
-
if r.status_code != 200:
|
|
193
|
-
self._log_error(url, {}, r)
|
|
194
|
-
return None
|
|
195
|
-
return r.json()
|
|
172
|
+
return self._request(requests.get, url).json()
|
|
196
173
|
|
|
197
174
|
def add_emission(self, carbon_emission: dict):
|
|
198
175
|
assert self.experiment_id is not None
|
|
@@ -233,15 +210,14 @@ class ApiClient: # (AsyncClient)
|
|
|
233
210
|
try:
|
|
234
211
|
payload = dataclasses.asdict(emission)
|
|
235
212
|
url = self.url + "/emissions"
|
|
236
|
-
|
|
237
|
-
r = requests.post(url=url, json=payload, timeout=2, headers=headers)
|
|
238
|
-
if r.status_code != 201:
|
|
239
|
-
self._log_error(url, payload, r)
|
|
240
|
-
return False
|
|
213
|
+
self._request(requests.post, url, payload=payload, expected_status=201)
|
|
241
214
|
logger.debug(f"ApiClient - Successful upload emission {payload} to {url}")
|
|
215
|
+
except requests.exceptions.HTTPError:
|
|
216
|
+
# Already logged by _raise_api_error, do not log it twice.
|
|
217
|
+
raise
|
|
242
218
|
except Exception as e:
|
|
243
219
|
logger.error(e, exc_info=True)
|
|
244
|
-
|
|
220
|
+
raise
|
|
245
221
|
return True
|
|
246
222
|
|
|
247
223
|
def _create_run(self, experiment_id: str):
|
|
@@ -275,11 +251,7 @@ class ApiClient: # (AsyncClient)
|
|
|
275
251
|
)
|
|
276
252
|
payload = dataclasses.asdict(run)
|
|
277
253
|
url = self.url + "/runs"
|
|
278
|
-
|
|
279
|
-
r = requests.post(url=url, json=payload, timeout=2, headers=headers)
|
|
280
|
-
if r.status_code != 201:
|
|
281
|
-
self._log_error(url, payload, r)
|
|
282
|
-
return None
|
|
254
|
+
r = self._request(requests.post, url, payload=payload, expected_status=201)
|
|
283
255
|
self.run_id = r.json()["id"]
|
|
284
256
|
logger.info(
|
|
285
257
|
"ApiClient Successfully registered your run on the API.\n\n"
|
|
@@ -292,20 +264,20 @@ class ApiClient: # (AsyncClient)
|
|
|
292
264
|
f"Failed to connect to API, please check the configuration. {e}",
|
|
293
265
|
exc_info=False,
|
|
294
266
|
)
|
|
267
|
+
raise
|
|
268
|
+
except requests.exceptions.HTTPError:
|
|
269
|
+
# Already logged by _raise_api_error, do not log it twice.
|
|
270
|
+
raise
|
|
295
271
|
except Exception as e:
|
|
296
272
|
logger.error(e, exc_info=True)
|
|
273
|
+
raise
|
|
297
274
|
|
|
298
275
|
def list_experiments_from_project(self, project_id: str):
|
|
299
276
|
"""
|
|
300
277
|
List all experiments for a project
|
|
301
278
|
"""
|
|
302
279
|
url = self.url + "/projects/" + project_id + "/experiments"
|
|
303
|
-
|
|
304
|
-
r = requests.get(url=url, timeout=2, headers=headers)
|
|
305
|
-
if r.status_code != 200:
|
|
306
|
-
self._log_error(url, {}, r)
|
|
307
|
-
return []
|
|
308
|
-
return r.json()
|
|
280
|
+
return self._request(requests.get, url).json()
|
|
309
281
|
|
|
310
282
|
def set_experiment(self, experiment_id: str):
|
|
311
283
|
"""
|
|
@@ -320,26 +292,21 @@ class ApiClient: # (AsyncClient)
|
|
|
320
292
|
"""
|
|
321
293
|
payload = dataclasses.asdict(experiment)
|
|
322
294
|
url = self.url + "/experiments"
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
self._log_error(url, payload, r)
|
|
327
|
-
return None
|
|
328
|
-
return r.json()
|
|
295
|
+
return self._request(
|
|
296
|
+
requests.post, url, payload=payload, expected_status=201
|
|
297
|
+
).json()
|
|
329
298
|
|
|
330
299
|
def get_experiment(self, experiment_id):
|
|
331
300
|
"""
|
|
332
301
|
Get an experiment by id
|
|
333
302
|
"""
|
|
334
303
|
url = self.url + "/experiments/" + experiment_id
|
|
335
|
-
|
|
336
|
-
r = requests.get(url=url, timeout=2, headers=headers)
|
|
337
|
-
if r.status_code != 200:
|
|
338
|
-
self._log_error(url, {}, r)
|
|
339
|
-
return None
|
|
340
|
-
return r.json()
|
|
304
|
+
return self._request(requests.get, url).json()
|
|
341
305
|
|
|
342
|
-
def
|
|
306
|
+
def _raise_api_error(self, url, payload, response):
|
|
307
|
+
"""
|
|
308
|
+
Log the failed call then always raise a requests.exceptions.HTTPError.
|
|
309
|
+
"""
|
|
343
310
|
if len(payload) > 0:
|
|
344
311
|
logger.error(
|
|
345
312
|
f"ApiClient Error when calling the API on {url} with : {json.dumps(payload)}"
|
|
@@ -349,6 +316,11 @@ class ApiClient: # (AsyncClient)
|
|
|
349
316
|
logger.error(
|
|
350
317
|
f"ApiClient API return http code {response.status_code} and answer : {response.text}"
|
|
351
318
|
)
|
|
319
|
+
response.raise_for_status()
|
|
320
|
+
# 2xx/3xx that still isn't what the caller expected
|
|
321
|
+
raise requests.exceptions.HTTPError(
|
|
322
|
+
f"Unexpected status {response.status_code} from {url}", response=response
|
|
323
|
+
)
|
|
352
324
|
|
|
353
325
|
def close_experiment(self):
|
|
354
326
|
"""
|
|
@@ -134,6 +134,10 @@ def _spec_from_hardware(hw) -> Dict[str, Any]:
|
|
|
134
134
|
spec["rapl_include_dram"] = getattr(intel, "rapl_include_dram", False)
|
|
135
135
|
spec["rapl_prefer_psys"] = getattr(intel, "rapl_prefer_psys", False)
|
|
136
136
|
spec["rapl_dir"] = getattr(intel, "_lin_rapl_dir", DEFAULT_RAPL_DIR)
|
|
137
|
+
elif hw._mode == "windows_emi" and hasattr(hw, "_intel_interface"):
|
|
138
|
+
spec["rapl_include_dram"] = getattr(
|
|
139
|
+
hw._intel_interface, "emi_include_dram", False
|
|
140
|
+
)
|
|
137
141
|
return spec
|
|
138
142
|
if kind == HardwareKind.APPLE_CHIP:
|
|
139
143
|
return {
|
|
@@ -238,6 +242,7 @@ def clear_cache() -> None:
|
|
|
238
242
|
("codecarbon.core.gpu_amd", "clear_rocm_system_cache"),
|
|
239
243
|
("codecarbon.core.cpu", "clear_powergadget_cache"),
|
|
240
244
|
("codecarbon.core.powermetrics", "clear_powermetrics_cache"),
|
|
245
|
+
("codecarbon.core.windows_emi", "clear_emi_cache"),
|
|
241
246
|
):
|
|
242
247
|
mod = sys.modules.get(mod_name)
|
|
243
248
|
if mod is not None:
|
|
@@ -67,13 +67,11 @@ def _has_powermetrics_sudo() -> bool:
|
|
|
67
67
|
_, stderr = process.communicate()
|
|
68
68
|
|
|
69
69
|
if re.search(r"[sudo].*password", stderr):
|
|
70
|
-
logger.debug(
|
|
71
|
-
"""Not using PowerMetrics, sudo password prompt detected.
|
|
70
|
+
logger.debug("""Not using PowerMetrics, sudo password prompt detected.
|
|
72
71
|
If you want to enable Powermetrics please modify your sudoers file
|
|
73
72
|
as described in :
|
|
74
73
|
https://docs.codecarbon.io/latest/explanation/methodology/#power-usage
|
|
75
|
-
"""
|
|
76
|
-
)
|
|
74
|
+
""")
|
|
77
75
|
return False
|
|
78
76
|
if process.returncode != 0:
|
|
79
77
|
raise Exception("Return code != 0")
|