Skip to content

Commit bfc5656

Browse files
authored
Adding codecarbon detect CLI and the ability to report on hardware without running measurements. (#1031)
* Add `detect` command to CLI to report system hardware without starting a tracker. * Create `EmissionsTracker.get_detected_hardware()` to return basic hardware information. * Update internal logging to use `get_detected_hardware()`. * Create `examples/print_hardware.py` and unit tests. * Add documentation for the `detect` command in README and usage guide.
1 parent 4d96624 commit bfc5656

14 files changed

Lines changed: 150 additions & 52 deletions

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ In your command prompt use:
107107
```codecarbon monitor```
108108
The package will track your emissions independently from your code.
109109

110+
### Detecting your hardware 🔍
111+
112+
In your command prompt use:
113+
```codecarbon detect```
114+
The package will detect and print your hardware information (RAM, CPU, GPU).
115+
110116
### In your Python code 🐍
111117
```python
112118
from codecarbon import track_emissions

codecarbon/cli/main.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,31 @@ def signal_handler(signum, frame):
413413
raise e
414414

415415

416+
@codecarbon.command("detect", short_help="Detect hardware and print information.")
417+
def detect():
418+
"""
419+
Detects hardware and prints information without running any measurements.
420+
"""
421+
print("Detecting hardware...")
422+
tracker = EmissionsTracker(save_to_file=False)
423+
hardware_info = tracker.get_detected_hardware()
424+
425+
print("\nDetected Hardware and System Information:")
426+
print(f"- Available RAM: {hardware_info['ram_total_size']:.3f} GB")
427+
print(
428+
f"- CPU count: {hardware_info['cpu_count']} thread(s) in {hardware_info['cpu_physical_count']} physical CPU(s)"
429+
)
430+
print(f"- CPU model: {hardware_info['cpu_model']}")
431+
print(f"- GPU count: {hardware_info['gpu_count']}")
432+
433+
gpu_model_str = hardware_info["gpu_model"]
434+
if hardware_info.get("gpu_ids"):
435+
gpu_model_str += (
436+
f" BUT only tracking these GPU ids : {hardware_info['gpu_ids']}"
437+
)
438+
print(f"- GPU model: {gpu_model_str}")
439+
440+
416441
def questionary_prompt(prompt, list_options, default):
417442
value = questionary.select(
418443
prompt,

codecarbon/emissions_tracker.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -369,27 +369,30 @@ def __init__(
369369
self._active_task_emissions_at_start: Optional[EmissionsData] = None
370370

371371
# Tracking mode detection
372-
ressource_tracker = ResourceTracker(self)
373-
ressource_tracker.set_CPU_GPU_ram_tracking()
372+
self._hardware = []
373+
resource_tracker = ResourceTracker(self)
374+
resource_tracker.set_CPU_GPU_ram_tracking()
374375

375376
self._conf["hardware"] = list(map(lambda x: x.description(), self._hardware))
376377

377378
logger.info(">>> Tracker's metadata:")
378379
logger.info(f" Platform system: {self._conf.get('os')}")
379380
logger.info(f" Python version: {self._conf.get('python_version')}")
380381
logger.info(f" CodeCarbon version: {self._conf.get('codecarbon_version')}")
381-
logger.info(f" Available RAM : {self._conf.get('ram_total_size'):.3f} GB")
382+
383+
hardware_info = self.get_detected_hardware()
384+
logger.info(f" Available RAM : {hardware_info['ram_total_size']:.3f} GB")
382385
logger.info(
383-
f" CPU count: {self._conf.get('cpu_count')} thread(s) in {self._conf.get('cpu_physical_count')} physical CPU(s)"
386+
f" CPU count: {hardware_info['cpu_count']} thread(s) in {hardware_info['cpu_physical_count']} physical CPU(s)"
384387
)
385-
logger.info(f" CPU model: {self._conf.get('cpu_model')}")
386-
logger.info(f" GPU count: {self._conf.get('gpu_count')}")
388+
logger.info(f" CPU model: {hardware_info['cpu_model']}")
389+
logger.info(f" GPU count: {hardware_info['gpu_count']}")
387390
if self._gpu_ids:
388391
logger.info(
389-
f" GPU model: {self._conf.get('gpu_model')} BUT only tracking these GPU ids : {self._conf.get('gpu_ids')}"
392+
f" GPU model: {hardware_info['gpu_model']} BUT only tracking these GPU ids : {hardware_info['gpu_ids']}"
390393
)
391394
else:
392-
logger.info(f" GPU model: {self._conf.get('gpu_model')}")
395+
logger.info(f" GPU model: {hardware_info['gpu_model']}")
393396

394397
# Run `self._measure_power_and_energy` every `measure_power_secs` seconds in a
395398
# background thread
@@ -469,6 +472,22 @@ def _init_output_methods(self, *, api_key: str = None):
469472
if self._save_to_logfire:
470473
self._output_handlers.append(LogfireOutput())
471474

475+
def get_detected_hardware(self) -> Dict[str, Any]:
476+
"""
477+
Get the detected hardware.
478+
:return: A dictionary containing hardware data.
479+
"""
480+
hardware_info = {
481+
"ram_total_size": self._conf.get("ram_total_size"),
482+
"cpu_count": self._conf.get("cpu_count"),
483+
"cpu_physical_count": self._conf.get("cpu_physical_count"),
484+
"cpu_model": self._conf.get("cpu_model"),
485+
"gpu_count": self._conf.get("gpu_count"),
486+
"gpu_model": self._conf.get("gpu_model"),
487+
"gpu_ids": self._conf.get("gpu_ids"),
488+
}
489+
return hardware_info
490+
472491
def service_shutdown(self, signum, frame):
473492
logger.warning("service_shutdown - Caught signal %d" % signum)
474493
self.stop()

docs/_sources/installation.rst.txt

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,6 @@
33
Installing CodeCarbon
44
=====================
55

6-
Create a virtual environment using `conda` for easier management of dependencies and packages.
7-
For installing conda, follow the instructions on the
8-
`official conda website <https://docs.conda.io/projects/conda/en/latest/user-guide/install>`__
9-
10-
.. code-block:: bash
11-
12-
conda create --name codecarbon
13-
conda activate codecarbon
14-
156
From PyPi repository
167
--------------------
178

@@ -23,16 +14,20 @@ To install the package, run the following command in your terminal.
2314
2415
pip install codecarbon
2516
26-
From conda repository
27-
---------------------
28-
29-
The package is hosted on the conda repository `here <https://anaconda.org/codecarbon/codecarbon>`__.
17+
Using Conda environments
18+
------------------------
3019

31-
To install the package, run the following command in your terminal.
20+
If you're using Conda for environment management, you can install CodeCarbon with pip in your Conda environment:
3221

3322
.. code-block:: bash
3423
35-
conda install -c codecarbon -c conda-forge codecarbon
24+
conda create --name codecarbon
25+
conda activate codecarbon
26+
pip install codecarbon
27+
28+
.. note::
29+
30+
While CodeCarbon can be used in Conda environments, we no longer maintain Conda packages. We recommend using ``pip install codecarbon`` within your Conda environment, which works seamlessly with Conda.
3631

3732
.. note::
3833

docs/_sources/usage.rst.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ If you want to track the emissions of a computer without having to modify your c
4242
4343
You have to stop the monitoring manually with ``Ctrl+C``.
4444

45+
If you want to detect the hardware of your computer without starting any measurement, you can use:
46+
47+
.. code-block:: console
48+
49+
codecarbon detect
50+
51+
It will print the detected RAM, CPU and GPU information.
52+
4553
In the following example you will see how to use the CLI to monitor all the emissions of you computer and sending everything
4654
to an API running on "localhost:8008" (Or you can start a private local API with "docker-compose up"). Using the public API with
4755
this is not supported yet (coming soon!)

docs/_static/basic.css

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -741,14 +741,6 @@ abbr, acronym {
741741
cursor: help;
742742
}
743743

744-
.translated {
745-
background-color: rgba(207, 255, 207, 0.2)
746-
}
747-
748-
.untranslated {
749-
background-color: rgba(255, 207, 207, 0.2)
750-
}
751-
752744
/* -- code displays --------------------------------------------------------- */
753745

754746
pre {

docs/_static/searchtools.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -513,9 +513,11 @@ const Search = {
513513
// perform the search on the required terms
514514
searchTerms.forEach((word) => {
515515
const files = [];
516+
// find documents, if any, containing the query word in their text/title term indices
517+
// use Object.hasOwnProperty to avoid mismatching against prototype properties
516518
const arr = [
517-
{ files: terms[word], score: Scorer.term },
518-
{ files: titleTerms[word], score: Scorer.title },
519+
{ files: terms.hasOwnProperty(word) ? terms[word] : undefined, score: Scorer.term },
520+
{ files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined, score: Scorer.title },
519521
];
520522
// add support for partial matches
521523
if (word.length > 2) {
@@ -547,8 +549,9 @@ const Search = {
547549

548550
// set score for the word in each file
549551
recordFiles.forEach((file) => {
550-
if (!scoreMap.has(file)) scoreMap.set(file, {});
551-
scoreMap.get(file)[word] = record.score;
552+
if (!scoreMap.has(file)) scoreMap.set(file, new Map());
553+
const fileScores = scoreMap.get(file);
554+
fileScores.set(word, record.score);
552555
});
553556
});
554557

@@ -587,7 +590,7 @@ const Search = {
587590
break;
588591

589592
// select one (max) score for the file.
590-
const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
593+
const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w)));
591594
// add result to the result list
592595
results.push([
593596
docNames[file],

docs/edit/usage.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ If you want to track the emissions of a computer without having to modify your c
4242
4343
You have to stop the monitoring manually with ``Ctrl+C``.
4444

45+
If you want to detect the hardware of your computer without starting any measurement, you can use:
46+
47+
.. code-block:: console
48+
49+
codecarbon detect
50+
51+
It will print the detected RAM, CPU and GPU information.
52+
4553
In the following example you will see how to use the CLI to monitor all the emissions of you computer and sending everything
4654
to an API running on "localhost:8008" (Or you can start a private local API with "docker-compose up"). Using the public API with
4755
this is not supported yet (coming soon!)

docs/index.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
<script src="_static/documentation_options.js?v=eb155f5e"></script>
1717
<script src="_static/doctools.js?v=9bcbadda"></script>
1818
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
19-
<script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
2019
<script src="_static/js/theme.js"></script>
2120
<link rel="index" title="Index" href="genindex.html" />
2221
<link rel="search" title="Search" href="search.html" />
@@ -133,7 +132,7 @@ <h1>CodeCarbon<a class="headerlink" href="#codecarbon" title="Link to this headi
133132
<ul>
134133
<li class="toctree-l1"><a class="reference internal" href="installation.html">Installing CodeCarbon</a><ul>
135134
<li class="toctree-l2"><a class="reference internal" href="installation.html#from-pypi-repository">From PyPi repository</a></li>
136-
<li class="toctree-l2"><a class="reference internal" href="installation.html#from-conda-repository">From conda repository</a></li>
135+
<li class="toctree-l2"><a class="reference internal" href="installation.html#using-conda-environments">Using Conda environments</a></li>
137136
<li class="toctree-l2"><a class="reference internal" href="installation.html#dependencies">Dependencies</a></li>
138137
</ul>
139138
</li>

docs/installation.html

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
<ul class="current">
5555
<li class="toctree-l1 current"><a class="current reference internal" href="#">Installing CodeCarbon</a><ul>
5656
<li class="toctree-l2"><a class="reference internal" href="#from-pypi-repository">From PyPi repository</a></li>
57-
<li class="toctree-l2"><a class="reference internal" href="#from-conda-repository">From conda repository</a></li>
57+
<li class="toctree-l2"><a class="reference internal" href="#using-conda-environments">Using Conda environments</a></li>
5858
<li class="toctree-l2"><a class="reference internal" href="#dependencies">Dependencies</a></li>
5959
</ul>
6060
</li>
@@ -99,13 +99,6 @@
9999

100100
<section id="installing-codecarbon">
101101
<span id="installation"></span><h1>Installing CodeCarbon<a class="headerlink" href="#installing-codecarbon" title="Link to this heading"></a></h1>
102-
<p>Create a virtual environment using <cite>conda</cite> for easier management of dependencies and packages.
103-
For installing conda, follow the instructions on the
104-
<a class="reference external" href="https://docs.conda.io/projects/conda/en/latest/user-guide/install">official conda website</a></p>
105-
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>conda<span class="w"> </span>create<span class="w"> </span>--name<span class="w"> </span>codecarbon
106-
conda<span class="w"> </span>activate<span class="w"> </span>codecarbon
107-
</pre></div>
108-
</div>
109102
<section id="from-pypi-repository">
110103
<h2>From PyPi repository<a class="headerlink" href="#from-pypi-repository" title="Link to this heading"></a></h2>
111104
<p>The package is hosted on the pip repository <a class="reference external" href="https://pypi.org/project/codecarbon/">here</a>.</p>
@@ -114,15 +107,20 @@ <h2>From PyPi repository<a class="headerlink" href="#from-pypi-repository" title
114107
</pre></div>
115108
</div>
116109
</section>
117-
<section id="from-conda-repository">
118-
<h2>From conda repository<a class="headerlink" href="#from-conda-repository" title="Link to this heading"></a></h2>
119-
<p>The package is hosted on the conda repository <a class="reference external" href="https://anaconda.org/codecarbon/codecarbon">here</a>.</p>
120-
<p>To install the package, run the following command in your terminal.</p>
121-
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>conda<span class="w"> </span>install<span class="w"> </span>-c<span class="w"> </span>codecarbon<span class="w"> </span>-c<span class="w"> </span>conda-forge<span class="w"> </span>codecarbon
110+
<section id="using-conda-environments">
111+
<h2>Using Conda environments<a class="headerlink" href="#using-conda-environments" title="Link to this heading"></a></h2>
112+
<p>If you’re using Conda for environment management, you can install CodeCarbon with pip in your Conda environment:</p>
113+
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>conda<span class="w"> </span>create<span class="w"> </span>--name<span class="w"> </span>codecarbon
114+
conda<span class="w"> </span>activate<span class="w"> </span>codecarbon
115+
pip<span class="w"> </span>install<span class="w"> </span>codecarbon
122116
</pre></div>
123117
</div>
124118
<div class="admonition note">
125119
<p class="admonition-title">Note</p>
120+
<p>While CodeCarbon can be used in Conda environments, we no longer maintain Conda packages. We recommend using <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">codecarbon</span></code> within your Conda environment, which works seamlessly with Conda.</p>
121+
</div>
122+
<div class="admonition note">
123+
<p class="admonition-title">Note</p>
126124
<p>We recommend using Python 3.8 or above.</p>
127125
</div>
128126
</section>

0 commit comments

Comments
 (0)