A small Rust tool that reads a Linux machine's NUMA/PCIe topology from sysfs and recommends which CPU cores to pin near a given GPU or accelerator device.
- Reads NUMA node and CPU info from
/sys/devices/system/node/*, including the kernel's SLIT distance table (relative memory-access cost between nodes). - Finds GPUs and other accelerator-class PCIe devices from
/sys/bus/pci/devices/*, along with each device's reported NUMA affinity. - Scores every NUMA node's distance to each accelerator's home node
and outputs a ranked recommendation, a plain-English verdict, and a
ready-to-paste
numactlcommand.
No hwloc, no netlink, zero external crates — just the sysfs files
the kernel already exposes.
Placing a workload's CPU threads on the wrong NUMA node relative to
its GPU can cost real throughput on memory-bandwidth-bound work. This
tool automates the "which cores are actually close to this GPU"
question instead of doing it by hand with lstopo/numactl -H.
$ cargo install --path .Or build without installing:
$ cargo build --release
$ ./target/release/topolens scan$ topolens scan
NUMA nodes: 2
node0 cpus=0-15
node1 cpus=16-31
Accelerators: 1
0000:81:00.0 class=0x030200 vendor=0x10de device=0x2331 numa_node=1
$ topolens recommend
0000:81:00.0
verdict: local: pin here, no cross-node hop
pin cpus: 16-31
numactl: numactl --physcpubind=16-31 --membind=1As a library:
use topolens::{Topology, advisor};
let topo = Topology::scan();
for placement in advisor::recommend_all(&topo) {
println!("{}: {}", placement.accelerator.bdf, placement.verdict());
}hwloc/lstopo is a general-purpose topology library that builds a full
hardware graph on every run. This tool only reads the handful of sysfs
paths it needs for CPU-to-accelerator scoring — narrower in scope, not
a replacement for hwloc.
It doesn't schedule anything and doesn't talk to any external control plane — it's just a topology-to-recommendation calculator. Wiring the output into an actual scheduler is left to the caller.
See BENCHMARKS.md for micro-benchmark numbers and how to reproduce them.
$ cargo testTests run against synthetic topology fixtures (no real sysfs required), so they pass regardless of the machine running them.