Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
971a965
Add an array-API Lloyd iteration and CUDA fusion benchmarks.
cursoragent Oct 15, 2026
c476847
Record the L4 fusion journal for three Lloyd assignment shapes.
cursoragent Oct 15, 2026
21767be
Publish the rendered journal from PR CI
cursoragent Oct 15, 2026
86d4657
Re-run the Pages deployment
cursoragent Oct 15, 2026
03f5b4b
Summarize whether argmin fused into the distance
cursoragent Oct 15, 2026
cae5632
Link each assignment schedule to its source
cursoragent Oct 15, 2026
ba94de8
Split the fusion answer into PyTorch and CuPy
cursoragent Oct 15, 2026
154f652
Publish the k-means journal with the shared Pages workflow.
cursoragent Oct 15, 2026
676285c
Pass GITHUB_TOKEN into the report-site push.
cursoragent Oct 15, 2026
715dbaa
Call the shared publisher from this branch.
cursoragent Oct 15, 2026
4e3f2b0
Call the shared publisher on main.
cursoragent Oct 15, 2026
d70ffae
Add tiled Gram Lloyd steps and k-means++.
cursoragent Oct 15, 2026
16cfa4d
Log the tile-size iteration before the L4 sweep.
cursoragent Oct 15, 2026
b35a95e
Record the Cython Lloyd timing on the L4 host.
cursoragent Oct 15, 2026
7569dd8
Record the feature-heavy Gram tile sweep.
cursoragent Oct 15, 2026
df65b22
Record compiled running tiles against the Gram tiles.
cursoragent Oct 15, 2026
b9a3db8
Compute the k-means++ sample norm once.
cursoragent Oct 15, 2026
b1d5a08
Record the tiled Lloyd step, Cython comparison, and k-means++.
cursoragent Oct 15, 2026
c2f3a1e
Tile the full k-means fit so it does not copy X.
cursoragent Oct 15, 2026
1d641b2
Record the full k-means comparison with PR 23 and cuML.
cursoragent Oct 15, 2026
d4ff3db
Add a multi-dataset benchmark across five k-means implementations.
cursoragent Oct 15, 2026
85d91b8
Record the first breadth comparison across blob structure and k.
cursoragent Oct 15, 2026
678d95e
Add the two largest shapes to the breadth comparison.
cursoragent Oct 15, 2026
e4940c0
Add repeated-seed and fixed-center KMeans benchmarks
cursoragent Oct 15, 2026
c74d6eb
Start the repeated-seed Lloyd comparison journal
cursoragent Oct 15, 2026
dfc0f02
Checkpoint the five-seed benchmark run
cursoragent Oct 15, 2026
d00f7a5
Record large-shape seed variation checkpoint
cursoragent Oct 15, 2026
f71204d
Checkpoint the final seeded repetitions
cursoragent Oct 16, 2026
f2e08e3
Publish five-seed and fixed-center KMeans results
cursoragent Oct 16, 2026
4df721e
Lead the journal homepage with the five-seed eager comparison
cursoragent Oct 16, 2026
1b73577
Add stochastic empty-center relocation and bounded task benchmark
cursoragent Oct 16, 2026
e327808
Calibrate the bounded empty-center task mix
cursoragent Oct 16, 2026
ed31c3f
Publish empty-center relocation task mix
cursoragent Oct 16, 2026
fd61e6f
Mark the empty-center task mix as complete
cursoragent Oct 16, 2026
7881e7e
Keep the random baseline on inertia plots only
cursoragent Oct 16, 2026
a6962df
Time k-means++ initialization without Lloyd iterations.
cursoragent Oct 16, 2026
9f1ab99
Publish k-means++ initialization timing, memory, and inertia.
cursoragent Oct 16, 2026
a7d252c
Use farthest relocation and add scalable k-means init
cursoragent Oct 16, 2026
0dd276f
Publish scalable initialization comparison
cursoragent Oct 16, 2026
8aa4eef
Join wrapped bullet continuation lines in the journal renderer
cursoragent Oct 16, 2026
92a3f4a
Add farthest and scalable fit tracks and a scalable reduction ablation
cursoragent Oct 16, 2026
9775e8f
Use Array API backend labels and single-panel initializer plots
cursoragent Oct 16, 2026
cea3964
Keep URL fragments when rewriting journal report links
cursoragent Oct 16, 2026
82e5aaa
Publish consolidated init, Lloyd-only, and full-fit benchmark with sc…
cursoragent Oct 16, 2026
4350c3e
Check journal source links against pinned commits in CI
cursoragent Oct 16, 2026
9b70f1a
Pin journal source links to the commits each report measured
cursoragent Oct 16, 2026
d981dda
Add source link audit journal entry
cursoragent Oct 16, 2026
13fb48e
Normalize each fitted-quality section against its own task results
cursoragent Oct 16, 2026
c9cbf86
Show quality as inertia divided by each task's best mean
cursoragent Oct 16, 2026
b0a5d9b
Add large-k Lloyd and scalable initialization probes
cursoragent Oct 16, 2026
4430d69
Publish large-k Lloyd optimization plan
cursoragent Oct 16, 2026
0622b3b
Expand 013 report with code detail on missing array-API scatter-add
cursoragent Oct 16, 2026
49f904a
Add portable scikit-learn compatible KMeans estimator
cursoragent Oct 16, 2026
27747a6
Add CuPy centroid update acceleration probe
cursoragent Oct 16, 2026
09b9d63
Publish portable KMeans and CuPy update findings
cursoragent Oct 16, 2026
88badd2
Clarify CuPy update hook constraints
cursoragent Oct 16, 2026
f13c074
Add PyTorch and CuPy scatter-add centroid updates with portable fallback
cursoragent Oct 16, 2026
7f11202
Benchmark the KMeans estimator with native and generic update paths
cursoragent Oct 16, 2026
89ee454
Add estimator benchmark plots and document native update paths
cursoragent Oct 16, 2026
3432356
Check array-API input finiteness without an input-sized temporary
cursoragent Oct 16, 2026
04848dd
Keep the one-hot update for wide few-cluster CUDA inputs
cursoragent Oct 16, 2026
606a159
Read JSON result files and hatch scalable cuML bars in estimator plots
cursoragent Oct 16, 2026
69636e9
Correct the measured PyTorch finiteness-check overhead in a docstring
cursoragent Oct 16, 2026
98fd4f1
Add journal 015: native backend updates in the KMeans estimator
cursoragent Oct 16, 2026
89df12c
Add bounded GEMM versus broadcast distance benchmark
cursoragent Oct 17, 2026
8e7a2ec
Plot distance formulation benchmark results
cursoragent Oct 17, 2026
c7b001e
Report distance benchmark ratios and extended timeouts
cursoragent Oct 17, 2026
26aae29
Add journal 016 GEMM versus broadcast benchmark
cursoragent Oct 17, 2026
3ca8690
Prototype stable GEMM distances with selective recomputation
cursoragent Oct 17, 2026
1cb6801
Benchmark stable GEMM fallback on translated data
cursoragent Oct 17, 2026
9f373a4
Analyze GEMM cancellation fallback
cursoragent Oct 17, 2026
f211390
Report GEMM cancellation fallback results
cursoragent Oct 17, 2026
6c25822
Prototype backend-agnostic CPU KMeans optimizations
cursoragent Oct 17, 2026
ee8e241
Report backend-neutral CPU optimization results
cursoragent Oct 17, 2026
45199eb
Benchmark KMeans optimizations on CUDA and avoid strided augmented GEMM
cursoragent Oct 17, 2026
d5fa47d
Report CPU and GPU optimization rerun beside cakedev0
cursoragent Oct 17, 2026
67a64ea
Benchmark balanced KMeans task on device-resident cuML data
cursoragent Oct 28, 2026
6cd77af
Resolve benchmark interpreters from repository root
cursoragent Oct 28, 2026
0b9beea
Benchmark balanced KMeans task on gpu-2
cursoragent Oct 28, 2026
8c85d91
Pin balanced benchmark source links
cursoragent Oct 28, 2026
4bc8139
Remeasure five-task cuML timings on device-resident data
cursoragent Oct 28, 2026
3ba152a
Record PyTorch XPU and dpnp timings on Arc B390.
ogrisel Oct 28, 2026
d6605d1
Merge main and keep the pandoc journal renderer
cursoragent Oct 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/kmeans-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Render k-means fusion report

on:
pull_request:
paths:
- "kmeans_lloyd/**"
- ".github/workflows/kmeans-report.yml"

concurrency:
group: kmeans-report-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: write
pages: write
id-token: write
pull-requests: write

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Check journal source links
run: python tools/check_source_links.py --repo "${{ github.repository }}" kmeans_lloyd/journal
- name: CPU tests
working-directory: kmeans_lloyd
env:
SCIPY_ARRAY_API: "1"
run: |
python -m pip install --upgrade pip
python -m pip install -e . array-api-strict pytest
python -m pytest tests

report:
needs: test
uses: ogrisel/cursor-sandbox/.github/workflows/publish-report.yml@main
with:
journal-path: kmeans_lloyd/journal
site-title: Lloyd k-means journal
comment-marker: "<!-- kmeans-lloyd-report -->"
9 changes: 9 additions & 0 deletions kmeans_lloyd/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.pixi
__pycache__/
*.py[cod]
.pytest_cache/
*.egg-info/
dist/
build/
.mplconfig/
site/
68 changes: 68 additions & 0 deletions kmeans_lloyd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Portable array-API KMeans and kernel experiments

`kmeans_lloyd.KMeans` is a scikit-learn-compatible dense KMeans estimator
implemented with Python array API operations. It preserves NumPy, PyTorch, or
CuPy arrays on their original device and supports the public KMeans
hyperparameters that apply to dense Lloyd iterations. Initialization is
restricted to `"k-means++"` and `"random"`; sparse inputs and Elkan are
intentionally unsupported.

```python
from kmeans_lloyd import KMeans

model = KMeans(
n_clusters=8,
init="k-means++",
n_init="auto",
random_state=0,
).fit(X)

labels = model.labels_
centers = model.cluster_centers_
```

The centroid update uses PyTorch `index_add_` or CuPy `add.at` when `X` is a
PyTorch tensor or CuPy array, and portable one-hot matrix products for every
other array API namespace. On CUDA, wide inputs with few clusters keep the
one-hot products, which beat atomic scatter-adds there.
`kmeans_lloyd.backends.use_native_backends(False)`
forces the portable path everywhere.

The package also contains lower-level Lloyd primitives and CUDA experiments
on assignment fusion and backend-specific centroid reductions.

The naive assignment is

```text
distances = sum((X[:, None, :] - centroids[None, :, :]) ** 2, axis=-1)
labels = argmin(distances, axis=1)
```

That broadcasts a difference tensor of shape `(n_samples, n_clusters, n_features)`.
The Gram form and the tiled / running schedules are rewrites used to give
the compilers a smaller region to fuse. Eager execution is always measured
beside the compiled or fused call.

## Reproduce

On a machine with an NVIDIA GPU whose driver supports CUDA 13:

```bash
cd kmeans_lloyd
pixi install
pixi run test
pixi run probe
pixi run bench
python ../tools/render_journal.py \
--journal journal \
--site site \
--title "Lloyd k-means fusion journal"
```

`NVIDIA_TF32_OVERRIDE=0` is set in the pixi environment so PyTorch and CuPy
both run IEEE float32 matmuls.

Results land in `journal/*/results.json`. The narrative is the journal.
The shared renderer builds `site/`. Pull request CI calls
`.github/workflows/publish-report.yml`, which publishes that journal at
`pr-<number>/` and updates the pull request comment with the URL.
Loading
Loading