Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
evoc (Rust)
evoc is a Rust implementation of EVōC — Embedding Vector Oriented Clustering for fast clustering of high-dimensional vectors (CLIP, sentence-transformers, document embeddings, images, etc.).
The API mirrors the Python library: build a kNN graph, learn a low-dimensional node embedding on that graph, then run density-based clustering (Borůvka MST + HDBSCAN-style condensed tree) with optional multi-resolution cluster layers.
Documentation
| Document | Description |
|---|---|
| ARCHITECTURE.md | Pipeline, module map, parity, backends |
| examples/README.md | Runnable examples and figures |
| CONTRIBUTING.md | Build, test, parity workflow |
| CHANGELOG.md | Version history |
| AUTHORS.md | Upstream and Rust port attribution |
| CITATION.md | How to cite PLSCAN, EVōC, and this crate |
| LICENSE | BSD-2-Clause |
| NOTICE.md | Third-party dependency licenses |
Installation
Add to Cargo.toml:
[]
= "0.0.1"
= "0.16"
Or from git:
= { = "https://github.com/eugenehp/evoc-rs" }
Build from source:
Quick start
use Evoc;
use Array2;
// One row per vector; L2-normalize rows for cosine kNN on f32 data.
let data: = /* ... */ zeros;
let mut clusterer = Evoc ;
let labels = clusterer.fit_predict?;
let n_clusters = labels
.iter
.filter
.
.len;
println!;
// Learned graph embedding (after fit_predict):
let _embedding = clusterer.embedding_.clone;
Examples
| Command | Description |
|---|---|
cargo run --release --example cluster_in_memory |
Synthetic blobs, no files |
cargo run --release --example user_clustering -- data.npy 42 |
Your .npy matrix |
cargo run --release --example bbc_news_clustering |
BBC News (5 topics) |
cargo run --release --example news_clustering -- 3000 42 |
20 Newsgroups |
cargo run --release --example fashion_mnist_clustering -- 3000 42 |
Fashion-MNIST |
cargo run --release --bin mnist_labels -- --mnist 3000 42 labels.npy |
MNIST download + cluster |
| Example | Figure |
|---|---|
| Synthetic blobs | ![]() |
| MNIST | ![]() |
| Fashion-MNIST | ![]() |
| BBC News (5 topics) | ![]() |
| 20 Newsgroups | ![]() |
Regenerate figures: python3 examples/render_readme_figures.py (requires matplotlib + scikit-learn).
Binaries
| Binary | Purpose |
|---|---|
bench |
Time fit_predict on a float32 .npy matrix |
bench_backends |
Compare wall time across strict + RLX backends — see benches/README.md |
bench_huge |
Synthetic scale benchmarks |
mnist_fetch / fashion_mnist_fetch |
Download, subsample, write .npy |
mnist_labels |
Cluster from .npy, --mnist, or --fashion-mnist |
emb_epoch_diff |
UMAP epoch parity vs Python dumps |
Supported input types
| Type | Distance | API |
|---|---|---|
f32 (L2-normalized rows) |
Cosine | Evoc::fit_predict(Array2<f32>) |
i8 |
Quantized cosine | knn_graph(EmbeddingData::Int8(...)) |
u8 (packed bits/row) |
Bitwise Jaccard | knn_graph(EmbeddingData::Binary(...)) |
Features
| Cargo feature | Description |
|---|---|
full (default) |
cluster + npy + datasets |
cluster |
Full Evoc API (implies embed → init → graph → knn) |
knn |
kNN graph (rlx-cpu fast path; C reference when deterministic) |
graph |
Fuzzy neighbor graph from kNN |
init |
Label-propagation initialization |
embed |
UMAP-style node embedding |
npy |
.npy / .npz load helpers (parity, benchmarks) |
datasets |
MNIST, Fashion-MNIST, BBC News, 20 Newsgroups download helpers |
rlx-cpu |
RLX CPU backend (no extra rlx crate) |
rlx-cuda |
RLX CUDA backend (NVIDIA) |
rlx-mlx |
RLX MLX backend (Apple Silicon) |
rlx-rocm |
RLX ROCm backend (AMD) |
rlx-wgpu |
RLX wgpu backend (cross-platform GPU) |
rlx-all |
Convenience: all rlx-* backends |
rlx_metal |
Alias for rlx-mlx |
Minimal dependency (clustering only):
= { = "0.0.1", = false, = ["cluster"] }
Enable only the backend you need (each feature is independent):
= { = "0.0.1", = false, = ["cluster", "rlx-cuda"] }
Run one backend at a time:
EVOC_BACKEND=cuda
EVOC_BACKEND=cuda
Set EVOC_BACKEND=strict|cpu|cuda|mlx|metal|rocm|wgpu|gpu or pass compute_backend on Evoc. Requesting a backend without its Cargo feature returns an error (no silent fallback).
Parity with Python EVōC
Golden parity fixtures live in the git repository under tests/fixtures/ (not included in the crates.io package):
| Test | Status |
|---|---|
graph_parity |
Exact fuzzy graph from fixture kNN |
parity_knn_* |
Bit-exact kNN |
parity_intermediates |
Staged init/embedding tolerance |
parity_labels_* |
0 label mismatches on goldens |
With Evoc.parity_graph_coo, graph/init checkpoints match Python on reference fixtures. Ad-hoc large datasets may still differ slightly without those intermediates (see CHANGELOG.md).
Python reference
Upstream: TutteInstitute/evoc · Read the Docs
Set EVOC_ROOT (or EVOC_PARITY_ROOT) for parity scripts in scripts/.
Citation
If you use this software in research, cite:
- PLSCAN — algorithm paper (arXiv:2512.16558)
- EVōC (Python) — reference implementation
- evoc-rs (Rust) — this crate when you run the Rust implementation
Full text, BibTeX (evoc_rs2026), and CITATION.cff: CITATION.md · CITATION.bib
Authors
- EVōC (Python): Leland McInnes, Tutte Institute for Mathematics and Computing
- evoc-rs (Rust): Eugene Hauptmann — see AUTHORS.md
License
BSD-2-Clause — see LICENSE. Same license family as upstream EVōC.
Third-party crate licenses: NOTICE.md.




