Metadata-Version: 2.4
Name: mainboard
Version: 0.0.9
Summary: CPU, GPU, and NPU hardware topology and telemetry for Python.
Author-email: Pedro Valois <contact@phvv.me>
License-Expression: Apache-2.0
Project-URL: Documentation, https://phvv.me/mainboard
Project-URL: Homepage, https://github.com/phvv-me/mainboard
Project-URL: Repository, https://github.com/phvv-me/mainboard
Project-URL: Issues, https://github.com/phvv-me/mainboard/issues
Keywords: apple-silicon,cpu,cuda,gpu,hardware,machine,npu,telemetry,topology
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: System :: Hardware
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.13
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cyclopts<5,>=4.16
Requires-Dist: patos>=0.0.1
Requires-Dist: plumbum<3,>=2
Requires-Dist: psutil<8,>=7
Requires-Dist: pydantic<3,>=2.13
Requires-Dist: rich>=13
Provides-Extra: cuda
Requires-Dist: cuda-bindings<14,>=13.3; platform_system == "Linux" and extra == "cuda"
Requires-Dist: cuda-core<2,>=1; platform_system == "Linux" and extra == "cuda"
Requires-Dist: cuda-python<14,>=13.3; platform_system == "Linux" and extra == "cuda"
Provides-Extra: dev
Requires-Dist: mainboard[cuda]; extra == "dev"
Requires-Dist: hypothesis>=6; extra == "dev"
Requires-Dist: mypy>=1.13; extra == "dev"
Requires-Dist: pyrefly>=1; extra == "dev"
Requires-Dist: pytest>=9; extra == "dev"
Requires-Dist: pytest-benchmark>=4; extra == "dev"
Requires-Dist: pytest-cov>=5; extra == "dev"
Requires-Dist: pytest-randomly>=3; extra == "dev"
Requires-Dist: ruff>=0.15; extra == "dev"
Requires-Dist: torch>=2; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
Requires-Dist: mkdocs-static-i18n>=1.2; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.26; extra == "docs"
Provides-Extra: profiling
Requires-Dist: nvtx>=0.2; platform_system == "Linux" and extra == "profiling"
Requires-Dist: os-signpost>=0.0.3; platform_system == "Darwin" and extra == "profiling"
Dynamic: license-file

<div align="center">

[![mainboard banner](https://raw.githubusercontent.com/phvv-me/mainboard/main/docs/assets/banner.png)](https://phvv.me/mainboard)

[![CI](https://github.com/phvv-me/mainboard/actions/workflows/ci.yml/badge.svg)](https://github.com/phvv-me/mainboard/actions/workflows/ci.yml)
[![Publish](https://github.com/phvv-me/mainboard/actions/workflows/publish.yml/badge.svg)](https://github.com/phvv-me/mainboard/actions/workflows/publish.yml)
[![PyPI](https://img.shields.io/pypi/v/mainboard)](https://pypi.org/project/mainboard/)
[![Python](https://img.shields.io/pypi/pyversions/mainboard)](https://pypi.org/project/mainboard/)
[![Docs](https://img.shields.io/badge/docs-phvv.me%2Fmainboard-15803d)](https://phvv.me/mainboard)
[![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://github.com/phvv-me/mainboard/actions/workflows/ci.yml)

</div>

## Installation

```sh
pip install mainboard         # CPU and Apple probing, pure Python
pip install mainboard[cuda]   # adds NVIDIA telemetry via the CUDA Python bindings
```

Working in a [chefe](https://phvv.me/chefe) project? Add it to your manifest:

```sh
chefe add mainboard -l python
```

The base install is light and pure Python, so GPU-less Linux hosts like a Raspberry Pi pull nothing CUDA-related. The `cuda` extra installs the NVIDIA bindings on Linux for full GPU detection and telemetry, and provider detection degrades gracefully to no NVIDIA devices whenever the bindings or the hardware are absent.

The root API uses the PEP 810 `__lazy_modules__` compatibility bridge. Python 3.14
keeps the normal eager import behavior. Python 3.15 defers only the audited Mainboard
modules until their exported names are first used. Mainboard does not enable global
lazy imports. `GPU.all()` and `NPU.all()` explicitly load provider registration before
probing, so lazy imports cannot hide hardware backends.

## What it is

mainboard tells Python what compute is on the current machine, without assuming the world is only CUDA. It models CPUs, GPUs, and NPUs as `Unit`s, keeps vendor-specific probing behind providers (Apple and NVIDIA today), and gives you the whole board in one call.

```python
from mainboard import Machine

print(Machine().model_dump_json(indent=2))  # cpu, memory, gpus, npus, and the host environment
```

## Usage

```python
machine = Machine()
machine.cpu.snapshot()  # CPU identity and capacity
machine.gpus[0].snapshot()  # per-GPU telemetry
machine.environment  # user, group(s), and job scheduler on the host
machine.model_dump_json()  # one-call JSON probe of the whole machine
```

The CLI renders a Rich schematic of the board:

```sh
mainboard
```

## Timing spans

`span` is a dormant annotation that is safe to leave in application code. It contains no collection policy and performs no clock, memory, marker, device, or context variable work until a `Profiler` is active. The profiler decides what to collect through `Profiler.Feature` flags. The resulting `Profile` shows only evidence that was observed.

```python
from mainboard.profiling import Profiler, span

with Profiler(features=Profiler.Feature.SPANS) as profiler:
    with span("pipeline"):
        with span("extract"):
            ...
        with span("embed"):
            ...

profiler.show()
```

`Profiler.run("package.module")` profiles a module or script once. Python 3.15 sampling, span timing, process GPU telemetry, native markers, and GPU activity all feed the same result. A detected but unused GPU creates no GPU section. See [`docs/profiling.md`](docs/profiling.md) for feature costs, CLI usage, Tachyon requirements, and native activity behavior.
