Metadata-Version: 2.4
Name: gpiyo
Version: 0.1.0
Summary: Tell the gpiyo dashboard what a GPU run is, how far it has got, and how it ended
Project-URL: Homepage, https://gpiyo.cloud
Author: Zhanbo Huang
Requires-Python: >=3.9
Provides-Extra: rich
Requires-Dist: rich>=13; extra == 'rich'
Description-Content-Type: text/markdown

# gpiyo

Lets a GPU run tell the [gpiyo](https://gpiyo.cloud) dashboard what it is, how far it has got, and how it ended.

```
uv add gpiyo            # or: uv pip install gpiyo
```

```python
import gpiyo

gpiyo.note(title="dinov3 probe", run="probe-v2", tags=["probe"])

for step in range(total):
    ...
    gpiyo.progress(step + 1, total)
```

That is the whole API.

- `note(...)` takes the fields of the `annotate` MCP tool: `title`, `run`, `agent`, `expect`, `preemptible`, `links`, `tags`, `detail`. Calls merge; a field left out is kept.
- `progress(done, total)` reports the fraction done, and from the pace so far, how long the whole run should take. If the run stops advancing, that estimate stops moving and the dashboard reports it overdue.
- The exit code is recorded on the way out: a normal exit, `sys.exit(n)`, an uncaught exception or SIGTERM. A process killed outright (SIGKILL, the OOM killer) cannot record anything; gpiyo still sees it vanish.

## Under torchrun and DDP

Every rank is its own process and reports itself. Under torchrun the ranks of one launch share a `run` without being told: it is the rendezvous id, or the master address and port, which every rank of that launch sees and no other launch running at the same time can. Pass `run=` to name it yourself.

## Rich

```python
from gpiyo.rich import GpiyoProgress, track  # pip install "gpiyo[rich]"

for batch in track(loader, description="train"):
    ...
```

`GpiyoProgress` is rich's `Progress`; it reports the first unfinished task that has a total, so an outer epoch bar wins over the batch bar inside it.

## Lightning

```python
from gpiyo.lightning import GpiyoCallback

trainer = Trainer(callbacks=[GpiyoCallback(run="probe-v2", tags=["probe"])])
```

The title defaults to the LightningModule's class name. `fit` reports `global_step` against `estimated_stepping_batches`, with its validation counted in the pace; a standalone `validate`, `test` or `predict` reports its own batches and starts its estimate afresh.

## Where it goes

The run writes `/dev/shm/gpiyo/<pid>.json`, which the gpiyo node client on the same machine reads and forwards. The client is installed by the machine's administrators, not by this package. On a machine without it, every call does nothing, so the same script runs unchanged on a laptop. `GPIYO_NOTE_DIR` overrides the directory.

Nothing here raises: a run is never stopped by its own reporting.
