Large inputs¶
The exact neighbour search is O(n²) and dominates runtime above roughly 20,000 points.
pip install fastumap[ann] adds an approximate backend, faiss HNSW, which
ships prebuilt wheels for Linux x86_64 and aarch64, macOS and Windows, so it installs without a
compiler.
xy = umap_project(x, 2, knn="auto") # default: exact for small n, approximate above 16k
xy = umap_project(x, 2, knn="approx") # force approximate (needs fastumap[ann])
xy = umap_project(x, 2, knn="exact") # force the exact brute force
"auto", the default, switches to approximate only when the extra is installed and n is at least
16,384, so small inputs remain bit-identical. It is deterministic and retains at least 0.86
neighbour recall against exact. Measured on the neighbour search alone, at 256 dimensions:
| n | exact | approx | speedup | recall@15 |
|---|---|---|---|---|
| 20000 | 71 s | 29 s | 2.4× | 0.91 |
| 30000 | 142 s | 50 s | 2.8× | 0.86 |
fastumap.ann_available() reports whether the backend is installed.
For a given input and seed, output is bit-identical across processes and machines in the same environment. Two things change it across different environments:
- The native kernel against the numpy fallback. The wheels carry the kernel and use it by default; an unbuilt checkout falls back to numpy and differs.
fastumap[ann], which changes the neighbour graph above 16,384 points.
Both are properties of the environment. accelerator_active() and ann_available() report which
paths a run used, so a stored projection can record how it was produced.
Next¶
- The approximate backend is part of the environment, not a free switch — see Guarantees and reproducibility.