# hypomnesis
[](https://github.com/PCfVW/hypomnesis/actions/workflows/ci.yml)
[](https://crates.io/crates/hypomnesis)
[](https://docs.rs/hypomnesis)
[](https://www.rust-lang.org)
[](https://github.com/PCfVW/hypomnesis#license)
[-blue.svg)](https://github.com/rust-secure-code/safety-dance/)
[](#capabilities)
**ὑπόμνησις** — *External RAM and VRAM, measured.*
> 🚀 **`0.2.1` is the first dogfooding-driven patch.** Five wear-and-tear additions surfaced by [`hf-fetch-model 0.10.1`](https://github.com/PCfVW/hf-fetch-model)'s adoption: a `test-helpers`-feature `GpuDeviceInfoBuilder` so downstream tests can synthesise `#[non_exhaustive]` `GpuDeviceInfo` fixtures, a `name_or_unknown()` convenience to settle consumer divergence on the fallback phrase, `format_total` / `format_used` parity helpers for `report`-feature consumers, an `HypomnesisError` `Display`-vs-structured-fields contract codified in the doc-comment, and a `README.md` "Used by" + brief refresh. All additive under the `#[non_exhaustive]` policy carried over from v0.2.0 (`Snapshot::all`, `gpu_processes`, `hmn` CLI, `format_free` / `print_free`). See [`CHANGELOG.md`](CHANGELOG.md) for the v0.2.1 entry, [`docs/roadmap-v0.2.1.md`](docs/roadmap-v0.2.1.md) for the wave-by-wave rationale, and [`docs/hypomnesis-adoption.md`](docs/hypomnesis-adoption.md) for the underlying dogfooding report.
## Table of Contents
- [Install](#install)
- [Usage](#usage)
- [Binary (`hmn`)](#binary-hmn)
- [Capabilities](#capabilities)
- [Feature Flags](#feature-flags)
- [Used by](#used-by)
- [License](#license)
- [Development](#development)
## Install
```toml
[dependencies]
hypomnesis = "0.2"
```
The default feature set (`nvml`, `dxgi`, `nvidia-smi-fallback`) covers process RSS and per-process / device-wide GPU memory on both Windows (`IDXGIAdapter3` + `NVML`) and Linux (`NVML`), with a `nvidia-smi` subprocess fallback. The `dxgi` dependency on the `windows` crate is target-conditional — Linux users pay nothing for it.
For candle-mi-compatible delta and printing helpers (`MemoryReport`, `print_delta`, `print_before_after`, `ram_mb`, `vram_mb`):
```toml
hypomnesis = { version = "0.2", features = ["report"] }
```
For a stripped-down build (process RSS only, no GPU backends):
```toml
hypomnesis = { version = "0.2", default-features = false }
```
## Usage
```rust
use hypomnesis::Snapshot;
fn main() -> Result<(), hypomnesis::HypomnesisError> {
let snap = Snapshot::now(0)?;
println!("RAM: {} bytes", snap.ram_bytes);
if let Some(dev) = snap.gpu_device {
let total_gib = dev.total_bytes as f64 / (1u64 << 30) as f64;
let used_gib = dev.used_bytes as f64 / (1u64 << 30) as f64;
println!(
"GPU 0 [{}]: {:.1} / {:.1} GiB used",
dev.name.as_deref().unwrap_or("unknown"),
used_gib, total_gib,
);
}
if let Some(proc_gpu) = snap.gpu {
let kind = if proc_gpu.is_per_process { "per-process" } else { "device-wide" };
let mib = proc_gpu.used_bytes as f64 / (1u64 << 20) as f64;
println!("This process: {:.0} MiB ({})", mib, kind);
}
Ok(())
}
```
Expected output (RTX 5060 Ti, Windows, idle process):
```
RAM: 142475264 bytes
GPU 0 [NVIDIA GeForce RTX 5060 Ti]: 1.8 / 16.0 GiB used
This process: 119 MiB (per-process)
```
## Binary (`hmn`)
`hypomnesis` ships a small CLI binary, `hmn`, behind the default-off `cli` feature. Install it with:
```sh
cargo install hypomnesis --features cli
```
Two subcommands:
```sh
hmn # device summary (free / total per GPU)
hmn ps # all GPU processes — discovery command
hmn ps --pid 12345 # filter to one PID
hmn ps --device 0 # filter to one GPU on multi-GPU rigs
hmn ps --json # scriptable output
```
Example default output (single NVIDIA dGPU, the maintainer's reference machine — Ryzen 9 5950X has no iGPU, so only one adapter surfaces):
```
GPU 0 [NVIDIA GeForce RTX 5060 Ti]: free 13284 MiB / 16384 MiB
```
Illustrative output on a *heterogeneous* machine (NVIDIA dGPU + Intel/AMD iGPU on Windows). Not yet verified end-to-end on real hardware — see [`docs/roadmap-v0.2.0.md`](docs/roadmap-v0.2.0.md) "Verification plan":
```
GPU 0 [NVIDIA GeForce RTX 5060 Ti]: free 13284 MiB / 16384 MiB
GPU 1 [Intel Iris Xe Graphics]: free 32768 MiB / 32768 MiB
```
`hmn ps` (illustrative — empty on machines with no active CUDA workload):
```
PID NAME VRAM DEVICE
12345 lm-studio.exe 8.2 GiB NVIDIA GeForce RTX 5060 Ti
67890 python.exe 1.4 GiB NVIDIA GeForce RTX 5060 Ti
```
A one-line summary is written to **stderr** after each `hmn ps` run:
```
hmn: 2 compute processes found.
hmn: 0 compute processes found matching pid=99 device=0. # with filters
```
The stderr summary is always printed, even when the table is empty, so interactive users get an unambiguous "command worked, here's the count" line without breaking stdout's scriptability. Pipelines like `hmn ps | awk 'NR>1 {print $1}'` or `hmn ps --json | jq` work as expected. Redirect `2>/dev/null` to suppress the summary.
**Limitations** (intrinsic to the underlying data sources, not bugs):
1. **Compute-only.** `hmn ps` enumerates only processes with an active `CUDA` context. Browsers using GPU compositing, games, and pure-graphics apps do not appear. This is a property of the `NVML` and `nvidia-smi --query-compute-apps` data sources.
2. **Windows process names may be `?`.** `nvidia-smi` writes a literal `?` for protected processes whose image name it cannot read. The library preserves this as `Some("?")` rather than failing the row.
3. **WDDM bug parity.** The `R570` `u64::MAX` sentinel and `used > total` corruption checks the library handles for the calling process are applied per-row in `hmn ps`; affected rows are dropped rather than reported as garbage.
4. **Windows compute-process attribution is `nvidia-smi`-backed.** `IDXGIAdapter3::QueryVideoMemoryInfo` only answers for the *calling* process, and `NVML`'s per-process query returns `NVML_VALUE_NOT_AVAILABLE` under `WDDM`. So `hmn ps` on Windows is honest-but-second-class compared to Linux's clean `NVML` enumeration.
## Capabilities
| Metric | Windows | Linux |
|--------|---------|-------|
| Process RSS | `K32GetProcessMemoryInfo` | `/proc/self/status` (no `unsafe`) |
| Device-wide GPU memory | `NVML` (`nvml.dll`) | `NVML` (`libnvidia-ml.so.1`) |
| Per-process GPU memory | `DXGI` (`IDXGIAdapter3::QueryVideoMemoryInfo`) | `NVML` (`nvmlDeviceGetComputeRunningProcesses`) |
| Fallback | `nvidia-smi` subprocess | `nvidia-smi` subprocess |
`hypomnesis` uses `IDXGIAdapter3` on Windows because `WDDM` means the kernel memory manager — not the NVIDIA driver — owns GPU allocations, so `NVML`'s per-process query returns `NOT_AVAILABLE` under Windows. `DXGI 1.4` is the only reliable per-process source. On Linux, `NVML`'s `nvmlDeviceGetComputeRunningProcesses_v3` returns true per-process figures.
The crate handles two known driver bugs out of the box:
1. **`NVML` `u64::MAX` sentinel** — some `R570`-series drivers report `0xFFFFFFFFFFFFFFFF` for every running process's memory (observed on `RTX 5060 Ti`). `hypomnesis` detects this and falls back to `nvidia-smi`.
2. **`used > total` corruption** — sanity-checks each per-process reading against the device-wide total; falls back to `nvidia-smi` on detected corruption.
## Feature Flags
| Feature | Default | Description |
|---------|---------|-------------|
| `nvml` | yes | `NVML` dynamic load via `libloading` (Linux + Windows-`WDDM` device-wide) |
| `dxgi` | yes | Windows per-process `VRAM` via `IDXGIAdapter3` (no-op on non-Windows) |
| `nvidia-smi-fallback` | yes | Subprocess fallback when `NVML` / `DXGI` fail or are disabled |
| `report` | no | `MemoryReport` delta + `print_delta` / `print_before_after` / `ram_mb` / `vram_mb` helpers (`candle-mi` parity, candidate for `candle-mi` v0.2 migration via Cargo flag flip); `format_free` / `print_free` / `format_total` / `format_used` formatting helpers on `GpuDeviceInfo` |
| `debug-output` | no | Print raw `NVML` / `DXGI` values to stderr (diagnostic) |
| `cli` | no | Build the `hmn` CLI binary (pulls `clap` 4 as a dep). Library users do not need this; install via `cargo install hypomnesis --features cli`. |
| `test-helpers` | no | Expose `GpuDeviceInfoBuilder` for downstream tests that need synthetic `GpuDeviceInfo` fixtures. Default-off, additive — production code must never enable it. |
## Used by
- [hf-fetch-model](https://github.com/PCfVW/hf-fetch-model) — Hugging Face model weights and metadata fetcher (uses `device_info` for `inspect --check-gpu`)
_Forthcoming: [candle-mi](https://github.com/PCfVW/candle-mi) is expected to migrate its in-tree memory module to `hypomnesis` (`features = ["report"]`) after v0.2.1 lands._
## License
Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or [MIT License](LICENSE-MIT) at your option.
## Development
- Exclusively developed with [Claude Code](https://claude.com/product/claude-code) (dev) and [Augment Code](https://www.augmentcode.com/) (review)
- Git workflow managed with [Fork](https://fork.dev/)
- All code follows [CONVENTIONS.md](CONVENTIONS.md), derived from [Amphigraphic-Strict](https://github.com/PCfVW/Amphigraphic-Strict)'s [Grit](https://github.com/PCfVW/Amphigraphic-Strict/tree/master/Grit) — a strict Rust subset designed to improve AI coding accuracy.