Fix TopK v2 fallback when 16-block cluster capacity is zero (#40163)
Co-authored-by: Hank Han <hanhan7630@outlook.com>
This commit is contained in:
@@ -328,7 +328,8 @@ TOPK_KERNEL void topk_main_kernel(const __grid_constant__ TopKPagedParams params
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SGL_TOPK_V2_MAX_C16_OCC1
|
#ifndef SGL_TOPK_V2_MAX_C16_OCC1
|
||||||
#define SGL_TOPK_V2_MAX_C16_OCC1 7
|
// Non-portable clusters require a positive device probe.
|
||||||
|
#define SGL_TOPK_V2_MAX_C16_OCC1 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr uint32_t kNumPersistentClusters = SGL_TOPK_V2_MAX_C8_OCC2;
|
constexpr uint32_t kNumPersistentClusters = SGL_TOPK_V2_MAX_C8_OCC2;
|
||||||
|
|||||||
@@ -10,7 +10,11 @@ from sglang.kernels.jit.utils.compile import load_jit
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from tvm_ffi.module import Module
|
from tvm_ffi.module import Module
|
||||||
|
|
||||||
__all__ = ["get_max_active_clusters"]
|
__all__ = ["NoSchedulableClustersError", "get_max_active_clusters"]
|
||||||
|
|
||||||
|
|
||||||
|
class NoSchedulableClustersError(ValueError):
|
||||||
|
"""The occupancy query succeeded, but no cluster fits the requested shape."""
|
||||||
|
|
||||||
|
|
||||||
@cache_once
|
@cache_once
|
||||||
@@ -36,11 +40,13 @@ def get_max_active_clusters(cluster_size: int, occupancy: int) -> int:
|
|||||||
dividing a GPC evenly. The probe kernel is pinned to ``occupancy`` blocks per
|
dividing a GPC evenly. The probe kernel is pinned to ``occupancy`` blocks per
|
||||||
SM, so pass the occupancy the real kernel reaches (its second
|
SM, so pass the occupancy the real kernel reaches (its second
|
||||||
``__launch_bounds__`` argument). Raises ``RuntimeError`` before sm90, which
|
``__launch_bounds__`` argument). Raises ``RuntimeError`` before sm90, which
|
||||||
has no clusters, and ``ValueError`` when nothing is schedulable.
|
has no clusters, and ``NoSchedulableClustersError`` (a ``ValueError``)
|
||||||
|
when the query succeeds but nothing is schedulable. Other probe errors
|
||||||
|
propagate to the caller.
|
||||||
"""
|
"""
|
||||||
result = _get_max_active_clusters(cluster_size, occupancy)
|
result = _get_max_active_clusters(cluster_size, occupancy)
|
||||||
if result == 0:
|
if result == 0:
|
||||||
raise ValueError(
|
raise NoSchedulableClustersError(
|
||||||
f"no cluster of {cluster_size} fits at occupancy {occupancy}; "
|
f"no cluster of {cluster_size} fits at occupancy {occupancy}; "
|
||||||
"the cluster width is likely beyond what this device supports"
|
"the cluster width is likely beyond what this device supports"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -29,27 +29,25 @@ def _jit_topk_v1_module():
|
|||||||
|
|
||||||
@cache_once
|
@cache_once
|
||||||
def _jit_topk_v2_module():
|
def _jit_topk_v2_module():
|
||||||
from sglang.kernels.jit.utils.occupancy import get_max_active_clusters
|
from sglang.kernels.jit.utils.occupancy import (
|
||||||
|
NoSchedulableClustersError,
|
||||||
|
get_max_active_clusters,
|
||||||
|
)
|
||||||
|
|
||||||
args = make_cpp_args(is_arch_support_pdl())
|
args = make_cpp_args(is_arch_support_pdl())
|
||||||
# Leave these undefined if the probe fails: topk_v2.cuh carries per-arch
|
# Enable each cluster path only when its occupancy probe reports capacity.
|
||||||
# defaults, and a 0 would size the persistent pool to an empty grid.
|
|
||||||
extra_cuda_cflags = []
|
extra_cuda_cflags = []
|
||||||
if is_arch_support_pdl(): # set the persistent cluster size after hopper
|
if is_arch_support_pdl(): # set the persistent cluster size after hopper
|
||||||
|
for cluster_size, occupancy in ((8, 2), (16, 1)):
|
||||||
try:
|
try:
|
||||||
occ_8_2 = get_max_active_clusters(8, occupancy=2)
|
max_active_clusters = get_max_active_clusters(
|
||||||
except Exception:
|
cluster_size, occupancy=occupancy
|
||||||
pass
|
)
|
||||||
else:
|
except NoSchedulableClustersError:
|
||||||
if occ_8_2 > 0:
|
max_active_clusters = 0
|
||||||
extra_cuda_cflags.append(f"-DSGL_TOPK_V2_MAX_C8_OCC2={occ_8_2}")
|
extra_cuda_cflags.append(
|
||||||
try:
|
f"-DSGL_TOPK_V2_MAX_C{cluster_size}_OCC{occupancy}={max_active_clusters}"
|
||||||
occ_16_1 = get_max_active_clusters(16, occupancy=1)
|
)
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
if occ_16_1 > 0:
|
|
||||||
extra_cuda_cflags.append(f"-DSGL_TOPK_V2_MAX_C16_OCC1={occ_16_1}")
|
|
||||||
kernel = f"TopKKernel<{args}>"
|
kernel = f"TopKKernel<{args}>"
|
||||||
return load_jit(
|
return load_jit(
|
||||||
make_name("topk_v2"),
|
make_name("topk_v2"),
|
||||||
|
|||||||
Reference in New Issue
Block a user