Split-K envelope sweeps, RTX 4060, 2026-10-14¶
Step 5 of the split-K resolution (splitk_tables.md) infers S = 1 for a shape that is not in the shipped table, when no live query is possible. At 8429385 it did so, without a warning, when MN was above the largest MN that split in the setting, or K was below the smallest K that split. The review of the release candidate (2026-10-14) asked whether cuBLASLt agrees. These sweeps ask it directly on the RTX 4060.
Method¶
- Query:
mmaemu.platform.cublaslt.heuristic, the cuBLASLt heuristic with torch 2.7.1's_scaled_mmdescriptor and the profile's workspace and alignment. No GEMM runs. - Settings: both table profiles,
ada-rtx4060-torch(1 MiB) andada-rtx4060-te(4 MiB, alignment 256). For each, every (out dtype, fast accumulation, format pair) that has split rows in the shipped table: 28 per profile, 56 in all. - Factor f = MN / (largest split MN of the setting in the shipped table). For each M and f, N is rounded up to a multiple of 16, so the real factor is slightly above f; every factor quoted below is the real one.
- Device: NVIDIA GeForce RTX 4060 (24 SMs), driver 570.211.01, torch 2.7.1+cu128, cuBLASLt 12.8.3.14 (the host of ../rtx4060-host/README.md).
- Code: on 2026-10-14 the scripts imported the review's work-in-progress tree. The parts they use
(
cublaslt.heuristic,SplitKTable.envelopeand the shipped table) return the same values as at 8429385. On 2026-10-15 they ran again, unchanged, on the tree of 49f1ecf: every per-query row was equal (../../2026-10-15/rtx-4060-sm89/README.md).
Results¶
Shapes above the largest split M*N:
| Script | M | f | K | Queries | Split (S > 1) | Largest factor that split |
|---|---|---|---|---|---|---|
sweep_env.py |
15 values, 16-8192 | 1.0-4.0 (step 0.1), 5, 6, 8, 12, 16 | 2,048-4,194,304 (6 values) | 181,440 | 1,419 | 1.208 |
sweep_env2.py |
16 values, 1-8192 | 1.00-2.00 (step 0.02), 2.25-4.0 (step 0.25) | 1,024-4,194,304 (13 values) | 663,936 | 8,292 | 1.271 |
sweep_env3.py |
16-1024 (step 16) | 1.25-2.0 (step 0.025) | 3,072-32,768 (6 values) | 666,624 | 274 | 1.271 |
| all | 1,512,000 | 9,985 | 1.271 |
- Shapes above the old envelope split in 52 of the 56 settings, at K from 3,072 to 4,194,304 (none at K = 1,024 or 2,048).
- No shape split above a factor of 1.271. The sweeps reach a factor of 17.0 in
sweep_env.pyand 5.2 insweep_env2.py.
Shapes with K below the smallest split K (sweep_env.py):
- 23 of the 56 settings have a smallest split K above 16 in the table: from 1,664 to 4,096.
- For those, the sweep ran K from 16 up to that value (step 16), with M in 16-256 and N in 16-1024, and MN at or below the largest split MN.
- Of 125,419 queries, 18,504 split, in 13 of the 23 settings. The smallest K that split was 1,760.
- The K rule therefore did not hold: the smallest split K of the table is a property of its K grid, not of cuBLASLt.
summary.json gives the counts and the largest factor that split for each setting and sweep.
Code change¶
mmaemu/platform/splitk_table.py now infers S = 1 only when MN is above ENVELOPE_MARGIN (2) times the setting's
largest split MN. K plays no part. The largest factor that split in these sweeps is 1.271.
- A shape that is not in the table and is not above that bound raises
SplitKUnknownError. Without the reference GPU, more shapes raise than before; on the RTX 4060 the live query (step 4) resolves them first. - The Evo 2 shapes resolve as before, to S = 1: from the table up to M = 8192, by the envelope above
(
tests/test_splitk_table.py::test_evo2_shapes_are_unsplit_and_never_raise). - The bound is a measurement, not a proof: it holds for this device, driver and cuBLASLt version on the shapes
queried. T3p (
tests/test_splitk_table.py::test_live_heuristic_never_splits_where_the_envelope_infers_s1) queries shapes at 2-4 times the largest split M*N of every setting live (11,760 queries) and requires S = 1.
Not kept¶
The per-query row files (sweep_env.json 30 MB, sweep_env2.json 61 MB, sweep_env3.json 61 MB) are not in the
repository. The scripts rebuild them on the reference GPU in under a minute each (19 s, 40 s and 42 s here).