@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 6c1f9e4c18
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 9, 07:30 UTC

[Kernel] [Helion] [1/N] Add Helion ConfigManager (#32740)

Signed-off-by: Yanan Cao <gmagogsfm@gmail.com>

Yanan Cao committed Jan 30, 2026 at 09:19 UTC 6c1f9e4c1877cb5cb6a702f5813e606eaba35600
4 files changed +608
tests/kernels/helion/test_config_manager.py new
+361
@@ -0,0 +1,361 @@
1 +# SPDX-License-Identifier: Apache-2.0
2 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +"""
4 +Unit tests for Helion ConfigManager and ConfigSet.
5 +
6 +Tests the simplified configuration management system for Helion custom kernels.
7 +"""
8 +
9 +import json
10 +import tempfile
11 +from pathlib import Path
12 +
13 +import pytest
14 +
15 +from vllm.utils.import_utils import has_helion
16 +
17 +# Skip entire module if helion is not available
18 +if not has_helion():
19 + pytest.skip(
20 + "Helion is not installed. Install with: pip install vllm[helion]",
21 + allow_module_level=True,
22 + )
23 +
24 +import helion
25 +
26 +from vllm.kernels.helion.config_manager import (
27 + ConfigManager,
28 + ConfigSet,
29 +)
30 +
31 +
32 +@pytest.fixture(autouse=True)
33 +def reset_config_manager_singleton():
34 + """Reset ConfigManager singleton before each test."""
35 + ConfigManager.reset_instance()
36 + yield
37 + ConfigManager.reset_instance()
38 +
39 +
40 +class TestConfigSet:
41 + """Test suite for ConfigSet class."""
42 +
43 + def test_config_set_creation(self):
44 + """Test creating an empty ConfigSet."""
45 + config_set = ConfigSet("test_kernel")
46 +
47 + assert config_set.kernel_name == "test_kernel"
48 + assert config_set.get_platforms() == []
49 +
50 + def test_config_set_from_dict(self):
51 + """Test creating ConfigSet from dictionary data."""
52 + # Use realistic config data that helion.Config can handle
53 + config_data = {
54 + "block_sizes": [32, 16],
55 + "num_warps": 4,
56 + "num_stages": 3,
57 + "pid_type": "persistent_interleaved",
58 + }
59 + data = {"h100": {"batch_32_hidden_4096": config_data}}
60 +
61 + config_set = ConfigSet.from_dict("test_kernel", data)
62 +
63 + assert config_set.kernel_name == "test_kernel"
64 + assert config_set.get_platforms() == ["h100"]
65 +
66 + # Verify the config was created correctly
67 + config = config_set.get_config("h100", "batch_32_hidden_4096")
68 + assert isinstance(config, helion.Config)
69 + assert config.block_sizes == [32, 16]
70 + assert config.num_warps == 4
71 + assert config.num_stages == 3
72 + assert config.pid_type == "persistent_interleaved"
73 +
74 + def test_config_set_get_config_keyerror(self):
75 + """Test that accessing non-existent configs raises informative KeyErrors."""
76 + config_set = ConfigSet("test_kernel")
77 +
78 + with pytest.raises(KeyError, match="platform 'h100' not found"):
79 + config_set.get_config("h100", "batch_32_hidden_4096")
80 +
81 + # Use realistic config data
82 + config_data = {"num_warps": 8, "num_stages": 4}
83 + data = {"h100": {"batch_64_hidden_2048": config_data}}
84 + config_set = ConfigSet.from_dict("test_kernel", data)
85 +
86 + with pytest.raises(
87 + KeyError, match="config_key 'batch_32_hidden_4096' not found"
88 + ):
89 + config_set.get_config("h100", "batch_32_hidden_4096")
90 +
91 + def test_config_set_get_platforms(self):
92 + """Test get_platforms method."""
93 + # Use realistic config data
94 + config1 = {"num_warps": 4, "num_stages": 3}
95 + config2 = {"num_warps": 8, "num_stages": 5}
96 +
97 + data = {
98 + "h100": {"batch_32_hidden_4096": config1},
99 + "a100": {"batch_16_hidden_2048": config2},
100 + }
101 + config_set = ConfigSet.from_dict("test_kernel", data)
102 +
103 + platforms = config_set.get_platforms()
104 + assert platforms == ["a100", "h100"] # Should be sorted
105 +
106 + def test_config_set_get_config_keys(self):
107 + """Test get_config_keys method."""
108 + # Use realistic config data
109 + config1 = {"num_warps": 4, "num_stages": 3}
110 + config2 = {"num_warps": 8, "num_stages": 5}
111 +
112 + data = {
113 + "h100": {
114 + "batch_32_hidden_4096": config1,
115 + "batch_64_hidden_2048": config2,
116 + }
117 + }
118 + config_set = ConfigSet.from_dict("test_kernel", data)
119 +
120 + config_keys = config_set.get_config_keys("h100")
121 + assert config_keys == ["batch_32_hidden_4096", "batch_64_hidden_2048"]
122 +
123 + assert config_set.get_config_keys("v100") == []
124 +
125 + def test_config_set_to_dict(self):
126 + """Test converting ConfigSet to dictionary."""
127 + # Use realistic config data
128 + original_config = {
129 + "block_sizes": [64, 32],
130 + "num_warps": 16,
131 + "num_stages": 4,
132 + "pid_type": "persistent_blocked",
133 + }
134 + original_data = {"h100": {"batch_32_hidden_4096": original_config}}
135 +
136 + config_set = ConfigSet.from_dict("test_kernel", original_data)
137 + result_data = config_set.to_dict()
138 +
139 + # The result should match the original (Config roundtrip should work)
140 + assert result_data == original_data
141 +
142 +
143 +class TestConfigManager:
144 + """Test suite for ConfigManager class."""
145 +
146 + def test_config_manager_creation_default_base_dir(self):
147 + """Test creating ConfigManager with default base directory."""
148 + manager = ConfigManager()
149 + assert manager._base_dir.name == "configs"
150 +
151 + def test_config_manager_creation_custom_base_dir(self):
152 + """Test creating ConfigManager with custom base directory."""
153 + custom_dir = "/tmp/custom_configs"
154 + manager = ConfigManager(base_dir=custom_dir)
155 +
156 + # Paths are resolved, so compare with resolved path
157 + assert manager._base_dir == Path(custom_dir).resolve()
158 +
159 + def test_get_config_file_path(self):
160 + """Test getting config file path for a kernel."""
161 + manager = ConfigManager(base_dir="/tmp")
162 +
163 + file_path = manager.get_config_file_path("silu_mul_fp8")
164 +
165 + expected_path = Path("/tmp/silu_mul_fp8.json")
166 + assert file_path == expected_path
167 +
168 + def test_ensure_base_dir_exists(self):
169 + """Test ensuring base directory exists."""
170 + with tempfile.TemporaryDirectory() as temp_dir:
171 + base_dir = Path(temp_dir) / "non_existent" / "configs"
172 + manager = ConfigManager(base_dir=base_dir)
173 + assert not base_dir.exists()
174 +
175 + returned_path = manager.ensure_base_dir_exists()
176 +
177 + assert base_dir.exists()
178 + assert base_dir.is_dir()
179 + assert returned_path == base_dir
180 +
181 + def test_load_config_set_file_not_exists(self):
182 + """Test loading config set when file doesn't exist."""
183 + with tempfile.TemporaryDirectory() as temp_dir:
184 + manager = ConfigManager(base_dir=temp_dir)
185 + config_set = manager.load_config_set("non_existent_kernel")
186 +
187 + assert isinstance(config_set, ConfigSet)
188 + assert config_set.kernel_name == "non_existent_kernel"
189 + assert config_set.get_platforms() == []
190 +
191 + def test_load_config_set_valid_file(self):
192 + """Test loading config set from valid file."""
193 + with tempfile.TemporaryDirectory() as temp_dir:
194 + # Use realistic config data
195 + kernel_config = {
196 + "block_sizes": [128, 64],
197 + "num_warps": 8,
198 + "num_stages": 6,
199 + "pid_type": "persistent_interleaved",
200 + }
201 + config_data = {"h100": {"batch_32_hidden_4096": kernel_config}}
202 + config_file = Path(temp_dir) / "test_kernel.json"
203 + with open(config_file, "w") as f:
204 + json.dump(config_data, f)
205 +
206 + manager = ConfigManager(base_dir=temp_dir)
207 + config_set = manager.load_config_set("test_kernel")
208 +
209 + assert isinstance(config_set, ConfigSet)
210 + assert config_set.kernel_name == "test_kernel"
211 + assert config_set.get_platforms() == ["h100"]
212 +
213 + # Verify the config was loaded correctly
214 + config = config_set.get_config("h100", "batch_32_hidden_4096")
215 + assert isinstance(config, helion.Config)
216 + assert config.block_sizes == [128, 64]
217 + assert config.num_warps == 8
218 +
219 + def test_load_config_set_invalid_json(self):
220 + """Test loading config set from file with invalid JSON."""
221 + with tempfile.TemporaryDirectory() as temp_dir:
222 + config_file = Path(temp_dir) / "test_kernel.json"
223 + with open(config_file, "w") as f:
224 + f.write("invalid json content {")
225 +
226 + manager = ConfigManager(base_dir=temp_dir)
227 + config_set = manager.load_config_set("test_kernel")
228 +
229 + assert isinstance(config_set, ConfigSet)
230 + assert config_set.kernel_name == "test_kernel"
231 + assert config_set.get_platforms() == []
232 +
233 + def test_save_config_set(self):
234 + """Test saving ConfigSet to file."""
235 + with tempfile.TemporaryDirectory() as temp_dir:
236 + # Use realistic config data
237 + kernel_config = {
238 + "block_sizes": [256, 128],
239 + "num_warps": 16,
240 + "num_stages": 8,
241 + "pid_type": "persistent_blocked",
242 + }
243 + data = {"h100": {"batch_32_hidden_4096": kernel_config}}
244 + config_set = ConfigSet.from_dict("test_kernel", data)
245 +
246 + manager = ConfigManager(base_dir=temp_dir)
247 + saved_path = manager.save_config_set(config_set)
248 +
249 + expected_path = Path(temp_dir) / "test_kernel.json"
250 + assert saved_path == expected_path
251 + assert saved_path.exists()
252 +
253 + with open(saved_path) as f:
254 + loaded_data = json.load(f)
255 + assert loaded_data == data
256 +
257 + def test_save_config_set_creates_directory(self):
258 + """Test that save_config_set creates parent directories if needed."""
259 + with tempfile.TemporaryDirectory() as temp_dir:
260 + nested_dir = Path(temp_dir) / "nested" / "configs"
261 + config_set = ConfigSet("test_kernel")
262 +
263 + manager = ConfigManager(base_dir=nested_dir)
264 + saved_path = manager.save_config_set(config_set)
265 +
266 + assert nested_dir.exists()
267 + assert nested_dir.is_dir()
268 + assert saved_path.exists()
269 +
270 + def test_get_platform_configs(self):
271 + """Test getting all configs for a specific platform."""
272 + with tempfile.TemporaryDirectory() as temp_dir:
273 + # Use realistic config data
274 + config_1 = {"num_warps": 4, "num_stages": 3, "block_sizes": [64, 32]}
275 + config_2 = {"num_warps": 8, "num_stages": 5, "block_sizes": [128, 64]}
276 + default_config = {
277 + "num_warps": 16,
278 + "num_stages": 7,
279 + "block_sizes": [256, 128],
280 + }
281 + config_3 = {"num_warps": 2, "num_stages": 2, "block_sizes": [32, 16]}
282 +
283 + config_data = {
284 + "h100": {
285 + "batch_32_hidden_4096": config_1,
286 + "batch_64_hidden_2048": config_2,
287 + "default": default_config,
288 + },
289 + "a100": {"batch_16_hidden_1024": config_3},
290 + }
291 + config_file = Path(temp_dir) / "test_kernel.json"
292 + with open(config_file, "w") as f:
293 + json.dump(config_data, f)
294 +
295 + manager = ConfigManager(base_dir=temp_dir)
296 +
297 + h100_configs = manager.get_platform_configs("test_kernel", "h100")
298 + assert len(h100_configs) == 3
299 + assert "batch_32_hidden_4096" in h100_configs
300 + assert "batch_64_hidden_2048" in h100_configs
301 + assert "default" in h100_configs
302 + for config in h100_configs.values():
303 + assert isinstance(config, helion.Config)
304 +
305 + # Verify specific config details
306 + assert h100_configs["batch_32_hidden_4096"].num_warps == 4
307 + assert h100_configs["default"].num_stages == 7
308 +
309 + a100_configs = manager.get_platform_configs("test_kernel", "a100")
310 + assert len(a100_configs) == 1
311 + assert "batch_16_hidden_1024" in a100_configs
312 + assert isinstance(a100_configs["batch_16_hidden_1024"], helion.Config)
313 + assert a100_configs["batch_16_hidden_1024"].num_warps == 2
314 +
315 + nonexistent_configs = manager.get_platform_configs("test_kernel", "v100")
316 + assert len(nonexistent_configs) == 0
317 +
318 + def test_singleton_returns_same_instance(self):
319 + """Test that ConfigManager returns the same instance on repeated calls."""
320 + manager1 = ConfigManager(base_dir="/tmp/test_singleton")
321 + manager2 = ConfigManager(base_dir="/tmp/test_singleton")
322 +
323 + assert manager1 is manager2
324 +
325 + def test_singleton_with_default_base_dir(self):
326 + """Test singleton behavior with default base directory."""
327 + manager1 = ConfigManager()
328 + manager2 = ConfigManager()
329 +
330 + assert manager1 is manager2
331 + assert manager1._base_dir == manager2._base_dir
332 +
333 + def test_singleton_error_on_different_base_dir(self):
334 + """Test that ConfigManager raises error when created with different base_dir."""
335 + ConfigManager(base_dir="/tmp/first_dir")
336 +
337 + with pytest.raises(ValueError, match="singleton already exists"):
338 + ConfigManager(base_dir="/tmp/different_dir")
339 +
340 + def test_reset_instance_allows_new_base_dir(self):
341 + """Test that reset_instance allows creating with a new base_dir."""
342 + manager1 = ConfigManager(base_dir="/tmp/first_dir")
343 + assert manager1._base_dir == Path("/tmp/first_dir").resolve()
344 +
345 + ConfigManager.reset_instance()
346 +
347 + manager2 = ConfigManager(base_dir="/tmp/second_dir")
348 + assert manager2._base_dir == Path("/tmp/second_dir").resolve()
349 + assert manager1 is not manager2
350 +
351 + def test_get_instance_returns_existing(self):
352 + """Test that get_instance returns the existing singleton."""
353 + manager1 = ConfigManager(base_dir="/tmp/test_get_instance")
354 + manager2 = ConfigManager.get_instance()
355 +
356 + assert manager1 is manager2
357 +
358 + def test_get_instance_raises_if_not_initialized(self):
359 + """Test that get_instance raises RuntimeError if no instance exists."""
360 + with pytest.raises(RuntimeError, match="has not been created"):
361 + ConfigManager.get_instance()
vllm/kernels/__init__.py new
+3
@@ -0,0 +1,3 @@
1 +# SPDX-License-Identifier: Apache-2.0
2 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +"""Kernel implementations for vLLM."""
vllm/kernels/helion/__init__.py new
+13
@@ -0,0 +1,13 @@
1 +# SPDX-License-Identifier: Apache-2.0
2 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +"""Helion integration for vLLM."""
4 +
5 +from vllm.kernels.helion.config_manager import (
6 + ConfigManager,
7 + ConfigSet,
8 +)
9 +
10 +__all__ = [
11 + "ConfigManager",
12 + "ConfigSet",
13 +]
vllm/kernels/helion/config_manager.py new
+231
@@ -0,0 +1,231 @@
1 +# SPDX-License-Identifier: Apache-2.0
2 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +"""
4 +Configuration management for Helion kernels.
5 +
6 +This module provides centralized configuration file management for Helion custom
7 +operations, including naming conventions, directory resolution, and file I/O.
8 +
9 +Config File Structure
10 +---------------------
11 +Each kernel has a single JSON config file: {kernel_name}.json
12 +
13 +The file uses a simplified 2-layer hierarchical structure:
14 +{
15 + "h100": { # GPU platform
16 + "default": { ... }, # Fallback configuration
17 + "batch_32_hidden_4096": { ... },
18 + "batch_64_hidden_8192": { ... }
19 + },
20 + "a100": {
21 + "default": { ... },
22 + "batch_16_hidden_2048": { ... }
23 + }
24 +}
25 +
26 +Example file: silu_mul_fp8.json
27 +
28 +Config keys should be structured strings that encode the relevant
29 +parameters (e.g., "batch_32_hidden_4096", "seq_512_heads_16", "fp8_batch_64", etc.).
30 +
31 +Classes
32 +-------
33 +- ConfigSet: In-memory collection of configs for a kernel with lookup/query APIs.
34 +- ConfigManager: File-level operations for config persistence.
35 +"""
36 +
37 +import json
38 +from pathlib import Path
39 +from typing import Any
40 +
41 +from vllm.logger import init_logger
42 +from vllm.utils.import_utils import has_helion
43 +
44 +if not has_helion():
45 + raise ImportError(
46 + "ConfigManager requires helion to be installed. "
47 + "Install it with: pip install helion"
48 + )
49 +
50 +import helion
51 +
52 +logger = init_logger(__name__)
53 +
54 +
55 +class ConfigSet:
56 + """In-memory collection of Helion configs with lookup/query capabilities."""
57 +
58 + # Type alias for nested config structure:
59 + # platform -> config_key -> helion.Config
60 + _ConfigDict = dict[str, dict[str, "helion.Config"]]
61 +
62 + def __init__(self, kernel_name: str):
63 + self._kernel_name = kernel_name
64 + self._configs: ConfigSet._ConfigDict = {}
65 +
66 + @property
67 + def kernel_name(self) -> str:
68 + return self._kernel_name
69 +
70 + def get_config(self, platform: str, config_key: str) -> helion.Config:
71 + platform_dict = self._configs.get(platform)
72 + if platform_dict is None:
73 + avail_platforms = self.get_platforms()
74 + raise KeyError(
75 + f"Config not found for kernel '{self._kernel_name}': "
76 + f"platform '{platform}' not found. "
77 + f"Available platforms: {avail_platforms or '(none)'}"
78 + )
79 +
80 + config = platform_dict.get(config_key)
81 + if config is None:
82 + avail_keys = self.get_config_keys(platform)
83 + raise KeyError(
84 + f"Config not found for kernel '{self._kernel_name}': "
85 + f"config_key '{config_key}' not found for platform '{platform}'. "
86 + f"Available config_keys: {avail_keys or '(none)'}"
87 + )
88 +
89 + return config
90 +
91 + def get_platforms(self) -> list[str]:
92 + return sorted(self._configs.keys())
93 +
94 + def get_config_keys(self, platform: str) -> list[str]:
95 + platform_dict = self._configs.get(platform.lower())
96 + if platform_dict is None:
97 + return []
98 + return sorted(platform_dict.keys())
99 +
100 + def to_dict(self) -> dict[str, Any]:
101 + result: dict[str, Any] = {}
102 +
103 + for platform, config_keys_dict in self._configs.items():
104 + result[platform] = {}
105 +
106 + for config_key, config in config_keys_dict.items():
107 + # Convert helion.Config to dict using to_json() + json.loads()
108 + import json
109 +
110 + result[platform][config_key] = json.loads(config.to_json())
111 +
112 + return result
113 +
114 + @classmethod
115 + def from_dict(cls, kernel_name: str, data: dict[str, Any]) -> "ConfigSet":
116 + config_set = cls(kernel_name)
117 + count = 0
118 +
119 + for platform, platform_data in data.items():
120 + if platform not in config_set._configs:
121 + config_set._configs[platform] = {}
122 +
123 + for config_key, config_data in platform_data.items():
124 + config = helion.Config(**config_data)
125 + config_set._configs[platform][config_key] = config
126 + count += 1
127 +
128 + if count > 0:
129 + logger.debug(
130 + "Loaded %d configs for kernel '%s'",
131 + count,
132 + kernel_name,
133 + )
134 +
135 + return config_set
136 +
137 +
138 +class ConfigManager:
139 + """File-level configuration management for Helion kernels (global singleton)."""
140 +
141 + _instance: "ConfigManager | None" = None
142 + _instance_base_dir: Path | None = None
143 +
144 + def __new__(cls, base_dir: str | Path | None = None) -> "ConfigManager":
145 + resolved_base_dir = cls._resolve_base_dir(base_dir)
146 +
147 + if cls._instance is not None:
148 + # Instance already exists - check for base_dir mismatch
149 + if cls._instance_base_dir != resolved_base_dir:
150 + raise ValueError(
151 + f"ConfigManager singleton already exists with base_dir "
152 + f"'{cls._instance_base_dir}', cannot create with different "
153 + f"base_dir '{resolved_base_dir}'"
154 + )
155 + return cls._instance
156 +
157 + # Create new instance
158 + instance = super().__new__(cls)
159 + cls._instance = instance
160 + cls._instance_base_dir = resolved_base_dir
161 + return instance
162 +
163 + def __init__(self, base_dir: str | Path | None = None):
164 + # Only initialize if not already initialized
165 + if hasattr(self, "_base_dir"):
166 + return
167 +
168 + self._base_dir = self._resolve_base_dir(base_dir)
169 + logger.debug("ConfigManager initialized with base_dir: %s", self._base_dir)
170 +
171 + @staticmethod
172 + def _resolve_base_dir(base_dir: str | Path | None) -> Path:
173 + if base_dir is not None:
174 + return Path(base_dir).resolve()
175 + return (Path(__file__).parent / "configs").resolve()
176 +
177 + @classmethod
178 + def get_instance(cls) -> "ConfigManager":
179 + if cls._instance is None:
180 + raise RuntimeError(
181 + "ConfigManager instance has not been created. "
182 + "Call ConfigManager(base_dir=...) first to initialize."
183 + )
184 + return cls._instance
185 +
186 + @classmethod
187 + def reset_instance(cls) -> None:
188 + """For testing purposes only."""
189 + cls._instance = None
190 + cls._instance_base_dir = None
191 +
192 + def get_config_file_path(self, kernel_name: str) -> Path:
193 + return self._base_dir / f"{kernel_name}.json"
194 +
195 + def ensure_base_dir_exists(self) -> Path:
196 + self._base_dir.mkdir(parents=True, exist_ok=True)
197 + return self._base_dir
198 +
199 + def load_config_set(self, kernel_name: str) -> ConfigSet:
200 + config_path = self.get_config_file_path(kernel_name)
201 + if not config_path.exists():
202 + return ConfigSet.from_dict(kernel_name, {})
203 +
204 + try:
205 + with open(config_path) as f:
206 + data = json.load(f)
207 + return ConfigSet.from_dict(kernel_name, data)
208 + except (json.JSONDecodeError, OSError) as e:
209 + logger.error("Failed to load config file %s: %s", config_path, e)
210 + return ConfigSet.from_dict(kernel_name, {})
211 +
212 + def get_platform_configs(
213 + self, kernel_name: str, platform: str
214 + ) -> dict[str, helion.Config]:
215 + config_set = self.load_config_set(kernel_name)
216 + config_keys = config_set.get_config_keys(platform)
217 +
218 + return {
219 + config_key: config_set.get_config(platform, config_key)
220 + for config_key in config_keys
221 + }
222 +
223 + def save_config_set(self, config_set: ConfigSet) -> Path:
224 + config_path = self.get_config_file_path(config_set.kernel_name)
225 + config_path.parent.mkdir(parents=True, exist_ok=True)
226 +
227 + with open(config_path, "w") as f:
228 + json.dump(config_set.to_dict(), f, indent=2)
229 +
230 + logger.info("Saved config to: %s", config_path)
231 + return config_path