Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ if(VLLM_GPU_LANG STREQUAL "CUDA")
# `+PTX` in TORCH_CUDA_ARCH_LIST is not preserved here. If a kernel really
# needs PTX, add `+PTX` to that kernel's component-specific arch list below.
#
clear_cuda_arches(CUDA_ARCH_FLAGS)
clear_cuda_gencode_flags(CUDA_ARCH_FLAGS)
warn_if_ptx_arch_requested("${CUDA_ARCH_FLAGS}")
extract_unique_cuda_archs_ascending(CUDA_ARCHS "${CUDA_ARCH_FLAGS}")
message(STATUS "CUDA target architectures: ${CUDA_ARCHS}")
# Filter the target architectures by the supported supported archs
Expand Down
24 changes: 22 additions & 2 deletions cmake/utils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,11 @@ endmacro()
#
# Example:
# CMAKE_CUDA_FLAGS="-Wall -gencode arch=compute_70,code=sm_70 -gencode arch=compute_75,code=sm_75"
# clear_cuda_arches(CUDA_ARCH_FLAGS)
# clear_cuda_gencode_flags(CUDA_ARCH_FLAGS)
# CUDA_ARCH_FLAGS="-gencode arch=compute_70,code=sm_70;-gencode arch=compute_75,code=sm_75"
# CMAKE_CUDA_FLAGS="-Wall"
#
macro(clear_cuda_arches CUDA_ARCH_FLAGS)
macro(clear_cuda_gencode_flags CUDA_ARCH_FLAGS)
# Extract all `-gencode` flags from `CMAKE_CUDA_FLAGS`
string(REGEX MATCHALL "-gencode arch=[^ ]+" CUDA_ARCH_FLAGS
${CMAKE_CUDA_FLAGS})
Expand All @@ -235,6 +235,26 @@ macro(clear_cuda_arches CUDA_ARCH_FLAGS)
${CMAKE_CUDA_FLAGS})
endmacro()

#
# Warn when a caller requested PTX code generation through global CUDA arch
# flags. vLLM removes those flags and reapplies per-source gencode flags, so the
# user's global PTX request will not be preserved.
#
function(warn_if_ptx_arch_requested CUDA_ARCH_FLAGS)
foreach(_ARCH_FLAG ${CUDA_ARCH_FLAGS})
if(_ARCH_FLAG MATCHES "code=.*compute_[0-9]+[af]?")
message(WARNING
"PTX code generation requested in CUDA architecture flags "
"(${_ARCH_FLAG}), but vLLM does not preserve global PTX requests "
"when normalizing per-source CUDA architectures. Remove '+PTX' from "
"TORCH_CUDA_ARCH_LIST or rely on vLLM's built-in per-kernel PTX "
"selection.")
return()
endif()
endforeach()
endfunction()


#
# Extract unique CUDA architectures from a list of compute capabilities codes in
# the form `<major><minor>[<letter>]`, convert them to the form sort
Expand Down
3 changes: 3 additions & 0 deletions docs/getting_started/installation/gpu.cuda.inc.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ cd vllm
uv pip install -e . --torch-backend=auto
```

!!! note "CUDA Architecture & PTX Flags"
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.

!!! tip
Building from source requires a lot of compilation. If you are building from source repeatedly, it's more efficient to cache the compilation results.

Expand Down
38 changes: 36 additions & 2 deletions tests/test_cmake_utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project

import shutil
import subprocess
import sys
from pathlib import Path


def _get_cmake_bin() -> str:
cmake = shutil.which("cmake")
if cmake:
return cmake
venv_cmake = Path(sys.executable).parent / "cmake"
if venv_cmake.is_file():
return str(venv_cmake)
return "cmake"


def test_exact_family_arch_precedes_generic_family_fallback(tmp_path: Path):
repo_root = Path(__file__).parents[1]
script = tmp_path / "test_cuda_archs.cmake"
Expand All @@ -20,7 +32,7 @@ def test_exact_family_arch_precedes_generic_family_fallback(tmp_path: Path):
"""
)

subprocess.run(["cmake", "-P", script], check=True)
subprocess.run([_get_cmake_bin(), "-P", script], check=True)


def test_extract_archs_prefers_sass_target_over_corrupted_virtual_arch(
Expand All @@ -45,4 +57,26 @@ def test_extract_archs_prefers_sass_target_over_corrupted_virtual_arch(
"""
)

subprocess.run(["cmake", "-P", script], check=True)
subprocess.run([_get_cmake_bin(), "-P", script], check=True)


def test_clear_cuda_gencode_flags(tmp_path: Path):
repo_root = Path(__file__).parents[1]
script = tmp_path / "test_clear_flags.cmake"
script.write_text(
f"""
cmake_minimum_required(VERSION 3.26)
include("{repo_root / "cmake" / "utils.cmake"}")
set(CMAKE_CUDA_FLAGS "-Wall -gencode arch=compute_80,code=sm_80")
clear_cuda_gencode_flags(CUDA_ARCH_FLAGS)
if(NOT "${{CMAKE_CUDA_FLAGS}}" STREQUAL "-Wall ")
message(FATAL_ERROR "Expected '-Wall ', got '${{CMAKE_CUDA_FLAGS}}'")
endif()
if(NOT "${{CUDA_ARCH_FLAGS}}" STREQUAL "-gencode arch=compute_80,code=sm_80")
message(FATAL_ERROR "Expected '-gencode arch=compute_80,code=sm_80', "
"got '${{CUDA_ARCH_FLAGS}}'")
endif()
"""
)

subprocess.run([_get_cmake_bin(), "-P", script], check=True)
Loading