CCCL saxpy.cu demonstrates the principle: fused operations should minimize
wasted work. The saxpy_fast (single transform) vs saxpy_slow (two transforms)
comparison shows that eliminating unnecessary memory round-trips is the
primary optimization lever for element-wise ops.
Applied to MoE: during decode, M=8 (max-num-seqs) × topk=8 = 64 tokens.
Old heuristic: numel≤64 → BLOCK_SIZE_M=32 → 2 tiles of 32, no waste.
But for smaller batches (M=1,2,4 × topk=8 = 8,16,32 tokens):
BLOCK_SIZE_M=32 → tile padding: 24/16/0 rows wasted per tile
BLOCK_SIZE_M=16 → tile padding: 8/0/0 rows wasted per tile
New heuristic adds a finer-grained tier:
numel ≤ 16 → BLOCK_SIZE_M = 16 (zero waste for ≤2 seqs)
numel ≤ 64 → BLOCK_SIZE_M = 32 (was: same, no change)
numel ≤ 1024 → BLOCK_SIZE_M = 64 (was: same, no change)
else → BLOCK_SIZE_M = 256 (was: same, no change)
ixformer only reads BLOCK_SIZE_M from the config dict. The 16→32 threshold
matters for low-batch decode on BI-V100 where 16 SMs benefit from more
tiles with less padding over fewer tiles with more padding.
Source: cccl_upstream/thrust/examples/saxpy.cu (fusion + waste minimization)
Two findings from CCCL benchmarks applied to Triton autotune configs:
1. num_stages=2 (from transform bif=8 finding):
CCCL transform benchmark (babelstream.cu) search space includes
TUNE_BIF_BIAS from -16 to +16. BI-V100 bench found bif=8 (64KB
prefetch window) dominates across all problem sizes. Physical basis:
BW_per_SM × memory_latency = 56 GB/s × 1100ns ≈ 62KB
Triton's num_stages is the software pipelining equivalent of CCCL's
bytes_in_flight. num_stages=2 doubles the prefetch window from ~32KB
to ~64KB, matching the optimal BW×latency product.
2. Small-tile high-occupancy (from scan no_delay finding):
CCCL scan benchmark (sum.cu) found dcid=0 (no_delay) optimal on
BI-V100 because 16 SMs produce only ~32 CTAs, so the tile_status
array fits entirely in 6MB L2 with zero inter-CTA contention.
Implication: more smaller CTAs can saturate the 16 SMs better than
fewer large CTAs, especially for short sequences.
Added 3 new configs, all with num_stages=2 or waves_per_eu=4.
Triton autotune will select the fastest; no risk of regression.
Source: cccl_upstream/cub/benchmarks/bench/transform/babelstream.cu
cccl_upstream/cub/benchmarks/bench/scan/exclusive/sum.cu
bench_triton_prefill.py:
- Split --block into --block (BLOCK_M) and --block-n (BLOCK_N)
- Each (M, N, warps) combo triggers Triton JIT recompilation
- Enables finding asymmetric optima like M=64,N=32 that save SMEM
triton_flash_attention.py:
- Re-add 3 BI-V100 autotune configs (64x32, 32x64, 64x64 with warps=4)
- These were wrongly reverted in 8c1955d -- autotune is zero-risk
run_on_bi100.sh:
- Updated to use asymmetric block search