022 — PyTorch XPU and the CPU contenders on Arc B390

015 through 021 timed this six-task mix on one NVIDIA L4 host. This entry repeats the same tasks on a laptop: PyTorch on the integrated Arc GPU, PyTorch on the CPU, stock scikit-learn, and cakedev0's optimized scikit-learn. There is no CUDA device here, so CuPy and cuML are absent. Seed-level rows are in runs.jsonl. Means are in results.json.

Setup

Full fit from greedy k-means++

Time in seconds, mean ± sample standard deviation. Bold is the fastest mean in that hardware group.

implementation k3-d1000 k17-d180 k100-d32 k256-d128 k550-d6 k3000-d2
Torch CPU, native 4.99 ± 0.06 3.82 ± 0.07 5.12 ± 0.10 1.85 ± 0.04 5.98 ± 0.17 17.06 ± 0.19
Torch CPU, generic 5.01 ± 0.19 4.16 ± 0.29 5.79 ± 0.05 2.32 ± 0.01 7.61 ± 0.11 20.49 ± 0.26
scikit-learn 1.9.1 33.12 ± 6.69 7.31 ± 0.23 8.95 ± 0.07 5.72 ± 0.01 10.26 ± 0.03 13.67 ± 0.67
cakedev0 PRs 23+26 9.01 ± 0.22 2.35 ± 0.10 1.92 ± 0.04 1.06 ± 0.02 2.18 ± 0.01 3.01 ± 0.01
Torch XPU, native 4.45 ± 0.00 3.36 ± 0.01 2.98 ± 0.01 2.05 ± 0.01 4.02 ± 0.01 4.88 ± 0.03
Torch XPU, generic 3.22 ± 0.25 2.83 ± 0.43 2.78 ± 0.01 1.87 ± 0.01 4.07 ± 0.01 4.97 ± 0.01

Lloyd from the same random rows

implementation k3-d1000 k17-d180 k100-d32 k256-d128 k550-d6 k3000-d2
Torch CPU, native 4.55 ± 0.27 2.66 ± 0.01 1.69 ± 0.11 1.13 ± 0.00 1.92 ± 0.00 10.62 ± 0.38
Torch CPU, generic 4.33 ± 0.15 2.83 ± 0.16 2.34 ± 0.11 1.57 ± 0.06 3.37 ± 0.02 13.23 ± 0.96
scikit-learn 1.9.1 8.53 ± 0.19 1.80 ± 0.02 0.88 ± 0.00 0.47 ± 0.01 1.13 ± 0.00 1.59 ± 0.00
cakedev0 PRs 23+26 8.64 ± 0.22 1.80 ± 0.02 0.95 ± 0.01 0.46 ± 0.00 1.20 ± 0.01 1.63 ± 0.01
Torch XPU, native 4.18 ± 0.00 2.95 ± 0.00 2.24 ± 0.00 1.66 ± 0.00 2.68 ± 0.01 3.08 ± 0.01
Torch XPU, generic 3.15 ± 0.47 2.23 ± 0.15 2.05 ± 0.00 1.48 ± 0.00 2.73 ± 0.00 3.29 ± 0.01

Shared-start Lloyd removes the initializer. Stock scikit-learn and cakedev0 then agree: 8.53 s against 8.64 s at 3 clusters, 1.80 s against 1.80 s at 17, 0.88 s against 0.95 s at 100, 0.47 s against 0.46 s at 256, 1.13 s against 1.20 s at 550, and 1.59 s against 1.63 s at 3000. cakedev0's full-fit lead is the k-means++ work in PR 23. The chunked Lloyd kernel in PR 26 matches stock Lloyd on this host, as it did on the L4 host.

XPU Lloyd is fastest at 3 clusters (3.15 s with the one-hot update). From 17 clusters up the Cython Lloyd kernel is faster. At 3000 clusters native XPU takes 3.08 s and native Torch CPU takes 10.62 s, while both scikit-learn builds take about 1.6 s.

Quality and memory

Greedy inertias agree across the six implementations. On k3-d1000 every greedy mean is 998.867. On k256-d128 they sit between 118.919 and 118.930. On k3000-d2 every greedy mean is 0.0181 and every shared-start mean is 0.0248, 37% higher, for Torch, both scikit-learn builds, and both XPU updates together. That gap is the shared random-row start.

Peak memory above the input, greedy full fits:

implementation k3-d1000 k17-d180 k100-d32 k256-d128 k550-d6 k3000-d2
Torch CPU 944 MiB 2075 MiB 386 MiB 156 MiB 157 MiB 53 MiB
Torch XPU 939 MiB 2051 MiB 368 MiB 148 MiB 98 MiB 68 MiB
scikit-learn and cakedev0 7248 MiB 2884 MiB 366 MiB 147 MiB 59 MiB 16 MiB

The XPU figure is the device-allocator peak after the input copy. On this shared-memory GPU that copy also occupies system RAM; it is outside the timed region and outside the increment, same as the device-resident CUDA measurements. The 7.1 GiB scikit-learn peak on k3-d1000 matches the L4 host.

Conclusion

On this Arc B390 the portable one-hot update is the faster PyTorch XPU path through 256 clusters, and index_add_ is only a small win at 550 and 3000. The CUDA few-cluster cutoff would keep the slower update on k17-d180. With the one-hot update, XPU is the fastest full fit at 3 clusters (3.22 s). From 17 clusters up, cakedev0 is the fastest full fit, and the gap against stock scikit-learn is initialization. Cython Lloyd stays ahead of XPU Lloyd from 17 clusters up.

Previous: device-resident cuML on the original five tasks. Index: journal.