Skip to content

Commit bbd5a4e

Browse files
committed
[VULKAN][ADRENO] Vulkan support for Adreno GPU inline with OpenCL support
This PR enabled Vulkan backend for Adreno GPU along side with OpenCL. With this Adreno GPU can be used with Vulkan backend resulting similar performance line OpenCL. This is foundation to add Vulkan specific extensions in near future like co-op matmul ...etc. Common Relax and TIR pipe line is used here with codegen and runtime being different.
1 parent fa51ea2 commit bbd5a4e

39 files changed

+2201
-255
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ tvm_option(USE_OPENCL "Build with OpenCL" OFF)
3333
tvm_option(USE_OPENCL_ENABLE_HOST_PTR "Enable OpenCL memory object access to host" OFF)
3434
tvm_option(USE_OPENCL_GTEST "Path to OpenCL specific gtest version for runtime cpp tests." /path/to/opencl/gtest)
3535
tvm_option(USE_VULKAN "Build with Vulkan" OFF)
36+
tvm_option(USE_VULKAN_GTEST "Path to Vulkan specific gtest version for runtime cpp tests." /path/to/vulkan/gtest)
3637

3738

3839
# Whether to use spirv-tools.and SPIRV-Headers from Khronos github or gitlab.
@@ -454,6 +455,9 @@ set(CMAKE_CXX_STANDARD 17)
454455
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
455456
set(CMAKE_CUDA_STANDARD 17)
456457

458+
#include centralized gtest setup
459+
include(cmake/modules/GTestConfig.cmake)
460+
457461
# Module rules
458462
include(cmake/modules/CUDA.cmake)
459463
include(cmake/modules/Hexagon.cmake) # This must come before logging.cmake

cmake/modules/GTestConfig.cmake

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
set(Build_GTests OFF)
19+
if(NOT TARGET gtest)
20+
unset(runtime_gtests)
21+
if(DEFINED USE_OPENCL_GTEST AND EXISTS ${USE_OPENCL_GTEST})
22+
set(runtime_gtests ${USE_OPENCL_GTEST})
23+
elseif(DEFINED USE_VULKAN_GTEST AND EXISTS ${USE_VULKAN_GTEST})
24+
set(runtime_gtests ${USE_VULKAN_GTEST})
25+
elseif(ANDROID_ABI AND DEFINED ENV{ANDROID_NDK_HOME})
26+
set(GOOGLETEST_ROOT $ENV{ANDROID_NDK_HOME}/sources/third_party/googletest)
27+
add_library(gtest_main STATIC
28+
${GOOGLETEST_ROOT}/src/gtest_main.cc
29+
${GOOGLETEST_ROOT}/src/gtest-all.cc)
30+
target_include_directories(gtest_main PRIVATE ${GOOGLETEST_ROOT})
31+
target_include_directories(gtest_main PUBLIC ${GOOGLETEST_ROOT}/include)
32+
set(Build_GTests ON)
33+
message(STATUS "Using gtest from Android NDK")
34+
return()
35+
else()
36+
message(STATUS "No valid GTest path found, skipping GTest configuration")
37+
return()
38+
endif()
39+
40+
# Configure if runtime_gtests is valid
41+
if(runtime_gtests AND EXISTS ${runtime_gtests})
42+
include(FetchContent)
43+
FetchContent_Declare(googletest SOURCE_DIR "${runtime_gtests}")
44+
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
45+
FetchContent_MakeAvailable(googletest)
46+
install(TARGETS gtest EXPORT ${PROJECT_NAME}Targets DESTINATION lib${LIB_SUFFIX})
47+
set(Build_GTests ON)
48+
else()
49+
set(Build_GTests OFF)
50+
return()
51+
endif()
52+
endif()

cmake/modules/LibInfo.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ function(add_lib_info src_file)
120120
TVM_INFO_USE_THRUST="${USE_THRUST}"
121121
TVM_INFO_USE_CURAND="${USE_CURAND}"
122122
TVM_INFO_USE_VULKAN="${USE_VULKAN}"
123+
TVM_INFO_USE_VULKAN_GTEST="${USE_VULKAN_GTEST}"
123124
TVM_INFO_USE_CLML="${USE_CLML}"
124125
TVM_INFO_USE_CLML_GRAPH_EXECUTOR="${USE_CLML_GRAPH_EXECUTOR}"
125126
TVM_INFO_USE_TVM_CLML_VERSION="${CLML_VERSION_MAJOR}"

cmake/modules/OpenCL.cmake

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
# KIND, either express or implied. See the License for the
1515
# specific language governing permissions and limitations
1616
# under the License.
17-
1817
if(USE_OPENCL)
1918
tvm_file_glob(GLOB RUNTIME_OPENCL_SRCS src/runtime/opencl/*.cc)
2019
list(APPEND COMPILER_SRCS src/target/spirv/spirv_utils.cc)
@@ -35,36 +34,15 @@ if(USE_OPENCL)
3534
list(APPEND TVM_RUNTIME_LINKER_LIBS ${OpenCL_LIBRARIES})
3635
endif()
3736

38-
if(DEFINED USE_OPENCL_GTEST)
39-
if(EXISTS ${USE_OPENCL_GTEST})
40-
include(FetchContent)
41-
FetchContent_Declare(googletest SOURCE_DIR "${USE_OPENCL_GTEST}")
42-
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
43-
FetchContent_MakeAvailable(googletest)
44-
install(TARGETS gtest EXPORT ${PROJECT_NAME}Targets DESTINATION lib${LIB_SUFFIX})
45-
46-
message(STATUS "Found OpenCL gtest at ${USE_OPENCL_GTEST}")
47-
set(Build_OpenCL_GTests ON)
48-
elseif (ANDROID_ABI AND DEFINED ENV{ANDROID_NDK_HOME})
49-
set(GOOGLETEST_ROOT $ENV{ANDROID_NDK_HOME}/sources/third_party/googletest)
50-
add_library(gtest_main STATIC ${GOOGLETEST_ROOT}/src/gtest_main.cc ${GOOGLETEST_ROOT}/src/gtest-all.cc)
51-
target_include_directories(gtest_main PRIVATE ${GOOGLETEST_ROOT})
52-
target_include_directories(gtest_main PUBLIC ${GOOGLETEST_ROOT}/include)
53-
message(STATUS "Using gtest from Android NDK")
54-
set(Build_OpenCL_GTests ON)
55-
endif()
56-
57-
if(Build_OpenCL_GTests)
58-
message(STATUS "Building OpenCL-Gtests")
59-
tvm_file_glob(GLOB_RECURSE OPENCL_TEST_SRCS
60-
"tests/cpp-runtime/opencl/*.cc"
61-
)
62-
add_executable(opencl-cpptest ${OPENCL_TEST_SRCS})
63-
target_link_libraries(opencl-cpptest PRIVATE gtest_main tvm_runtime ${OpenCL_LIBRARIES})
64-
else()
65-
message(STATUS "Couldn't build OpenCL-Gtests")
66-
endif()
37+
if(Build_GTests)
38+
message(STATUS "Building OpenCL GTests")
39+
tvm_file_glob(GLOB_RECURSE OPENCL_TEST_SRCS "tests/cpp-runtime/opencl/*.cc")
40+
add_executable(opencl-cpptest ${OPENCL_TEST_SRCS})
41+
target_link_libraries(opencl-cpptest PRIVATE gtest_main tvm_runtime ${OpenCL_LIBRARIES})
42+
else()
43+
message(STATUS "Couldn't build OpenCL-Gtests")
6744
endif()
45+
6846
list(APPEND RUNTIME_SRCS ${RUNTIME_OPENCL_SRCS})
6947
if(USE_OPENCL_ENABLE_HOST_PTR)
7048
add_definitions(-DOPENCL_ENABLE_HOST_PTR)

cmake/modules/Vulkan.cmake

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ if(USE_VULKAN)
3030
message(STATUS "Build with Vulkan support")
3131
tvm_file_glob(GLOB RUNTIME_VULKAN_SRCS src/runtime/vulkan/*.cc)
3232
tvm_file_glob(GLOB COMPILER_VULKAN_SRCS src/target/spirv/*.cc)
33+
34+
if(Build_GTests)
35+
message(STATUS "Building Vulkan GTests")
36+
tvm_file_glob(GLOB_RECURSE VULKAN_TEST_SRCS "tests/cpp-runtime/vulkan/*.cc")
37+
add_executable(vulkan-cpptest ${VULKAN_TEST_SRCS})
38+
target_link_libraries(vulkan-cpptest PRIVATE gtest_main tvm_runtime)
39+
else()
40+
message(STATUS "Couldn't build Vulkan-Gtests")
41+
endif()
42+
3343
list(APPEND RUNTIME_SRCS ${RUNTIME_VULKAN_SRCS})
3444
list(APPEND COMPILER_SRCS ${COMPILER_VULKAN_SRCS})
3545
list(APPEND TVM_LINKER_LIBS ${Vulkan_SPIRV_TOOLS_LIBRARY})

cmake/utils/FindVulkan.cmake

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ macro(find_vulkan use_vulkan use_khronos_spirv)
3636
set(__use_vulkan ${use_vulkan})
3737
if(IS_DIRECTORY ${__use_vulkan})
3838
set(__vulkan_sdk ${__use_vulkan})
39-
message(STATUS "Custom Vulkan SDK PATH=" ${__use_vulkan})
39+
message(STATUS "Using custom Vulkan SDK: ${__vulkan_sdk}")
4040
elseif(IS_DIRECTORY $ENV{VULKAN_SDK})
4141
set(__vulkan_sdk $ENV{VULKAN_SDK})
4242
else()
@@ -46,45 +46,65 @@ macro(find_vulkan use_vulkan use_khronos_spirv)
4646

4747
if(IS_DIRECTORY ${use_khronos_spirv})
4848
set(__use_khronos_spirv ${use_khronos_spirv})
49-
message(STATUS "Custom khronos spirv PATH=" ${__use_khronos_spirv})
49+
message(STATUS "Using custom Khronos SPIRV path: ${__use_khronos_spirv}")
5050
else()
5151
set(__use_khronos_spirv "")
5252
endif()
5353

5454
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
55-
set(VULKAN_NDK_SRC ${CMAKE_ANDROID_NDK}/sources/third_party/vulkan/src)
56-
set(Vulkan_INCLUDE_DIRS ${VULKAN_NDK_SRC}/include)
57-
set(Vulkan_FOUND TRUE)
58-
message(STATUS "Android Vulkan_INCLUDE_DIRS=" ${Vulkan_INCLUDE_DIRS})
59-
message(STATUS "Skip finding SPIRV in Android, make sure you only build tvm runtime.")
60-
return()
61-
endif()
55+
message(STATUS "Detected Android build")
56+
57+
set(Vulkan_INCLUDE_DIRS "${CMAKE_SYSROOT}/usr/include/vulkan")
58+
59+
# Map Android ABI to architecture
60+
set(ANDROID_LIB_ARCH "")
61+
if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
62+
set(ANDROID_LIB_ARCH "aarch64-linux-android")
63+
elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a")
64+
set(ANDROID_LIB_ARCH "arm-linux-androideabi")
65+
elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86")
66+
set(ANDROID_LIB_ARCH "i686-linux-android")
67+
elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64")
68+
set(ANDROID_LIB_ARCH "x86_64-linux-android")
69+
else()
70+
message(FATAL_ERROR "Unsupported Android ABI: ${CMAKE_ANDROID_ARCH_ABI}")
71+
endif()
72+
73+
# Find Vulkan library for Android
74+
set(Vulkan_LIB_PATH "${CMAKE_SYSROOT}/usr/lib/${ANDROID_LIB_ARCH}/27")
75+
find_library(Vulkan_LIBRARY NAMES vulkan libvulkan.so PATHS ${Vulkan_LIB_PATH} NO_DEFAULT_PATH)
76+
77+
if(Vulkan_LIBRARY)
78+
set(Vulkan_FOUND TRUE)
79+
else()
80+
message(FATAL_ERROR "Could not find Vulkan lib in ${Vulkan_LIB_PATH}")
81+
endif()
82+
83+
else()
6284

85+
message(STATUS "__vulkan_sdk:- " ${__vulkan_sdk})
6386
if(__vulkan_sdk)
6487
set(Vulkan_INCLUDE_DIRS ${__vulkan_sdk}/include)
6588
find_library(Vulkan_LIBRARY NAMES vulkan vulkan-1 PATHS ${__vulkan_sdk}/lib)
6689
if(Vulkan_LIBRARY)
6790
set(Vulkan_FOUND TRUE)
6891
endif()
69-
endif(__vulkan_sdk)
92+
endif()
7093

71-
# resort to find vulkan of option is on
72-
if(NOT Vulkan_FOUND)
73-
if(${__use_vulkan} MATCHES ${IS_TRUE_PATTERN})
74-
find_package(Vulkan QUIET)
75-
endif()
94+
if(NOT Vulkan_FOUND AND ${use_vulkan} MATCHES ${IS_TRUE_PATTERN})
95+
find_package(Vulkan QUIET)
7696
endif()
7797

7898
if(Vulkan_FOUND)
7999
get_filename_component(VULKAN_LIBRARY_PATH ${Vulkan_LIBRARY} DIRECTORY)
80100
if (WIN32)
81101
find_library(Vulkan_SPIRV_TOOLS_LIBRARY SPIRV-Tools
82-
HINTS ${__use_khronos_spirv}/spirv-tools/lib ${VULKAN_LIBRARY_PATH} ${VULKAN_LIBRARY_PATH}/spirv-tools ${VULKAN_SDK}/lib)
102+
HINTS ${__use_khronos_spirv}/spirv-tools/lib ${VULKAN_LIBRARY_PATH} ${VULKAN_LIBRARY_PATH}/spirv-tools ${__vulkan_sdk}/lib)
83103
find_path(_libspirv libspirv.h HINTS ${__use_khronos_spirv}/spirv-tools/include ${Vulkan_INCLUDE_DIRS} PATH_SUFFIXES vulkan spirv-tools)
84104
find_path(_spirv spirv.hpp HINTS ${__use_khronos_spirv}/SPIRV-Headers/include ${Vulkan_INCLUDE_DIRS} PATH_SUFFIXES vulkan SPIRV spirv/unified1 spirv-headers)
85105
else()
86106
find_library(Vulkan_SPIRV_TOOLS_LIBRARY SPIRV-Tools
87-
HINTS ${__use_khronos_spirv}/lib ${VULKAN_LIBRARY_PATH} ${VULKAN_LIBRARY_PATH}/spirv-tools ${VULKAN_SDK}/lib)
107+
HINTS ${__use_khronos_spirv}/lib ${VULKAN_LIBRARY_PATH} ${VULKAN_LIBRARY_PATH}/spirv-tools ${__vulkan_sdk}/lib)
88108
find_path(_libspirv libspirv.h HINTS ${__use_khronos_spirv}/include ${Vulkan_INCLUDE_DIRS} PATH_SUFFIXES vulkan spirv-tools)
89109
find_path(_spirv spirv.hpp HINTS ${__use_khronos_spirv}/include ${Vulkan_INCLUDE_DIRS} PATH_SUFFIXES vulkan SPIRV spirv/unified1 spirv-headers)
90110
endif()
@@ -95,4 +115,5 @@ macro(find_vulkan use_vulkan use_khronos_spirv)
95115
message(STATUS "Vulkan_LIBRARY=" ${Vulkan_LIBRARY})
96116
message(STATUS "Vulkan_SPIRV_TOOLS_LIBRARY=" ${Vulkan_SPIRV_TOOLS_LIBRARY})
97117
endif(Vulkan_FOUND)
118+
endif()
98119
endmacro(find_vulkan)

python/tvm/relax/pipeline.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ def get_default_pipeline(target: tvm.target.Target):
337337
return backend.gpu_generic.get_default_pipeline(target)
338338
if target.kind.name == "llvm":
339339
return backend.cpu_generic.get_default_pipeline(target)
340-
if target.kind.name == "opencl" and "adreno" in target.keys:
340+
if target.kind.name in [ "opencl", "vulkan" ] and "adreno" in target.keys:
341341
return backend.adreno.get_default_pipeline(target)
342342
if BackendDispatcher.is_gpu_target(target):
343343
return backend.gpu_generic.get_default_pipeline(target)

python/tvm/testing/utils.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,14 @@ def _multi_gpu_exists():
838838
)
839839

840840

841+
def _check_opencl_vulkan():
842+
return (
843+
(_cmake_flag_enabled("USE_OPENCL") and tvm.opencl(0).exist)
844+
or (_cmake_flag_enabled("USE_VULKAN") and tvm.vulkan(0).exist)
845+
or "RPC_TARGET" in os.environ
846+
)
847+
848+
841849
# Mark a test as requiring llvm to run
842850
requires_llvm = Feature(
843851
"llvm", "LLVM", cmake_flag="USE_LLVM", target_kind_enabled="llvm", target_kind_hardware="llvm"
@@ -976,8 +984,8 @@ def _multi_gpu_exists():
976984
"Vulkan",
977985
cmake_flag="USE_VULKAN",
978986
target_kind_enabled="vulkan",
979-
target_kind_hardware="vulkan",
980-
parent_features="gpu",
987+
target_kind_hardware="vulkan" if "RPC_TARGET" not in os.environ else None,
988+
parent_features="gpu" if "RPC_TARGET" not in os.environ else None,
981989
)
982990

983991
# Mark a test as requiring OpenCLML support in build.
@@ -988,6 +996,13 @@ def _multi_gpu_exists():
988996
target_kind_enabled="opencl",
989997
)
990998

999+
requires_opencl_vulkan = Feature(
1000+
"opencl_vulkan",
1001+
"OpenCL or Vulkan",
1002+
run_time_check=_check_opencl_vulkan,
1003+
parent_features=["opencl", "vulkan"],
1004+
)
1005+
9911006
# Mark a test as requiring NNAPI support in build.
9921007
requires_nnapi = Feature(
9931008
"NNAPI",

src/runtime/file_utils.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ void FunctionInfo::Save(dmlc::JSONWriter* writer) const {
4545
writer->BeginObject();
4646
writer->WriteObjectKeyValue("name", name);
4747
writer->WriteObjectKeyValue("arg_types", sarg_types);
48+
writer->WriteObjectKeyValue("storage_scopes", storage_scopes);
4849
writer->WriteObjectKeyValue("launch_param_tags", launch_param_tags);
4950
std::vector<int> iarg_extra_tags(arg_extra_tags.size());
5051
for (size_t i = 0; i < arg_extra_tags.size(); ++i) {
@@ -59,6 +60,7 @@ void FunctionInfo::Load(dmlc::JSONReader* reader) {
5960
std::vector<std::string> sarg_types;
6061
helper.DeclareField("name", &name);
6162
helper.DeclareField("arg_types", &sarg_types);
63+
helper.DeclareOptionalField("storage_scopes", &storage_scopes);
6264
helper.DeclareOptionalField("launch_param_tags", &launch_param_tags);
6365
helper.DeclareOptionalField("thread_axis_tags",
6466
&launch_param_tags); // for backward compatibility
@@ -78,13 +80,15 @@ void FunctionInfo::Load(dmlc::JSONReader* reader) {
7880
void FunctionInfo::Save(dmlc::Stream* writer) const {
7981
writer->Write(name);
8082
writer->Write(arg_types);
83+
writer->Write(storage_scopes);
8184
writer->Write(launch_param_tags);
8285
writer->Write(arg_extra_tags);
8386
}
8487

8588
bool FunctionInfo::Load(dmlc::Stream* reader) {
8689
if (!reader->Read(&name)) return false;
8790
if (!reader->Read(&arg_types)) return false;
91+
if (!reader->Read(&storage_scopes)) return false;
8892
if (!reader->Read(&launch_param_tags)) return false;
8993
if (!reader->Read(&arg_extra_tags)) return false;
9094
return true;

src/runtime/meta_data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ constexpr const char* kUseCooperativeLaunch = "tir.use_cooperative_launch";
5959
struct FunctionInfo {
6060
std::string name;
6161
std::vector<DLDataType> arg_types;
62+
std::vector<std::string> storage_scopes;
6263
std::vector<std::string> launch_param_tags;
6364

6465
enum class ArgExtraTags : int { kNone = 0, kTensorMap = 1 };

0 commit comments

Comments
 (0)