[CI/Build] Add warning for unsupported global PTX architecture requests in... (#51901)

Shane Widanagama committed Aug 15, 2026 at 10:01 UTC d4801990a45792c7081652f8ebea4ee56ceb67f9
4 files changed +63 -5
CMakeLists.txt
+2 -1
@@ -222,7 +222,8 @@ if(VLLM_GPU_LANG STREQUAL "CUDA")
222 # `+PTX` in TORCH_CUDA_ARCH_LIST is not preserved here. If a kernel really
223 # needs PTX, add `+PTX` to that kernel's component-specific arch list below.
224 #
225 - clear_cuda_arches(CUDA_ARCH_FLAGS)
225 + clear_cuda_gencode_flags(CUDA_ARCH_FLAGS)
226 + warn_if_ptx_arch_requested("${CUDA_ARCH_FLAGS}")
227 extract_unique_cuda_archs_ascending(CUDA_ARCHS "${CUDA_ARCH_FLAGS}")
228 message(STATUS "CUDA target architectures: ${CUDA_ARCHS}")
229 # Filter the target architectures by the supported supported archs
cmake/utils.cmake
+22 -2
@@ -220,11 +220,11 @@ endmacro()
220 #
221 # Example:
222 # CMAKE_CUDA_FLAGS="-Wall -gencode arch=compute_70,code=sm_70 -gencode arch=compute_75,code=sm_75"
223 -# clear_cuda_arches(CUDA_ARCH_FLAGS)
223 +# clear_cuda_gencode_flags(CUDA_ARCH_FLAGS)
224 # CUDA_ARCH_FLAGS="-gencode arch=compute_70,code=sm_70;-gencode arch=compute_75,code=sm_75"
225 # CMAKE_CUDA_FLAGS="-Wall"
226 #
227 -macro(clear_cuda_arches CUDA_ARCH_FLAGS)
227 +macro(clear_cuda_gencode_flags CUDA_ARCH_FLAGS)
228 # Extract all `-gencode` flags from `CMAKE_CUDA_FLAGS`
229 string(REGEX MATCHALL "-gencode arch=[^ ]+" CUDA_ARCH_FLAGS
230 ${CMAKE_CUDA_FLAGS})
@@ -235,6 +235,26 @@ macro(clear_cuda_arches CUDA_ARCH_FLAGS)
235 ${CMAKE_CUDA_FLAGS})
236 endmacro()
237
238 +#
239 +# Warn when a caller requested PTX code generation through global CUDA arch
240 +# flags. vLLM removes those flags and reapplies per-source gencode flags, so the
241 +# user's global PTX request will not be preserved.
242 +#
243 +function(warn_if_ptx_arch_requested CUDA_ARCH_FLAGS)
244 + foreach(_ARCH_FLAG ${CUDA_ARCH_FLAGS})
245 + if(_ARCH_FLAG MATCHES "code=.*compute_[0-9]+[af]?")
246 + message(WARNING
247 + "PTX code generation requested in CUDA architecture flags "
248 + "(${_ARCH_FLAG}), but vLLM does not preserve global PTX requests "
249 + "when normalizing per-source CUDA architectures. Remove '+PTX' from "
250 + "TORCH_CUDA_ARCH_LIST or rely on vLLM's built-in per-kernel PTX "
251 + "selection.")
252 + return()
253 + endif()
254 + endforeach()
255 +endfunction()
256 +
257 +
258 #
259 # Extract unique CUDA architectures from a list of compute capabilities codes in
260 # the form `<major><minor>[<letter>]`, convert them to the form sort
docs/getting_started/installation/gpu.cuda.inc.md
+3
@@ -156,6 +156,9 @@ cd vllm
156 uv pip install -e . --torch-backend=auto
157 ```
158
159 +!!! note "CUDA Architecture & PTX Flags"
160 + vLLM normalizes CUDA architectures on a per-source basis to optimize build times and wheel sizes. Global `+PTX` requests in `TORCH_CUDA_ARCH_LIST` (e.g., `TORCH_CUDA_ARCH_LIST="8.0+PTX"`) are ignored for general extension targets; vLLM generates PTX only for specific internal kernels that require it.
161 +
162 !!! tip
163 Building from source requires a lot of compilation. If you are building from source repeatedly, it's more efficient to cache the compilation results.
164
tests/test_cmake_utils.py
+36 -2
@@ -1,10 +1,22 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 +import shutil
5 import subprocess
6 +import sys
7 from pathlib import Path
8
9
10 +def _get_cmake_bin() -> str:
11 + cmake = shutil.which("cmake")
12 + if cmake:
13 + return cmake
14 + venv_cmake = Path(sys.executable).parent / "cmake"
15 + if venv_cmake.is_file():
16 + return str(venv_cmake)
17 + return "cmake"
18 +
19 +
20 def test_exact_family_arch_precedes_generic_family_fallback(tmp_path: Path):
21 repo_root = Path(__file__).parents[1]
22 script = tmp_path / "test_cuda_archs.cmake"
@@ -20,7 +32,7 @@ endif()
32 """
33 )
34
23 - subprocess.run(["cmake", "-P", script], check=True)
35 + subprocess.run([_get_cmake_bin(), "-P", script], check=True)
36
37
38 def test_extract_archs_prefers_sass_target_over_corrupted_virtual_arch(
@@ -45,4 +57,26 @@ endif()
57 """
58 )
59
48 - subprocess.run(["cmake", "-P", script], check=True)
60 + subprocess.run([_get_cmake_bin(), "-P", script], check=True)
61 +
62 +
63 +def test_clear_cuda_gencode_flags(tmp_path: Path):
64 + repo_root = Path(__file__).parents[1]
65 + script = tmp_path / "test_clear_flags.cmake"
66 + script.write_text(
67 + f"""
68 +cmake_minimum_required(VERSION 3.26)
69 +include("{repo_root / "cmake" / "utils.cmake"}")
70 +set(CMAKE_CUDA_FLAGS "-Wall -gencode arch=compute_80,code=sm_80")
71 +clear_cuda_gencode_flags(CUDA_ARCH_FLAGS)
72 +if(NOT "${{CMAKE_CUDA_FLAGS}}" STREQUAL "-Wall ")
73 + message(FATAL_ERROR "Expected '-Wall ', got '${{CMAKE_CUDA_FLAGS}}'")
74 +endif()
75 +if(NOT "${{CUDA_ARCH_FLAGS}}" STREQUAL "-gencode arch=compute_80,code=sm_80")
76 + message(FATAL_ERROR "Expected '-gencode arch=compute_80,code=sm_80', "
77 + "got '${{CUDA_ARCH_FLAGS}}'")
78 +endif()
79 +"""
80 + )
81 +
82 + subprocess.run([_get_cmake_bin(), "-P", script], check=True)