Files
wehub-resource-sync 26446540fa
Lint / lint (push) Waiting to run
CI / MacOS (push) Waiting to run
CI / Windows (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:36:25 +08:00

352 lines
13 KiB
CMake

# 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.
include(ExternalProject)
include(cmake/modules/HexagonSDK.cmake)
set(FOUND_HEXAGON_TOOLCHAIN FALSE)
function(find_hexagon_toolchain)
if(FOUND_HEXAGON_TOOLCHAIN)
return()
endif()
if(NOT "${USE_HEXAGON_TOOLCHAIN}" STREQUAL "")
set(TRY_PATH "${USE_HEXAGON_TOOLCHAIN}")
else()
set(TRY_PATH "${USE_HEXAGON_SDK}")
endif()
message(STATUS "Looking for Hexagon toolchain in ${TRY_PATH}")
file(GLOB_RECURSE HEXAGON_CLANG "${TRY_PATH}/*/hexagon-clang++")
if(HEXAGON_CLANG)
# The path is ${HEXAGON_TOOLCHAIN}/bin/hexagon-clang++.
get_filename_component(HEXAGON_TMP0 "${HEXAGON_CLANG}" DIRECTORY)
get_filename_component(HEXAGON_TMP1 "${HEXAGON_TMP0}" DIRECTORY)
set(HEXAGON_TOOLCHAIN "${HEXAGON_TMP1}" CACHE PATH
"Path to the Hexagon toolchain")
set(FOUND_HEXAGON_TOOLCHAIN TRUE)
else()
message(SEND_ERROR "Cannot find Hexagon toolchain in ${TRY_PATH}")
endif()
endfunction()
macro(file_glob_append _output_list)
tvm_file_glob(GLOB _tmp0 ${ARGN})
set(_tmp1 ${${_output_list}})
list(APPEND _tmp1 ${_tmp0})
set(${_output_list} ${_tmp1})
endmacro()
set(TVMRT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/hexagon/runtime")
set(TVM_CORE_RUNTIME_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/runtime")
if(DEFINED USE_HEXAGON_DEVICE)
message(WARNING "USE_HEXAGON_DEVICE is deprecated, use USE_HEXAGON instead")
endif()
# This .cmake file is included when building any part of TVM for any
# architecture. It shouldn't require any Hexagon-specific parameters (like
# the path to the SDK), unless it's needed. The flag USE_HEXAGON decides
# whether any Hexagon-related functionality is enabled. Specifically,
# setting USE_HEXAGON=OFF, disables any form of Hexagon support.
#
# Note on the function of USE_HEXAGON_RPC:
# - When building for Hexagon, this will build the Hexagon endpoint of the
# RPC server: the FastRPC skel library (with TVM runtime built into it),
# and the standalone RPC server for simulator.
# - When building for Android, this will build the (intermediary) RPC server,
# including the "stub" code for the FastRPC implementation of the RPC
# channel.
# - When building for x86, this will build the host-side code that instan-
# tiates the simulator.
if(NOT BUILD_FOR_HEXAGON AND NOT BUILD_FOR_ANDROID)
set(BUILD_FOR_HOST TRUE)
endif()
if(NOT USE_HEXAGON)
# USE_HEXAGON=OFF: codegen still works through the per-backend fallback
# module (src/backend/hexagon/codegen/hexagon_fallback_module.cc), which is always
# compiled into libtvm via CODEGEN_SRCS. No opt-stub registration is
# needed.
return()
endif()
# From here on, USE_HEXAGON is assumed to be TRUE.
if(BUILD_FOR_HOST AND USE_HEXAGON_QHL)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_QHL")
endif()
function(add_android_paths)
get_hexagon_sdk_property("${USE_HEXAGON_SDK}" "${USE_HEXAGON_ARCH}"
SDK_INCLUDE SDK_INCLUDE_DIRS
DSPRPC_LIB DSPRPC_LIB_DIRS
RPCMEM_ROOT RPCMEM_ROOT_DIR
)
if(NOT SDK_INCLUDE_DIRS OR NOT DSPRPC_LIB_DIRS OR NOT RPCMEM_ROOT_DIR)
message(WARNING "Could not locate some Hexagon SDK components")
endif()
include_directories(SYSTEM
${SDK_INCLUDE_DIRS}
"${RPCMEM_ROOT_DIR}/inc"
)
link_directories(${DSPRPC_LIB_DIRS})
endfunction()
function(add_hexagon_wrapper_paths)
if(NOT DEFINED HEXAGON_TOOLCHAIN)
message(FATAL_ERROR "This function must be called after find_hexagon_toolchain")
endif()
include_directories(SYSTEM
"${HEXAGON_TOOLCHAIN}/include/iss"
)
link_directories("${HEXAGON_TOOLCHAIN}/lib/iss")
endfunction()
if(BUILD_FOR_HEXAGON)
# When building FOR Hexagon (the DSP itself), all runtime sources go into
# the single libtvm_runtime (static or shared). No per-backend DSO split.
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/*.cc"
)
# Add builtins to RelaxVM
tvm_file_glob(GLOB VM_BUILTIN_SRC_CC src/runtime/vm/hexagon/*.cc)
list(APPEND RUNTIME_SRCS ${VM_BUILTIN_SRC_CC})
else()
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/hexagon_module.cc"
)
endif()
set(htp_supported_archs "v68" "v69" "v73" "v75")
list(FIND htp_supported_archs "${USE_HEXAGON_ARCH}" supported_arch_index)
if(${supported_arch_index} EQUAL -1)
# Exclude User DMA files when building for archs below v68
list(REMOVE_ITEM RUNTIME_HEXAGON_SRCS "${TVMRT_SOURCE_DIR}/hexagon_user_dma.cc")
endif()
if(BUILD_FOR_HEXAGON)
get_hexagon_sdk_property("${USE_HEXAGON_SDK}" "${USE_HEXAGON_ARCH}"
SDK_INCLUDE SDK_INCLUDE_DIRS
QURT_INCLUDE QURT_INCLUDE_DIRS
)
if(NOT SDK_INCLUDE_DIRS OR NOT QURT_INCLUDE_DIRS)
message(WARNING "Could not locate some Hexagon SDK components")
endif()
# Set the compiler arch flag.
add_definitions("-m${USE_HEXAGON_ARCH}")
# Add SDK and QuRT includes when building for Hexagon.
include_directories(SYSTEM ${SDK_INCLUDE_DIRS} ${QURT_INCLUDE_DIRS})
set(USE_CUSTOM_LOGGING ON) # To use a custom logger
# QHL support.
if(USE_HEXAGON_QHL)
file_glob_append(TVM_QHL_WRAPPER_SRCS
"${TVMRT_SOURCE_DIR}/qhl/*.cc"
)
include_directories(
"${USE_HEXAGON_SDK}/libs/qhl_hvx/inc/qhmath_hvx"
"${USE_HEXAGON_SDK}/libs/qhl_hvx/inc/internal/"
"${USE_HEXAGON_SDK}/libs/qhl/inc/qhmath"
"${USE_HEXAGON_SDK}/libs/qhl/src/internal/"
)
set_property(SOURCE ${TVM_QHL_WRAPPER_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-narrowing -mhvx -mhvx-length=128B")
list(APPEND TVM_RUNTIME_LINKER_LIBS -Wl,--whole-archive ${USE_HEXAGON_SDK}/libs/qhl_hvx/prebuilt/hexagon_toolv84_v68/libqhmath_hvx.a -Wl,--no-whole-archive)
list(APPEND TVM_RUNTIME_LINKER_LIBS -Wl,--whole-archive ${USE_HEXAGON_SDK}/libs/qhl/prebuilt/hexagon_toolv84_v68/libqhmath.a -Wl,--no-whole-archive)
endif()
# Exclude HVX implementation files when building for archs below v68
if(${supported_arch_index} GREATER -1)
# Hand-written ops
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/ops/*.cc"
)
include_directories(
"${TVMRT_SOURCE_DIR}/ops"
)
set_source_files_properties(
"${TVMRT_SOURCE_DIR}/ops/conv2d_quant_hvx.cc"
PROPERTIES COMPILE_FLAGS "-mhvx"
)
set_source_files_properties(
"${TVMRT_SOURCE_DIR}/ops/conv2d_fp16_hvx.cc"
PROPERTIES COMPILE_FLAGS "-mhvx"
)
endif()
# Include hexagon external library runtime sources
if(USE_HEXAGON_EXTERNAL_LIBS)
# Check if the libs are provided as an absolute path
if(EXISTS ${USE_HEXAGON_EXTERNAL_LIBS})
# Check if the libs are provided as a git url
elseif(USE_HEXAGON_EXTERNAL_LIBS MATCHES "\.git$")
if(NOT DEFINED HEXAGON_EXTERNAL_LIBS_SHA)
message(FATAL_ERROR "HEXAGON_EXTERNA_LIBS_SHA must be set when "
"USE_HEXAGON_EXTERNAL_LIBS is set to a git repository")
endif()
include(FetchContent)
FetchContent_Declare(hexagon_external
GIT_REPOSITORY "${USE_HEXAGON_EXTERNAL_LIBS}"
GIT_TAG "${HEXAGON_EXTERNAL_LIBS_SHA}")
FetchContent_MakeAvailable(hexagon_external)
set(USE_HEXAGON_EXTERNAL_LIBS "${hexagon_external_SOURCE_DIR}")
else()
message(FATAL_ERROR "Invalid use of USE_HEXAGON_EXTERNAL_LIBS="
"${USE_HEXAGON_EXTERNAL_LIBS}; USE_HEXAGON_EXTERNAL_LIBS only "
"supports absolute paths and git repository urls")
endif()
file_glob_append(HEXAGON_EXTERNAL_RUNTIME_SRCS
"${USE_HEXAGON_EXTERNAL_LIBS}/src/runtime/hexagon/*.cc"
)
list(APPEND RUNTIME_HEXAGON_SRCS "${HEXAGON_EXTERNAL_RUNTIME_SRCS}")
if(EXISTS "${USE_HEXAGON_EXTERNAL_LIBS}/HexagonExternalCompileFlags.cmake")
# External libraries will define HEXAGON_EXTERNAL_LIBS_COMPILE_FLAGS,
# changing this variable name will break downstream external libraries.
include("${USE_HEXAGON_EXTERNAL_LIBS}/HexagonExternalCompileFlags.cmake")
set_source_files_properties(
"${HEXAGON_EXTERNAL_RUNTIME_SRCS}"
PROPERTIES COMPILE_FLAGS "${HEXAGON_EXTERNAL_LIBS_COMPILE_FLAGS}"
)
endif()
endif()
endif()
if(USE_HEXAGON_RPC)
function(build_rpc_idl)
get_hexagon_sdk_property("${USE_HEXAGON_SDK}" "${USE_HEXAGON_ARCH}"
SDK_INCLUDE SDK_INCLUDE_DIRS
QAIC_EXE QAIC_EXE_PATH
)
foreach(INCDIR IN LISTS SDK_INCLUDE_DIRS)
list(APPEND QAIC_FLAGS "-I${INCDIR}")
endforeach()
add_custom_command(
OUTPUT
"${TVMRT_SOURCE_DIR}/rpc/hexagon_rpc.h"
"${TVMRT_SOURCE_DIR}/rpc/hexagon_rpc_skel.c"
"${TVMRT_SOURCE_DIR}/rpc/hexagon_rpc_stub.c"
COMMAND
${QAIC_EXE_PATH} ${QAIC_FLAGS}
"${TVMRT_SOURCE_DIR}/rpc/hexagon_rpc.idl"
-o "${TVMRT_SOURCE_DIR}/rpc"
MAIN_DEPENDENCY "${TVMRT_SOURCE_DIR}/rpc/hexagon_rpc.idl"
)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
# We can't easily fix this at the source-code level, because the .c file is generated
# by the qaic program. But it should be safe to ignore the warning:
# https://stackoverflow.com/questions/13905200/is-it-wise-to-ignore-gcc-clangs-wmissing-braces-warning
set_source_files_properties("${TVMRT_SOURCE_DIR}/rpc/hexagon_rpc_stub.c"
PROPERTY COMPILE_FLAGS "-Wno-missing-braces")
endif()
endfunction()
if(BUILD_FOR_ANDROID)
# Android part
add_android_paths()
build_rpc_idl()
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/rpc/android/*.cc"
)
# Add this file separately, because it's auto-generated, and glob won't
# find it during cmake-time.
list(APPEND RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/rpc/hexagon_rpc_stub.c"
)
list(APPEND TVM_RUNTIME_LINKER_LIBS cdsprpc)
elseif(BUILD_FOR_HEXAGON)
# Hexagon part
find_hexagon_toolchain()
build_rpc_idl()
# Include the generic RPC code into the TVM runtime.
list(APPEND RUNTIME_HEXAGON_SRCS
"${TVM_CORE_RUNTIME_SOURCE_DIR}/rpc/minrpc/minrpc_server.h"
"${TVM_CORE_RUNTIME_SOURCE_DIR}/rpc/minrpc/rpc_reference.h"
"${TVM_CORE_RUNTIME_SOURCE_DIR}/rpc/rpc_module.cc"
"${TVM_CORE_RUNTIME_SOURCE_DIR}/rpc/rpc_endpoint.cc"
"${TVM_CORE_RUNTIME_SOURCE_DIR}/rpc/rpc_session.cc"
# TODO(masahi): Remove rpc_local_session.cc after verifying that things work without it
"${TVM_CORE_RUNTIME_SOURCE_DIR}/rpc/rpc_local_session.cc"
)
set(HEXAGON_PROFILER_DIR "${TVMRT_SOURCE_DIR}/profiler")
# Add the hardware-specific RPC code into the skel library.
set_property(SOURCE ${HEXAGON_PROFILER_DIR}/lwp_handler.S PROPERTY LANGUAGE C)
add_library(hexagon_rpc_skel SHARED
"${TVMRT_SOURCE_DIR}/rpc/hexagon/rpc_server.cc"
"${TVMRT_SOURCE_DIR}/rpc/hexagon_rpc_skel.c"
"${HEXAGON_PROFILER_DIR}/prof_utils.cc"
"${HEXAGON_PROFILER_DIR}/lwp_handler.S"
)
target_include_directories(hexagon_rpc_skel
SYSTEM PRIVATE "${TVMRT_SOURCE_DIR}/rpc"
)
# Add the simulator-specific RPC code into a shared library to be
# executed via run_main_on_sim.
add_library(hexagon_rpc_sim SHARED
"${TVMRT_SOURCE_DIR}/rpc/simulator/rpc_server.cc"
"${HEXAGON_PROFILER_DIR}/prof_utils.cc"
"${HEXAGON_PROFILER_DIR}/lwp_handler.S"
)
target_link_libraries(hexagon_rpc_sim
-Wl,--whole-archive tvm_runtime -Wl,--no-whole-archive
)
elseif(BUILD_FOR_HOST)
find_hexagon_toolchain()
add_hexagon_wrapper_paths()
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/rpc/simulator/session.cc"
)
list(APPEND TVM_RUNTIME_LINKER_LIBS "-lwrapper")
endif()
endif() # USE_HEXAGON_RPC
# When building for the Hexagon DSP itself, all sources fold into
# libtvm_runtime (static/shared). When building for a host with
# USE_HEXAGON=ON, create a separate libtvm_runtime_hexagon.so.
if(BUILD_FOR_HEXAGON)
list(APPEND RUNTIME_SRCS ${RUNTIME_HEXAGON_SRCS} ${TVM_QHL_WRAPPER_SRCS})
elseif(USE_HEXAGON)
message(STATUS "Build hexagon device runtime")
add_library(tvm_runtime_hexagon_objs OBJECT ${RUNTIME_HEXAGON_SRCS} ${TVM_QHL_WRAPPER_SRCS})
target_link_libraries(tvm_runtime_hexagon_objs PUBLIC tvm_ffi_header)
set_target_properties(tvm_runtime_hexagon_objs PROPERTIES POSITION_INDEPENDENT_CODE ON)
if(TVM_VISIBILITY_FLAG)
target_compile_options(tvm_runtime_hexagon_objs PRIVATE "${TVM_VISIBILITY_FLAG}")
endif()
add_library(tvm_runtime_hexagon SHARED $<TARGET_OBJECTS:tvm_runtime_hexagon_objs>)
list(APPEND TVM_RUNTIME_BACKEND_LIBS tvm_runtime_hexagon)
target_link_libraries(tvm_runtime_hexagon PUBLIC tvm_runtime)
tvm_configure_target_library(tvm_runtime_hexagon RUNTIME_MODULE)
endif()