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
derive TBE cache associativity from device warp size (#6037)
Summary:
X-link: facebookresearch/FBGEMM#2940
The TBE LRU/LFU/LXU cache hardcoded associativity (ways per set) to 64 on ROCm (`DEFAULT_ASSOC`) and guarded the populate/lookup kernels with `TORCH_CHECK(warp_size() == 64)`, refusing to run on wave32 ROCm devices. Cache associativity must equal the device warp size because one warp cooperatively scans the ways of a single set. The cache kernels are not templated on warp size: device code uses the per-arch `kWarpSize` constant for row indexing, so a multi-arch fat binary already contains correct per-arch device code. Only the host-allocated cache geometry was wrong.
Derive per-instance associativity from the running device (`torch.cuda.get_device_properties(dev).warp_size`) in the training and nbit inference modules, so cache-state tensors match the device kernel's per-arch indexing, and remove the wave64-only `TORCH_CHECK` guards. `DEFAULT_ASSOC` stays as the CPU/no-device fallback. Host-side cache kernel launch configs move to `kWarpSizeHost()`. The cache tests query the device warp size instead of assuming `DEFAULT_ASSOC`, and `lxu_cache_test` now also covers the direct-mapped (associativity 1) path.
Because `DEFAULT_ASSOC` no longer equals the device warp size on ROCm, `cache_test.py`'s `test_lru_cache_insert_large_grid` (which drives the low-level `lru_cache_populate` op directly and must allocate cache geometry matching the kernel's `kWarpSize` row stride) is updated to query the device warp size. Left unchanged it allocates a 32-wide cache on a wave64 device and the kernel, striding by 64, leaves half the slots unpopulated.
One deviation from the combined change (#5804): in `ssd_cache_actions_insert_kernel`, the flat cache-slot index (`cache_set * kWarpSize + insert_slot`) and the conflict-miss stride are `__device__` code and must use the per-arch device constant `kWarpSize`. #5804 changed these to `kWarpSizeHost()`, which calls `at::cuda::warp_size()` -- a host-only function not callable from device code. It is masked on single-arch builds only because `kWarpSizeHost() == kWarpSize` there. These sites are kept as `kWarpSize`; only the host-side launch configs in that file use `kWarpSizeHost()`.
Third in the chain splitting #5804 into reviewable pieces; stacked on #6031.
Authored with assistance from Claude (Anthropic).
Reviewed By: henrylhtsang
Differential Revision: D112940757
Pulled By: q10
0 commit comments