main
py 119 lines 3.94 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import importlib
5 import importlib.util
6 import subprocess
7 import sys
8 from pathlib import Path
9 from types import ModuleType
10 from typing import Any
11
12 import pytest
13
14 from vllm.platforms import current_platform
15 from vllm.utils import import_utils
16
17
18 class _PassConfigKey:
19 TL_DISABLE_WARP_SPECIALIZED = "disable_warp_specialized"
20 TL_DISABLE_TMA_LOWER = "disable_tma_lower"
21 TL_PTXAS_REGISTER_USAGE_LEVEL = "ptxas_register_usage_level"
22
23
24 def _install_tilelang_stub(
25 monkeypatch: pytest.MonkeyPatch,
26 ) -> dict[str, int]:
27 calls = {"jit_decorate": 0, "compiled_call": 0, "compiled_compile": 0}
28
29 tilelang: Any = ModuleType("tilelang")
30
31 class _JitImpl:
32 def __init__(self, func: Any) -> None:
33 self.func = func
34
35 def __call__(self, *args: Any, **kw: Any) -> Any:
36 calls["compiled_call"] += 1
37 return self.func.__name__
38
39 def compile(self, *args: Any, **kw: Any) -> Any:
40 calls["compiled_compile"] += 1
41 return self.func.__name__
42
43 def jit(**kwargs: Any) -> Any:
44 def decorate(func: Any) -> Any:
45 calls["jit_decorate"] += 1
46 return _JitImpl(func)
47
48 return decorate
49
50 tilelang.PassConfigKey = _PassConfigKey
51 tilelang.jit = jit
52
53 monkeypatch.setattr(import_utils, "has_tilelang", lambda: True)
54 monkeypatch.setitem(sys.modules, "tilelang", tilelang)
55 monkeypatch.setitem(
56 sys.modules, "tilelang.language", ModuleType("tilelang.language")
57 )
58 monkeypatch.delitem(sys.modules, "vllm.tilelang_utils", raising=False)
59
60 return calls
61
62
63 def test_tilelang_jit_decorator_is_lazy_only_on_rocm(
64 monkeypatch: pytest.MonkeyPatch,
65 ) -> None:
66 if not (current_platform.is_cuda() or current_platform.is_rocm()):
67 pytest.skip("Test requires CUDA or ROCm")
68
69 calls = _install_tilelang_stub(monkeypatch)
70 module_name = "vllm.model_executor.kernels.mhc.tilelang_kernels"
71 monkeypatch.delitem(sys.modules, module_name, raising=False)
72 module = importlib.import_module(module_name)
73
74 if current_platform.is_rocm():
75 assert calls["jit_decorate"] == 0
76 else:
77 assert calls["jit_decorate"] > 0
78
79 decorated_calls = calls["jit_decorate"]
80 assert module.mhc_post_tilelang() == "mhc_post_tilelang"
81 if current_platform.is_rocm():
82 assert calls["jit_decorate"] == 1
83 else:
84 assert calls["jit_decorate"] == decorated_calls
85 assert calls["compiled_call"] == 1
86
87
88 @pytest.mark.skipif(not current_platform.is_rocm(), reason="Test requires ROCm")
89 def test_tilelang_jit_proxies_compile_only_warmup(
90 monkeypatch: pytest.MonkeyPatch,
91 ) -> None:
92 calls = _install_tilelang_stub(monkeypatch)
93 module_name = "vllm.model_executor.kernels.mhc.tilelang_kernels"
94 monkeypatch.delitem(sys.modules, module_name, raising=False)
95 module = importlib.import_module(module_name)
96
97 assert module.mhc_post_tilelang.compile() == "mhc_post_tilelang"
98 assert calls["jit_decorate"] == 1
99 assert calls["compiled_compile"] == 1
100 assert calls["compiled_call"] == 0
101
102
103 @pytest.mark.skipif(not current_platform.is_rocm(), reason="Test requires ROCm")
104 def test_deepseek_v4_import_and_jit_monitor_do_not_hijack_hip_symbols() -> None:
105 if importlib.util.find_spec("tilelang") is None:
106 pytest.skip("Test requires TileLang to be installed")
107
108 # Both claims are about process-global state, `sys.modules` and the symbol
109 # table, and a sibling test legitimately imports TileLang to exercise those
110 # kernels, so the checks only mean something in an interpreter of their own.
111 script = Path(__file__).parents[1] / "scripts" / "check_no_tilelang_hijack.py"
112 result = subprocess.run(
113 [sys.executable, str(script)],
114 capture_output=True,
115 text=True,
116 timeout=300,
117 )
118 if result.returncode != 0:
119 pytest.fail(f"HIP symbols were hijacked:\n{result.stdout}\n{result.stderr}")