This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch manylinux-ci-836
in repository https://gitbox.apache.org/repos/asf/tvm-tirx.git
The following commit(s) were added to refs/heads/manylinux-ci-836 by this push:
new b9da34d2d [FEAT] Enable SPIR-V code generation independently of Vulkan
runtime
b9da34d2d is described below
commit b9da34d2d57eeff7cc0ad66ecea1d8ebcff73fd3
Author: Tianqi Chen <[email protected]>
AuthorDate: Sun Oct 25 19:21:34 2026 +0000
[FEAT] Enable SPIR-V code generation independently of Vulkan runtime
---
CMakeLists.txt | 5 +-
cmake/modules/SPIRV.cmake | 87 +++++++++++++++++++++++
cmake/modules/Vulkan.cmake | 23 +-----
cmake/utils/FindVulkan.cmake | 28 +-------
src/backend/vulkan/codegen/spirv_utils.cc | 2 +-
tests/python/backend/vulkan/test_module_export.py | 8 +--
6 files changed, 97 insertions(+), 56 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 515091b38..85b9270d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,7 +61,7 @@ tvm_tirx_option(TVM_TIRX_USE_OPENCL_EXTN_QCOM BOOL OFF
"Enable Qualcomm OpenCL e
# Vulkan
tvm_tirx_option(TVM_TIRX_USE_VULKAN STRING OFF "Build with Vulkan (OFF, ON, or
SDK path)")
-tvm_tirx_option(TVM_TIRX_USE_KHRONOS_SPIRV STRING OFF "Use Khronos SPIR-V
tools (OFF or install path)")
+tvm_tirx_option(TVM_TIRX_USE_KHRONOS_SPIRV STRING OFF "SPIR-V tools
installation prefix (OFF for automatic discovery)")
tvm_tirx_option(TVM_TIRX_USE_SPIRV_KHR_INTEGER_DOT_PRODUCT BOOL OFF "Enable
SPIR-V integer dot product")
# ROCm
@@ -221,6 +221,7 @@ include(cmake/modules/OpenMP.cmake)
# contributions are collected before the compiler object target is created.
include(cmake/modules/CUDA.cmake)
include(cmake/modules/OpenCL.cmake)
+include(cmake/modules/SPIRV.cmake)
include(cmake/modules/Vulkan.cmake)
include(cmake/modules/Metal.cmake)
include(cmake/modules/ROCM.cmake)
@@ -230,7 +231,7 @@ include(cmake/modules/Git.cmake)
# ######### Target: `tvm_tirx_compiler` ##########
add_library(tvm_tirx_compiler_objs OBJECT ${COMPILER_SRCS})
-target_link_libraries(tvm_tirx_compiler_objs PUBLIC tvm_tirx_header)
+target_link_libraries(tvm_tirx_compiler_objs PUBLIC tvm_tirx_header PRIVATE
tvm_spirv_header)
if(TARGET tvm_llvm_header)
target_link_libraries(tvm_tirx_compiler_objs PRIVATE tvm_llvm_header)
endif()
diff --git a/cmake/modules/SPIRV.cmake b/cmake/modules/SPIRV.cmake
new file mode 100644
index 000000000..0d90c4df4
--- /dev/null
+++ b/cmake/modules/SPIRV.cmake
@@ -0,0 +1,87 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# SPIR-V code generation needs headers and SPIRV-Tools, but no Vulkan loader.
+include(FetchContent)
+FetchContent_Declare(tvm_spirv_headers
+ URL
https://github.com/KhronosGroup/SPIRV-Headers/archive/09913f088a1197aba4aefd300a876b2ebbaa3391.tar.gz
+ URL_HASH
SHA256=6d4aad5a86d7d5af144747aee1d616f624897d64d842f282aca7777f84244318
+ SOURCE_SUBDIR headers-only)
+find_path(TVM_SPIRV_HEADERS_DIR spirv.hpp
+ HINTS "${TVM_TIRX_USE_KHRONOS_SPIRV}" ENV VULKAN_SDK
+ PATH_SUFFIXES include/spirv/unified1 include/SPIRV)
+if(NOT TVM_SPIRV_HEADERS_DIR)
+ FetchContent_MakeAvailable(tvm_spirv_headers)
+ set(TVM_SPIRV_HEADERS_DIR
"${tvm_spirv_headers_SOURCE_DIR}/include/spirv/unified1")
+endif()
+find_path(TVM_VULKAN_HEADERS_DIR vulkan/vulkan_core.h
+ HINTS "${TVM_TIRX_USE_VULKAN}" ENV VULKAN_SDK PATH_SUFFIXES include)
+if(NOT TVM_VULKAN_HEADERS_DIR)
+ FetchContent_Declare(tvm_vulkan_headers
+ URL
https://github.com/KhronosGroup/Vulkan-Headers/archive/952f776f6573aafbb62ea717d871cd1d6816c387.tar.gz
+ URL_HASH
SHA256=4c744e80c908bcc65c2057482f44e57d7e3d748f6eae4cd759fd593018f4ce35
+ SOURCE_SUBDIR headers-only)
+ FetchContent_MakeAvailable(tvm_vulkan_headers)
+ set(TVM_VULKAN_HEADERS_DIR "${tvm_vulkan_headers_SOURCE_DIR}/include")
+endif()
+
+find_package(SPIRV-Tools CONFIG QUIET
+ HINTS "${TVM_TIRX_USE_KHRONOS_SPIRV}" ENV VULKAN_SDK)
+if(NOT TARGET SPIRV-Tools-static AND NOT TARGET SPIRV-Tools)
+ # Keep the matching SDK 1.4.309 headers beside the source build. Only the
+ # validation/disassembly library is linked; tools and tests are not built.
+ if(NOT tvm_spirv_headers_SOURCE_DIR)
+ FetchContent_MakeAvailable(tvm_spirv_headers)
+ endif()
+ set(SPIRV-Headers_SOURCE_DIR "${tvm_spirv_headers_SOURCE_DIR}")
+ set(TVM_SPIRV_HEADERS_DIR
"${tvm_spirv_headers_SOURCE_DIR}/include/spirv/unified1")
+ set(SPIRV_SKIP_EXECUTABLES ON)
+ set(SPIRV_SKIP_TESTS ON)
+ set(SPIRV_TOOLS_BUILD_STATIC ON)
+ set(SKIP_SPIRV_TOOLS_INSTALL ON)
+ FetchContent_Declare(tvm_spirv_tools
+ URL
https://github.com/KhronosGroup/SPIRV-Tools/archive/f289d047f49fb60488301ec62bafab85573668cc.tar.gz
+ URL_HASH
SHA256=5fbd56baf226a04435656bae408287365102b69a24fa73bab8353c5f44b55615
+ SOURCE_SUBDIR library-only)
+ FetchContent_MakeAvailable(tvm_spirv_tools)
+ add_subdirectory("${tvm_spirv_tools_SOURCE_DIR}"
"${tvm_spirv_tools_BINARY_DIR}" EXCLUDE_FROM_ALL)
+ install(FILES "${tvm_spirv_tools_SOURCE_DIR}/LICENSE" DESTINATION licenses
+ RENAME LICENSE-SPIRV-Tools.txt COMPONENT tvm_tirx)
+endif()
+if(TARGET SPIRV-Tools-static)
+ set(TVM_SPIRV_TOOLS_LIBRARY SPIRV-Tools-static)
+else()
+ set(TVM_SPIRV_TOOLS_LIBRARY SPIRV-Tools)
+endif()
+
+add_library(tvm_spirv_header INTERFACE)
+target_include_directories(tvm_spirv_header SYSTEM INTERFACE
+ "${TVM_SPIRV_HEADERS_DIR}" "${TVM_VULKAN_HEADERS_DIR}")
+target_link_libraries(tvm_spirv_header INTERFACE ${TVM_SPIRV_TOOLS_LIBRARY})
+target_compile_definitions(tvm_spirv_header INTERFACE TVM_ENABLE_SPIRV=1)
+if(TVM_TIRX_USE_SPIRV_KHR_INTEGER_DOT_PRODUCT)
+ target_compile_definitions(tvm_spirv_header INTERFACE
TVM_SPIRV_KHR_INTEGER_DOT_PRODUCT=1)
+endif()
+file(GLOB COMPILER_SPIRV_SRCS CONFIGURE_DEPENDS
+ src/backend/vulkan/codegen/build_vulkan.cc
+ src/backend/vulkan/codegen/codegen_spirv.cc
+ src/backend/vulkan/codegen/intrin_rule_spirv.cc
+ src/backend/vulkan/codegen/ir_builder.cc
+ src/backend/vulkan/codegen/spirv_support.cc
+ src/backend/vulkan/codegen/spirv_utils.cc)
+list(APPEND COMPILER_SRCS ${COMPILER_SPIRV_SRCS})
+list(APPEND TVM_LINKER_LIBS ${TVM_SPIRV_TOOLS_LIBRARY})
diff --git a/cmake/modules/Vulkan.cmake b/cmake/modules/Vulkan.cmake
index 88025bf03..5fb61cacb 100644
--- a/cmake/modules/Vulkan.cmake
+++ b/cmake/modules/Vulkan.cmake
@@ -15,38 +15,19 @@
# specific language governing permissions and limitations
# under the License.
-# Be compatible with older version of CMake
-find_vulkan(${TVM_TIRX_USE_VULKAN} ${TVM_TIRX_USE_KHRONOS_SPIRV})
+find_vulkan(${TVM_TIRX_USE_VULKAN})
if(TVM_TIRX_USE_VULKAN)
if(NOT Vulkan_FOUND)
message(FATAL_ERROR "Cannot find Vulkan, TVM_TIRX_USE_VULKAN="
${TVM_TIRX_USE_VULKAN})
endif()
- if(TVM_TIRX_USE_SPIRV_KHR_INTEGER_DOT_PRODUCT)
- add_definitions(-DTVM_SPIRV_KHR_INTEGER_DOT_PRODUCT=1)
- message(STATUS "Enable SPIRV_KHR_INTEGER_DOT_PRODUCT")
- endif()
- include_directories(SYSTEM ${Vulkan_INCLUDE_DIRS})
- message(STATUS "Build with Vulkan support")
- file(GLOB COMPILER_VULKAN_SRCS CONFIGURE_DEPENDS
src/backend/vulkan/codegen/build_vulkan.cc
- src/backend/vulkan/codegen/codegen_spirv.cc
- src/backend/vulkan/codegen/intrin_rule_spirv.cc
- src/backend/vulkan/codegen/ir_builder.cc
- src/backend/vulkan/codegen/spirv_support.cc
- src/backend/vulkan/codegen/spirv_utils.cc
- )
- list(APPEND COMPILER_SRCS ${COMPILER_VULKAN_SRCS})
- list(APPEND TVM_LINKER_LIBS ${Vulkan_SPIRV_TOOLS_LIBRARY})
- add_definitions(-DTVM_ENABLE_SPIRV=1)
-endif(TVM_TIRX_USE_VULKAN)
-
-if(TVM_TIRX_USE_VULKAN)
message(STATUS "Build vulkan device runtime")
file(GLOB RUNTIME_VULKAN_SRCS CONFIGURE_DEPENDS
src/backend/vulkan/runtime/*.cc)
add_library(tvm_runtime_vulkan_objs OBJECT ${RUNTIME_VULKAN_SRCS})
target_link_libraries(tvm_runtime_vulkan_objs PUBLIC tvm_tirx_header)
+ target_include_directories(tvm_runtime_vulkan_objs SYSTEM PRIVATE
${Vulkan_INCLUDE_DIRS})
set_target_properties(tvm_runtime_vulkan_objs PROPERTIES
POSITION_INDEPENDENT_CODE ON)
add_library(tvm_runtime_vulkan SHARED
$<TARGET_OBJECTS:tvm_runtime_vulkan_objs>)
install(TARGETS tvm_runtime_vulkan DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT tvm_tirx)
diff --git a/cmake/utils/FindVulkan.cmake b/cmake/utils/FindVulkan.cmake
index 032ff1dff..a5d7a0799 100644
--- a/cmake/utils/FindVulkan.cmake
+++ b/cmake/utils/FindVulkan.cmake
@@ -29,10 +29,9 @@
# - Vulkan_FOUND
# - Vulkan_INCLUDE_DIRS
# - Vulkan_LIBRARY
-# - Vulkan_SPIRV_TOOLS_LIBRARY
#
-macro(find_vulkan use_vulkan use_khronos_spirv)
+macro(find_vulkan use_vulkan)
set(__use_vulkan ${use_vulkan})
if(IS_DIRECTORY ${__use_vulkan})
set(__vulkan_sdk ${__use_vulkan})
@@ -44,13 +43,6 @@ macro(find_vulkan use_vulkan use_khronos_spirv)
endif()
- if(IS_DIRECTORY ${use_khronos_spirv})
- set(__use_khronos_spirv ${use_khronos_spirv})
- message(STATUS "Custom khronos spirv PATH=" ${__use_khronos_spirv})
- else()
- set(__use_khronos_spirv "")
- endif()
-
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
set(VULKAN_NDK_SRC ${CMAKE_ANDROID_NDK}/sources/third_party/vulkan/src)
set(Vulkan_INCLUDE_DIRS ${VULKAN_NDK_SRC}/include)
@@ -76,23 +68,7 @@ macro(find_vulkan use_vulkan use_khronos_spirv)
endif()
if(Vulkan_FOUND)
- get_filename_component(VULKAN_LIBRARY_PATH ${Vulkan_LIBRARY} DIRECTORY)
- if (WIN32)
- find_library(Vulkan_SPIRV_TOOLS_LIBRARY SPIRV-Tools
- HINTS ${__use_khronos_spirv}/spirv-tools/lib ${VULKAN_LIBRARY_PATH}
${VULKAN_LIBRARY_PATH}/spirv-tools ${VULKAN_SDK}/lib)
- find_path(_libspirv libspirv.h HINTS
${__use_khronos_spirv}/spirv-tools/include ${Vulkan_INCLUDE_DIRS} PATH_SUFFIXES
vulkan spirv-tools)
- find_path(_spirv spirv.hpp HINTS
${__use_khronos_spirv}/SPIRV-Headers/include ${Vulkan_INCLUDE_DIRS}
PATH_SUFFIXES vulkan SPIRV spirv/unified1 spirv-headers)
- else()
- find_library(Vulkan_SPIRV_TOOLS_LIBRARY SPIRV-Tools
- HINTS ${__use_khronos_spirv}/lib ${VULKAN_LIBRARY_PATH}
${VULKAN_LIBRARY_PATH}/spirv-tools ${VULKAN_SDK}/lib)
- find_path(_libspirv libspirv.h HINTS ${__use_khronos_spirv}/include
${Vulkan_INCLUDE_DIRS} PATH_SUFFIXES vulkan spirv-tools)
- find_path(_spirv spirv.hpp HINTS ${__use_khronos_spirv}/include
${Vulkan_INCLUDE_DIRS} PATH_SUFFIXES vulkan SPIRV spirv/unified1 spirv-headers)
- endif()
-
- find_path(_glsl_std GLSL.std.450.h HINTS ${Vulkan_INCLUDE_DIRS}
PATH_SUFFIXES vulkan SPIRV spirv/unified1 spirv-headers)
- list(APPEND Vulkan_INCLUDE_DIRS ${_libspirv} ${_spirv} ${_glsl_std})
message(STATUS "Vulkan_INCLUDE_DIRS=" ${Vulkan_INCLUDE_DIRS})
message(STATUS "Vulkan_LIBRARY=" ${Vulkan_LIBRARY})
- message(STATUS "Vulkan_SPIRV_TOOLS_LIBRARY=" ${Vulkan_SPIRV_TOOLS_LIBRARY})
- endif(Vulkan_FOUND)
+ endif()
endmacro(find_vulkan)
diff --git a/src/backend/vulkan/codegen/spirv_utils.cc
b/src/backend/vulkan/codegen/spirv_utils.cc
index c2e9946a8..659d3a2af 100644
--- a/src/backend/vulkan/codegen/spirv_utils.cc
+++ b/src/backend/vulkan/codegen/spirv_utils.cc
@@ -28,7 +28,7 @@
#include <tvm/support/env.h>
#if TVM_ENABLE_SPIRV
-#include <libspirv.h>
+#include <spirv-tools/libspirv.h>
#include "codegen_spirv.h"
#endif
diff --git a/tests/python/backend/vulkan/test_module_export.py
b/tests/python/backend/vulkan/test_module_export.py
index 4e9e7fbe5..981df5d2e 100644
--- a/tests/python/backend/vulkan/test_module_export.py
+++ b/tests/python/backend/vulkan/test_module_export.py
@@ -15,19 +15,14 @@
# specific language governing permissions and limitations
# under the License.
-import pytest
-
import tvm_tirx
import tvm_tirx.testing
from tvm_tirx.script import ir as I
from tvm_tirx.script import tirx as T
-from tvm_tirx.testing import env
[email protected]
[email protected](not env.has_vulkan(), reason="need vulkan")
def test_export_load_with_fallback(monkeypatch, tmp_path):
- """Force the codegen wrapper into the fallback branch, then export."""
+ """Compile and export SPIR-V without requiring a Vulkan device or
runtime."""
n = 1024
@I.ir_module
@@ -42,6 +37,7 @@ def test_export_load_with_fallback(monkeypatch, tmp_path):
monkeypatch.setenv("TVM_TIRX_COMPILE_FORCE_FALLBACK", "1")
host_lib = tvm_tirx.tirx.compile(Module, target="vulkan")
monkeypatch.delenv("TVM_TIRX_COMPILE_FORCE_FALLBACK")
+ assert "OpEntryPoint GLCompute" in host_lib.mod.imports[0].inspect_source()
lib_path = str(tmp_path / "lib.so")
host_lib.export_library(lib_path)