You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(gemm): unified gemm_num_sms SM-count cap for all frontier GEMMs
Add a single knob `SonicMoEConfig.gemm_num_sms` (env
`SONIC_MOE_GEMM_NUM_SMS`) that caps the number of SMs every frontier
CUTLASS-DSL persistent GEMM may occupy, mirroring DeepGEMM's
`set_num_sms`. Intended for compute/communication multi-stream overlap:
capping the GEMM leaves SMs free for a comm kernel on another stream.
Mechanism (new helper `quack_utils/sm_limit.py`), applied identically at
every frontier call site:
1. `capped_max_active_clusters` narrows the runtime-dynamic
max_active_clusters (SM budget -> cluster budget, floor div, min 1).
2. `clc_persistence_default` forces use_clc_persistence=False (STATIC
scheduler) whenever the cap is set. On Blackwell (SM100+) the default
CLC scheduler ignores max_active_clusters entirely (grid is always
the full problem grid), so the cap only bites under STATIC. This is a
compile-time constant, so `sm_cap_enabled()` is folded into every
compile key (only the STATIC-vs-CLC bool, not the SM count -- the
count only drives the runtime-dynamic grid, no recompile).
When gemm_num_sms is None, behavior is unchanged bit-for-bit (CLC path,
full grid). Covers: gemm_gated, gemm_dgated, the 3 gather_A+blockscaled
zeromat variants, the 7 blockscaled_fp8_gemm call sites, and
bf16_wgrad_gemm. SM90/Hopper is out of scope (no CLC; STATIC already
honors max_active_clusters there).
Verified on B300 (SM103, 148 SM, CUDA 13.2):
- All GEMM unit tests pass with cap off AND cap forced to 64 (grid-only
change, no reduction-order change -> numerics bit-identical).
- ncu (real knob): grid.z tracks the cap (none=CLC full / 112->56 /
64->32 / 32->16 clusters), SM_active% ~= residentCTA/148, per-SM
efficiency stays ~1.0 (near-linear -- this is a compute-bound GEMM, so
capping trades throughput ~linearly; the knob is for freeing SMs, not
a free lunch).
- Compile cache grows by exactly one STATIC entry when toggling cap on;
different non-None caps reuse the same STATIC compilation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0 commit comments