Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hexagon] Deprecate USE_HEXAGON_DEVICE, introduce USE_HEXAGON #11025

Merged
merged 1 commit into from
Apr 18, 2022
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
[Hexagon] Deprecate USE_HEXAGON_DEVICE, introduce USE_HEXAGON
The new cmake flag `USE_HEXAGON=[ON|OFF]` enables/disables Hexagon
support in TVM and TVM runtime. It should be turned on _whenever_
Hexagon support is required, even when compiling TVM runtime for
Hexagon itself.

This is one in a series of commits intended to remove offload
support, and make the whole-model support the default mode of
operation.

With `USE_HEXAGON_DEVICE` deprecated, offload runtime is not built
anymore, so register `device_api.hexagon` to be same as `.v2`
(presence of device API is taken as evidence of support for the
device in TVM, so this step is necessary).
  • Loading branch information
Parzyszek, Krzysztof committed Apr 15, 2022
commit 940ed8bf362ae8039fcd2f514f9c380ec1dc6f5a
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ tvm_option(USE_SPIRV_KHR_INTEGER_DOT_PRODUCT "whether enable SPIRV_KHR_DOT_PRODU
tvm_option(USE_METAL "Build with Metal" OFF)
tvm_option(USE_ROCM "Build with ROCM" OFF)
tvm_option(ROCM_PATH "The path to rocm" /opt/rocm)
tvm_option(USE_HEXAGON_DEVICE "Build with Hexagon device support in TVM runtime" OFF)
tvm_option(USE_HEXAGON_SDK "Path to the Hexagon SDK root (required for Hexagon support in TVM runtime or for building TVM runtime for Hexagon)" /path/to/sdk)
tvm_option(USE_HEXAGON "Build with Hexagon support" OFF)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some TVM config options provide [ON|OFF|PATH_TO_SDK], with ON indicating to search for the SDK in common directories and fail otherwise.

tvm_option(USE_HEXAGON_SDK "Path to the Hexagon SDK root (required for Hexagon support)" /path/to/sdk)
tvm_option(USE_HEXAGON_RPC "Enable Hexagon RPC using minRPC implementation over Android." OFF)
tvm_option(USE_RPC "Build with RPC" ON)
tvm_option(USE_THREADS "Build with thread support" ON)
Expand Down
3 changes: 3 additions & 0 deletions apps/hexagon_api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ ExternalProject_Add(x86_tvm_runtime_rpc
"-DUSE_LIBBACKTRACE=OFF"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't catch the motivation on introduction of hexagon_api earlier this year, but to add to the backlog it would be nice if the hexagon_api was built automatically as part of a USE_HEXAGON=ON build. It's easy for users to forget to recompile the hexagon_api after making changes and only rebuilding tvm.

"-DUSE_RPC=ON"
"-DUSE_CPP_RPC=ON"
"-DUSE_HEXAGON=ON"
"-DUSE_HEXAGON_RPC=ON"
"-DBUILD_STATIC_RUNTIME=ON"
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
Expand Down Expand Up @@ -66,6 +67,7 @@ ExternalProject_Add(android_tvm_runtime_rpc
"-DUSE_LIBBACKTRACE=OFF"
"-DUSE_RPC=ON"
"-DUSE_CPP_RPC=ON"
"-DUSE_HEXAGON=ON"
"-DUSE_HEXAGON_RPC=ON"
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
"-DUSE_ALTERNATIVE_LINKER=OFF"
Expand Down Expand Up @@ -101,6 +103,7 @@ ExternalProject_Add(hexagon_tvm_runtime_rpc
"-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}"
"-DUSE_LIBBACKTRACE=OFF"
"-DUSE_RPC=OFF"
"-DUSE_HEXAGON=ON"
"-DUSE_HEXAGON_RPC=ON"
"-DBUILD_STATIC_RUNTIME=ON"
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
Expand Down
9 changes: 5 additions & 4 deletions apps/hexagon_launcher/cmake/android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,16 @@ ExternalProject_Add(android_tvm_runtime
SOURCE_DIR "${TVM_SOURCE_DIR}"
BUILD_COMMAND $(MAKE) runtime
CMAKE_ARGS
"-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}"
"-DANDROID_PLATFORM=${ANDROID_PLATFORM}"
"-DANDROID_ABI=${ANDROID_ABI}"
"-DANDROID_PLATFORM=${ANDROID_PLATFORM}"
"-DCMAKE_CXX_STANDARD=14"
"-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}"
"-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}"
"-DUSE_HEXAGON=ON"
"-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}"
"-DUSE_LIBBACKTRACE=OFF"
"-DUSE_LLVM=OFF"
"-DUSE_RPC=OFF"
"-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}"
"-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}"
INSTALL_COMMAND ""
BUILD_ALWAYS ON
)
Expand Down
7 changes: 4 additions & 3 deletions apps/hexagon_launcher/cmake/hexagon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,16 @@ ExternalProject_Add(static_hexagon_tvm_runtime
SOURCE_DIR "${TVM_SOURCE_DIR}"
BUILD_COMMAND $(MAKE) runtime
CMAKE_ARGS
"-DBUILD_STATIC_RUNTIME=ON"
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}"
"-DCMAKE_CXX_STANDARD=14"
"-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}"
"-DUSE_HEXAGON=ON"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Place USE_HEXAGON=ON before other hexagon cmake variable definitions

"-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}"
"-DUSE_LIBBACKTRACE=OFF"
"-DUSE_LLVM=OFF"
"-DUSE_RPC=OFF"
"-DBUILD_STATIC_RUNTIME=ON"
"-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}"
INSTALL_COMMAND ""
BUILD_ALWAYS ON
)
Expand Down
13 changes: 5 additions & 8 deletions cmake/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -293,20 +293,17 @@ set(USE_PT_TVMDSOOP OFF)
# Whether to use STL's std::unordered_map or TVM's POD compatible Map
set(USE_FALLBACK_STL_MAP OFF)

# Whether to use hexagon device
set(USE_HEXAGON_DEVICE OFF)
# Whether to enable Hexagon support
set(USE_HEXAGON OFF)
set(USE_HEXAGON_SDK /path/to/sdk)

# Whether to build the hexagon launcher
set(USE_HEXAGON_LAUNCHER OFF)

# Whether to build the minimal support android rpc server for hexagon
set(USE_HEXAGON_PROXY_RPC OFF)
# Whether to build the minimal support android rpc server for Hexagon
set(USE_HEXAGON_RPC OFF)

# Hexagon architecture to target when compiling TVM itself (not the target for
# compiling _by_ TVM). This applies to components like the TVM runtime, but is
# also used to select correct include/library paths from the Hexagon SDK when
# building offloading runtime for Android.
# building runtime for Android.
# Valid values are v65, v66, v68, v69.
set(USE_HEXAGON_ARCH "v66")

Expand Down
90 changes: 12 additions & 78 deletions cmake/modules/Hexagon.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@
include(ExternalProject)
include(cmake/modules/HexagonSDK.cmake)

set(PICK_SIM "sim")
set(PICK_HW "target")
set(PICK_NONE "OFF")

set(FOUND_HEXAGON_TOOLCHAIN FALSE)

function(find_hexagon_toolchain)
Expand Down Expand Up @@ -56,27 +52,17 @@ endmacro()

set(TVMRT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/runtime")

# First, verify that USE_HEXAGON_DEVICE has a valid value.
if(DEFINED USE_HEXAGON_DEVICE)
if(NOT USE_HEXAGON_DEVICE STREQUAL "${PICK_SIM}" AND
NOT USE_HEXAGON_DEVICE STREQUAL "${PICK_HW}" AND
NOT USE_HEXAGON_DEVICE STREQUAL "${PICK_NONE}")
message(SEND_ERROR "USE_HEXAGON_DEVICE must be one of "
"[${PICK_NONE}|${PICK_SIM}|${PICK_HW}]")
set(USE_HEXAGON_DEVICE OFF)
endif()
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.
#
# Aside from building the code for Hexagon, two flags can enable some
# Hexagon-related functionality:
# - USE_HEXAGON_DEVICE
# - USE_HEXAGON_RPC
#
# USE_HEXAGON_RPC:
# 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.
Expand All @@ -91,7 +77,7 @@ if(NOT BUILD_FOR_HEXAGON AND NOT BUILD_FOR_ANDROID)
endif()


if(NOT USE_HEXAGON_DEVICE AND NOT USE_HEXAGON_RPC AND NOT BUILD_FOR_HEXAGON)
if(NOT USE_HEXAGON)
# If nothing related to Hexagon is enabled, add phony Hexagon codegen,
# and some stuff needed by cpptests (this part is a temporary workaround
# until e2e support for Hexagon is enabled).
Expand All @@ -104,6 +90,7 @@ if(NOT USE_HEXAGON_DEVICE AND NOT USE_HEXAGON_RPC AND NOT BUILD_FOR_HEXAGON)
return()
endif()

# From here on, USE_HEXAGON is assumed to be TRUE.

function(add_android_paths)
get_hexagon_sdk_property("${USE_HEXAGON_SDK}" "${USE_HEXAGON_ARCH}"
Expand Down Expand Up @@ -132,10 +119,12 @@ function(add_hexagon_wrapper_paths)
link_directories("${HEXAGON_TOOLCHAIN}/lib/iss")
endfunction()


# Common sources for TVM runtime with Hexagon support
file_glob_append(RUNTIME_HEXAGON_COMMON_SRCS
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/hexagon/hexagon_module.cc"
"${TVMRT_SOURCE_DIR}/hexagon/hexagon/*.cc"
"${TVMRT_SOURCE_DIR}/hexagon/host/*.cc"
)


Expand All @@ -154,61 +143,10 @@ if(BUILD_FOR_HEXAGON)
# Add SDK and QuRT includes when building for Hexagon.
include_directories(SYSTEM ${SDK_INCLUDE_DIRS} ${QURT_INCLUDE_DIRS})

list(APPEND RUNTIME_HEXAGON_SRCS ${RUNTIME_HEXAGON_COMMON_SRCS})
set(USE_CUSTOM_LOGGING ON) # To use a custom logger
endif()


if(USE_HEXAGON_DEVICE)
function(invalid_device_value_for BUILD_TARGET)
message(SEND_ERROR
"USE_HEXAGON_DEVICE=${USE_HEXAGON_DEVICE} is not supported when "
"building for ${BUILD_TARGET}"
)
endfunction()

list(APPEND RUNTIME_HEXAGON_SRCS ${RUNTIME_HEXAGON_COMMON_SRCS})

if(BUILD_FOR_HOST)
if(NOT USE_HEXAGON_DEVICE STREQUAL "${PICK_SIM}")
invalid_device_value_for("host")
endif()
find_hexagon_toolchain()
add_hexagon_wrapper_paths()
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/hexagon/android/*.cc"
"${TVMRT_SOURCE_DIR}/hexagon/android/sim/*.cc"
)
list(APPEND TVM_RUNTIME_LINKER_LIBS "-lwrapper")

ExternalProject_Add(sim_dev
SOURCE_DIR "${TVMRT_SOURCE_DIR}/hexagon/android/sim/driver"
CMAKE_ARGS
"-DCMAKE_C_COMPILER=${HEXAGON_TOOLCHAIN}/bin/hexagon-clang"
"-DCMAKE_CXX_COMPILER=${HEXAGON_TOOLCHAIN}/bin/hexagon-clang++"
"-DHEXAGON_ARCH=${USE_HEXAGON_ARCH}"
INSTALL_COMMAND "true"
)

elseif(BUILD_FOR_ANDROID)
if(NOT USE_HEXAGON_DEVICE STREQUAL "${PICK_HW}")
invalid_device_value_for("Android")
endif()
find_hexagon_toolchain()
add_android_paths()
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/hexagon/android/*.cc"
"${TVMRT_SOURCE_DIR}/hexagon/android/target/*.cc"
)
# Hexagon runtime uses __android_log_print, which is in liblog.
list(APPEND TVM_RUNTIME_LINKER_LIBS dl log cdsprpc)

elseif(BUILD_FOR_HEXAGON)
invalid_device_value_for("Hexagon")
endif()
endif() # USE_HEXAGON_DEVICE


if(USE_HEXAGON_RPC)
function(build_rpc_idl)
get_hexagon_sdk_property("${USE_HEXAGON_SDK}" "${USE_HEXAGON_ARCH}"
Expand All @@ -232,14 +170,11 @@ if(USE_HEXAGON_RPC)
)
endfunction()

list(APPEND RUNTIME_HEXAGON_SRCS ${RUNTIME_HEXAGON_COMMON_SRCS})

if(BUILD_FOR_ANDROID)
# Android part
add_android_paths()
build_rpc_idl()
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/hexagon/host/*.cc"
"${TVMRT_SOURCE_DIR}/hexagon/rpc/android/*.cc"
)
# Add this file separately, because it's auto-generated, and glob won't
Expand Down Expand Up @@ -285,7 +220,6 @@ if(USE_HEXAGON_RPC)
find_hexagon_toolchain()
add_hexagon_wrapper_paths()
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/hexagon/host/*.cc"
"${TVMRT_SOURCE_DIR}/hexagon/rpc/simulator/session.cc"
)
list(APPEND TVM_RUNTIME_LINKER_LIBS "-lwrapper")
Expand Down
2 changes: 1 addition & 1 deletion cmake/modules/LibInfo.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function(add_lib_info src_file)
TVM_INFO_USE_GRAPH_EXECUTOR_CUDA_GRAPH="${USE_GRAPH_EXECUTOR_CUDA_GRAPH}"
TVM_INFO_USE_GRAPH_EXECUTOR="${USE_GRAPH_EXECUTOR}"
TVM_INFO_USE_GTEST="${USE_GTEST}"
TVM_INFO_USE_HEXAGON_DEVICE="${USE_HEXAGON_DEVICE}"
TVM_INFO_USE_HEXAGON="${USE_HEXAGON}"
TVM_INFO_USE_HEXAGON_RPC="${USE_HEXAGON_RPC}"
TVM_INFO_USE_HEXAGON_SDK="${USE_HEXAGON_SDK}"
TVM_INFO_USE_IOS_RPC="${USE_IOS_RPC}"
Expand Down
70 changes: 32 additions & 38 deletions src/runtime/hexagon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,61 +17,55 @@

# Hexagon backend runtime

The Hexagon runtime is a part of the TVM runtime that facilitates communication between a host and a Hexagon device. There are two types of host/device arrangements that are supported:
- X86/Linux host running Hexagon simulator,
- Android/AArch64 host running on a physical device containing a Hexagon module (i.e. CSDP or ADSP).
The Hexagon runtime implements the functionality necessary for executing ML
models on Hexagon hardware (or emulation).

The TVM runtime that contains Hexagon runtime is the one executing on host. In either case, there will need to be a separate TVM runtime (i.e. the `libtvm_runtime.so` library) compiled for execution on Hexagon.
The prerequisite is to have Hexagon SDK installed, version 4.0.0 or later.

The prerequisite is to have Hexagon SDK installed, preferably version 3.5.0 or later. The Hexagon SDK can be downloaded from https://developer.qualcomm.com/software/hexagon-dsp-sdk.
It is also recommended to use as recent version of LLVM as possible, version
7.0.0 being the minimum (based on community feedback).

It is also recommended to use as recent version of LLVM as possible, version 7.0.0 being the minimum (based on community feedback).
### Compiling TVM with support for Hexagon for host (x86)

### Compiling TVM runtime for x86

This will use Hexagon simulator, which is provided in the Hexagon SDK.

When configuring TVM (cmake), set the following variables:
TVM running on host can serve as a cross-compiler that produces machine code
for Hexagon. To enable that, certain elements of both, the compiler and the
runtime need to include Hexagon-specific functionality. For the compiler, it
is code generation, and for the runtime, it is the ability to represent
modules with Hexagon code. Since Hexagon codegen is based on LLVM, LLVM
codegen needs to be enabled as well. The set of cmake options to enable
Hexagon support is
```
USE_LLVM=llvm-config
USE_HEXAGON_DEVICE=sim
USE_HEXAGON=ON
USE_HEXAGON_SDK=/path/to/sdk
```

You can then build the entire TVM with the usual command (e.g. `make`).

### Compiling TVM runtime for Android
### Compiling TVM runtime for non-x86

This will use FastRPC mechanism to communicate between the AArch64 host and Hexagon.
Aside from x86, there are two other platforms where support for Hexagon may
be relevant. One of them is obviously Hexagon itself, the other one is
Android. Neither of these platforms supports the compiler side of TVM, only
runtime, and so the only compiler-related cmake option from the x86 build
above can be omitted: USE_LLVM.

When configuring TVM (cmake), set the following variables:
Additionally, for Android, set the toolchain and target flags:
```
USE_LLVM=llvm-config
USE_HEXAGON_DEVICE=device
ANDROID_ABI=aarch64-v8a
ANDROID_PLATFORM=android-28
CMAKE_TOOLCHAIN_FILE=/path/to/android-ndk/build/cmake/android.toolchain.cmake
USE_HEXAGON=ON
USE_HEXAGON_ARCH=v65|v66|v68|v69
USE_HEXAGON_SDK=/path/to/sdk
```

You will need Android clang toolchain to compile the runtime. It is provided in Android NDK r19 or newer.

Set the C/C++ compiler to the Android clang for aarch64, and pass `-DCMAKE_CXX_FLAGS='-stdlib=libc++'` to the cmake command.

Only build the `runtime` component of TVM (e.g. `make runtime`), building the entire TVM will not work.

### Compiling TVM runtime for Hexagon

The TVM runtime executing on Hexagon does not need to have support for Hexagon device in it (as it is only for communication between host and Hexagon device). In fact, it's only needed for basic services (like thread control), and so it should not contain support for any devices.

When configuring TVM (cmake), set the following variables:
Building for Hexagon requires setting the C/C++ compiler to `hexagon-clang/++`:
```
USE_RPC=OFF
USE_LLVM=OFF
USE_HEXAGON_DEVICE=OFF
CMAKE_C_COMPILER=hexagon-clang
CMAKE_CXX_COMPILER=hexagon-clang++
USE_HEXAGON=ON
USE_HEXAGON_ARCH=v65|v66|v68|v69
USE_HEXAGON_SDK=/path/to/sdk
```

Please note that while suport for a Hexagon device is disabled, the Hexagon SDK is still needed and the path to it needs to be passed to cmake.

Set the C/C++ compiler to `hexagon-clang` (included in the Hexagon SDK), and set `CMAKE_CXX_FLAGS='-stdlib=libc++'`.

As in the case of Android, only build the `runtime` component (e.g. `make runtime`).
As mentioned before, only build the `runtime` component (e.g. `make runtime`).

2 changes: 1 addition & 1 deletion src/runtime/hexagon/android/hexagon_device_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ inline void HexagonDeviceAPI::FreeWorkspace(Device dev, void* ptr) {
DeviceAPI::FreeWorkspace(dev, ptr);
}

TVM_REGISTER_GLOBAL("device_api.hexagon").set_body([](TVMArgs args, TVMRetValue* rv) {
TVM_REGISTER_GLOBAL("device_api.hexagon.v1").set_body([](TVMArgs args, TVMRetValue* rv) {
DeviceAPI* ptr = HexagonDeviceAPI::Global();
*rv = ptr;
});
Expand Down
5 changes: 5 additions & 0 deletions src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ TVM_REGISTER_GLOBAL("device_api.hexagon.free_nd").set_body([](TVMArgs args, TVMR
*rv = static_cast<int32_t>(0);
});

TVM_REGISTER_GLOBAL("device_api.hexagon").set_body([](TVMArgs args, TVMRetValue* rv) {
DeviceAPI* ptr = HexagonDeviceAPIv2::Global();
*rv = static_cast<void*>(ptr);
});

TVM_REGISTER_GLOBAL("device_api.hexagon.v2").set_body([](TVMArgs args, TVMRetValue* rv) {
DeviceAPI* ptr = HexagonDeviceAPIv2::Global();
*rv = static_cast<void*>(ptr);
Expand Down
Loading