- 6accumulator types the pairwise kernels declare
- ≈8 KBof shared memory per block for a tile pair
- 1atomic per tile into the cluster totals
One tile shape for every quadratic metric
Half of my cluster metrics are quadratic: they need every pair of members. The tiled pairwise machinery in the Inference Fabric's CUDA engine makes those metrics exact at a hundred thousand members with bounded memory, and it is the step that let me take every sampling cap out of the metrics in Removing the sampling caps.
The cluster is cut into tiles of sixteen rows by sixty-four, and the grid is flattened so one block owns one tile pair. Diagonal tiles visit each pair once over the upper triangle, rectangular tiles visit the full cross product, and a tile prefix sum maps a flat block index back to its cluster and tile pair without a search. The vectors for a tile pair are loaded into shared memory, and the loop runs with the dimension on the outside and the pair on the inside, so every thread reaches every barrier by construction and no thread stalls on a divergent exit.
The tile loader, the pair-index decoder for diagonal and rectangular tiles and multi-tile processing each have their own CUDA tests.
Accumulators as declared types
The pairwise, diversity, silhouette and entanglement kernels share that machinery, so each of them is a short declaration of what it accumulates. The accumulator is a type, and adding a pairwise metric is adding an accumulator.
Recompute, never store
Where a metric needs the cluster's distance range before it can bin, as entropy does, the kernel runs two tiled passes and recomputes the distances in the second rather than storing them.
Five billion distances do not fit, and a second sweep is cheap.