Metadata-Version: 2.4
Name: vor-profile
Version: 0.2.1
Classifier: Programming Language :: Rust
Summary: Headless profiling capture for Python: per-step metrics + flame scopes to a .vor stream, read back with the Rust vor tooling.
Keywords: profiling,puffin,gpu,ml,instrumentation
License: MIT OR Apache-2.0
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Repository, https://github.com/SConsul/vor

# vor

Python bindings for the [vor](https://github.com/SConsul/vor) profiler.
Instrument a training or inference loop, write per-step metrics (and
optional flame frames) to a `.vor` file, and read it back in Python with
`vor.Reader`. The GUI replay panel stays in the Rust tools.

## Install

```sh
uv add vor-profile      # or: pip install vor-profile
```

The distribution is `vor-profile` (the name `vor` is taken on PyPI); the
import is `vor`.

## Usage

```python
import vor

vor.enable()
vor.record_metric_unit("throughput", "tok/s")  # optional, once

@vor.profile
def train_step(batch):
    ...

for batch in loader:
    loss = train_step(batch)
    vor.record_metric("loss", loss)
    vor.frame_mark()
vor.flush()
```

Set `VOR_RECORD` to capture; leave it unset and nothing is written:

```sh
VOR_RECORD=/scratch/run.vor python train.py
```

`VOR_RECORD_FLAME=1` also records flame frames (`VOR_RECORD_EVERY=N`
samples 1 step in N). See `examples/train.py`.

## API

- `enable()` - turn collection on; arm capture when `VOR_RECORD` is set.
- `frame_mark()` - end a step; writes one record.
- `record_metric(name, value)` - a named scalar for this step.
- `record_metric_unit(name, unit)` - label a metric's row, once.
- `flush()` - write buffered records before exit.
- `@profile` - flame scope per call, named `module.qualname`.
- `profile_scope(name)` - flame scope for a `with` block.
- `Reader(path)` - iterate a capture; each `Frame` has `.system`
  (aligned to `reader.columns`), `.user` (dict of named scalars), and
  `.flame` (raw puffin bytes or `None`).

## Reading a capture

```python
import vor

reader = vor.Reader("/scratch/run.vor")
for frame in reader:
    step_ms = frame.system[0]      # columns are reader.columns
    loss = frame.user.get("loss")
```

Into a DataFrame for plotting (no pandas dependency in this package):

```python
import pandas as pd

reader = vor.Reader("/scratch/run.vor")
cols = [name for name, _unit in reader.columns]
df = pd.DataFrame(
    {**dict(zip(cols, f.system)), **f.user} for f in reader
)
df["loss"].rolling(50).mean().plot()
```

The GUI replay panel stays in the Rust crate:

```sh
cargo run --example replay --features viz,mac -- /scratch/run.vor
```

## Build from source

Needs [maturin](https://www.maturin.rs/). The base build is portable
(metrics only); add a platform feature for GPU rows:

```sh
maturin develop                        # metrics
maturin develop --features mac         # + Apple Silicon GPU (IOKit)
maturin build --release --features cuda  # + NVIDIA GPU (NVML)
```

