From 23d8698727d89eb7141b5aa7e989e3fd0258b628 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 13 Jan 2022 11:47:55 -0800 Subject: [PATCH 1/4] [Hexagon] Do not auto-build apps when building TVM The Hexagon cmakes have recently become unwieldy due to a complex network of dependencies between various automatically built components. This was in large part because of trying to automatically build some apps, which then tried to build TVM runtimes again, but with their own configurations. This patch removes the ability to automatically build any Hexagon- -related apps from the main TVM build. The following cmake options are now deprecated: - `USE_HEXAGON_LAUNCHER` - `USE_HEXAGON_PROXY_RPC` In order to build the binaries needed for HexagonLauncher from tvm.contrib.hexagon: - Build TVM+runtime for x86, with codegen for Hexagon enabled. This can be done via `USE_HEXAGON_DEVICE=sim` or `target`. - Build Android runtime and tvm_rpc with `-DUSE_RPC=ON`, `-DUSE_CPP_RPC=ON`, and `-DUSE_HEXAGON_RPC=ON`. - Build Hexagon runtime with `-DUSE_HEXAGON_RPC=ON`, and `-DBUILD_STATIC_RUNTIME=ON`. --- CMakeLists.txt | 22 +- apps/hexagon_api/CMakeLists.txt | 83 ++++++ apps/hexagon_launcher/README.md | 37 --- cmake/modules/Hexagon.cmake | 315 +++++--------------- src/runtime/hexagon/proxy_rpc/device_api.cc | 155 ---------- 5 files changed, 167 insertions(+), 445 deletions(-) create mode 100644 apps/hexagon_api/CMakeLists.txt delete mode 100644 src/runtime/hexagon/proxy_rpc/device_api.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 41529612880e..b60258206bb8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,8 +32,6 @@ 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_RPC "Enable Hexagon RPC using minRPC implementation over Android." OFF) -tvm_option(USE_HEXAGON_LAUNCHER "Build the Hexagon graph launcher application" OFF) -tvm_option(USE_HEXAGON_PROXY_RPC "Build the Hexagon Proxy RPC server application" OFF) tvm_option(USE_RPC "Build with RPC" ON) tvm_option(USE_THREADS "Build with thread support" ON) tvm_option(USE_LLVM "Build with LLVM, can be set to specific llvm-config path" OFF) @@ -323,7 +321,7 @@ if(BUILD_FOR_HEXAGON) # runtime, since it would cause multiple definition errors with the # static one. if(NOT BUILD_STATIC_RUNTIME) - list(APPEND RUNTIME_SRCS src/runtime/hexagon/hexagon_posix.cc) + list(APPEND RUNTIME_SRCS src/runtime/hexagon/android/hexagon_posix.cc) # Allow undefined symbols (there will be some from libc). set(TVM_NO_UNDEFINED_SYMBOLS "") endif() @@ -559,12 +557,6 @@ else() target_compile_definitions(tvm_libinfo_objs PRIVATE "USE_FALLBACK_STL_MAP=0") endif(USE_FALLBACK_STL_MAP) -if(BUILD_FOR_HEXAGON) - # Wrap pthread_create to allow setting custom stack size. - set_property(TARGET tvm_runtime APPEND PROPERTY LINK_FLAGS - "-Wl,--wrap=pthread_create") -endif() - if(USE_THREADS AND NOT BUILD_FOR_HEXAGON) message(STATUS "Build with thread support...") set(CMAKE_THREAD_PREFER_PTHREAD TRUE) @@ -699,6 +691,18 @@ if(APPLE AND TVM_IS_DEBUG_BUILD) ) endif() +if(BUILD_FOR_HEXAGON) + # Wrap pthread_create to allow setting custom stack size. + set_property(TARGET tvm_runtime APPEND PROPERTY LINK_FLAGS + "-Wl,--wrap=pthread_create") + # Link tvm_runtime into the RPC skel library. Make sure it's built + # as a part of the "runtime" target. + if(USE_HEXAGON_RPC) + target_link_libraries(hexagon_rpc_skel -Wl,--whole-archive tvm_runtime -Wl,--no-whole-archive) + add_dependencies(runtime hexagon_rpc_skel) + endif() +endif() + #Caches the build. #Note that ccache-3.x doesn't support nvcc well, so CUDA kernels may never hit the cache and still #need to be re-compiled every time. Using ccache 4.0+ can resolve this issue. diff --git a/apps/hexagon_api/CMakeLists.txt b/apps/hexagon_api/CMakeLists.txt new file mode 100644 index 000000000000..4f0e724cce9a --- /dev/null +++ b/apps/hexagon_api/CMakeLists.txt @@ -0,0 +1,83 @@ +cmake_minimum_required(VERSION 3.2) + +project(hexagon_api) + +include(ExternalProject) + +# Required variables: +# ANDROID_ABI +# ANDROID_PLATFORM +# USE_ANDROID_TOOLCHAIN (Android toolchain .cmake file) +# USE_HEXAGON_ARCH +# USE_HEXAGON_SDK +# USE_HEXAGON_TOOLCHAIN (Path to Hexagon toolchain ending with "Tools") + +set(TVM_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../..") +set(HEXAGON_API_BINARY_DIR "${CMAKE_BINARY_DIR}/hexagon_rpc") + + +# Build Android binaries: +# - libtvm_runtime.so +# - tvm_rpc_android + +ExternalProject_Add(android_tvm_runtime_rpc + SOURCE_DIR "${TVM_SOURCE_DIR}" + BUILD_COMMAND $(MAKE) runtime tvm_rpc + CMAKE_ARGS + "-DCMAKE_TOOLCHAIN_FILE=${USE_ANDROID_TOOLCHAIN}" + "-DANDROID_PLATFORM=${ANDROID_PLATFORM}" + "-DANDROID_ABI=${ANDROID_ABI}" + "-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}" + "-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}" + "-DCMAKE_CXX_STANDARD=14" + "-DUSE_LIBBACKTRACE=OFF" + "-DUSE_LLVM=OFF" + "-DUSE_RPC=ON" + "-DUSE_CPP_RPC=ON" + "-DUSE_HEXAGON_RPC=ON" + INSTALL_COMMAND "" + BUILD_ALWAYS ON +) +ExternalProject_Get_Property(android_tvm_runtime_rpc BINARY_DIR) +ExternalProject_Add_Step(android_tvm_runtime_rpc copy_runtime + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${BINARY_DIR}/libtvm_runtime.so + ${HEXAGON_API_BINARY_DIR} + DEPENDEES install +) +ExternalProject_Add_Step(android_tvm_runtime_rpc copy_rpc_server + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${BINARY_DIR}/tvm_rpc + ${HEXAGON_API_BINARY_DIR}/tvm_rpc_android + DEPENDEES install +) + + +# Build Hexagon binaries: +# - libhexagon_rpc_skel.so +# - libtvm_runtime.a + +ExternalProject_Add(hexagon_tvm_runtime_rpc + SOURCE_DIR "${TVM_SOURCE_DIR}" + BUILD_COMMAND $(MAKE) runtime + CMAKE_ARGS + "-DCMAKE_C_COMPILER=${USE_HEXAGON_TOOLCHAIN}/bin/hexagon-clang" + "-DCMAKE_CXX_COMPILER=${USE_HEXAGON_TOOLCHAIN}/bin/hexagon-clang++" + "-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}" + "-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}" + "-DUSE_LIBBACKTRACE=OFF" + "-DUSE_RPC=OFF" + "-DUSE_HEXAGON_RPC=ON" + "-DBUILD_STATIC_RUNTIME=ON" + INSTALL_COMMAND "" + BUILD_ALWAYS ON +) +ExternalProject_Get_Property(hexagon_tvm_runtime_rpc BINARY_DIR) +ExternalProject_Add_Step(hexagon_tvm_runtime_rpc copy_binaries + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${BINARY_DIR}/libtvm_runtime.a + ${BINARY_DIR}/libhexagon_rpc_skel.so + ${HEXAGON_API_BINARY_DIR} + DEPENDEES install +) + diff --git a/apps/hexagon_launcher/README.md b/apps/hexagon_launcher/README.md index b52aa80bcaad..0e49a3927af7 100644 --- a/apps/hexagon_launcher/README.md +++ b/apps/hexagon_launcher/README.md @@ -31,43 +31,6 @@ The supported Snapdragon architectures are 855, 865, and 888. Android NDK can be downloaded from https://developer.android.com/ndk. Hexagon SDK is available at //developer.qualcomm.com/software/hexagon-dsp-sdk. -### Compilation with TVM - -Building the Hexagon launcher application as a component of the main TVM build -used for Hexagon codegen can be achieved by setting `USE_HEXAGON_LAUNCHER=ON`. -This option will compile core tvm, the android launcher binary and its corresponding -tvm_runtime, as well as the Hexagon launcher shared library and its corresponding -tvm_runtime. As described in the [Manual compilation](#Manual compilation) section -each component requires Hexagon and android dependencies. When building the launcher -along with TVM these configurations must be providing when invoking cmake. A minimal -example invocation for compiling TVM along with the Hexagon launcher is included below: - -``` -cmake -DCMAKE_C_COMPILER=/path/to/clang \ - -DCMAKE_CXX_COMPILER=/path/to/clang++ \ - -DCMAKE_CXX_FLAGS='-stdlib=libc++' \ - -DCMAKE_CXX_STANDARD=14 \ - -DUSE_LLVM=/path/to/llvm/bin/llvm-config \ - -DUSE_HEXAGON_ARCH=v65|v66|v68 \ - -DUSE_HEXAGON_LAUNCHER=ON \ - -DUSE_HEXAGON_SDK=/path/to/hexagon/SDK \ - -DUSE_HEXAGON_TOOLCHAIN=/path/to/hexagon/toolchain/ .. - -DANDROID_ABI=arm64-v8a \ - -DANDROID_PLATFORM=android-28 \ - -DUSE_ANDROID_TOOLCHAIN=/path/to/android-ndk/build/cmake/android.toolchain.cmake \ - .. -``` - -where `v65|v66|v68` means "one of" these architecture versions. -The Hexagon launcher application is an android binary and thus requires the use -of an android toolchain for compilation. Similarly, the Hexagon tvm runtime -requires the use of the Hexagon toolchain and depends on the Hexagon SDK. The -resulting hexagon launcher binaries can be found in the `apps_hexagon_launcher` -subdirectory of the cmake build directory. The above command -will build support for Hexagon codegen in the TVM library that requires -`USE_LLVM` to be set to an llvm-config that has the Hexagon target built in. - - ### Manual compilation Since some source files are shared between the Hexagon and android builds, diff --git a/cmake/modules/Hexagon.cmake b/cmake/modules/Hexagon.cmake index d982601fc1bb..d4dfaf22d698 100644 --- a/cmake/modules/Hexagon.cmake +++ b/cmake/modules/Hexagon.cmake @@ -42,7 +42,7 @@ function(find_hexagon_toolchain) set(HEXAGON_TOOLCHAIN "${HEXAGON_TMP1}" CACHE PATH "Path to the Hexagon toolchain") set(FOUND_HEXAGON_TOOLCHAIN TRUE) - else(HEXAGON_CLANG) + else() message(SEND_ERROR "Cannot find Hexagon toolchain in ${TRY_PATH}") endif() endfunction() @@ -71,239 +71,91 @@ endif() # Don't run these checks when compiling Hexagon device code, # e.g. when compiling the TVM runtime for Hexagon. if (NOT BUILD_FOR_HEXAGON AND NOT BUILD_FOR_ANDROID) - if(USE_HEXAGON_LAUNCHER STREQUAL "OFF" AND - USE_HEXAGON_PROXY_RPC STREQUAL "OFF" AND NOT USE_HEXAGON_RPC) - if(USE_HEXAGON_DEVICE STREQUAL "OFF") - list(APPEND COMPILER_SRCS src/target/opt/build_hexagon_off.cc) - # append select runtime sources for unit testing - list(APPEND RUNTIME_SRCS src/runtime/hexagon/hexagon/hexagon_buffer.cc) - list(APPEND RUNTIME_SRCS src/runtime/hexagon/hexagon/hexagon_common.cc) - if (NOT USE_HEXAGON_RPC) - return() - endif() - elseif(NOT USE_HEXAGON_DEVICE STREQUAL "${PICK_SIM}" AND - NOT USE_HEXAGON_DEVICE STREQUAL "${PICK_HW}") - set(ERROR_MSG - "USE_HEXAGON_DEVICE must be one of [${PICK_NONE}|${PICK_SIM}|${PICK_HW}]") - message(SEND_ERROR "${ERROR_MSG}") - return() - endif() + if(USE_HEXAGON_DEVICE STREQUAL "OFF") + list(APPEND COMPILER_SRCS src/target/opt/build_hexagon_off.cc) + # append select runtime sources for unit testing + list(APPEND RUNTIME_SRCS src/runtime/hexagon/hexagon/hexagon_buffer.cc) + list(APPEND RUNTIME_SRCS src/runtime/hexagon/hexagon/hexagon_common.cc) + return() + elseif(NOT USE_HEXAGON_DEVICE STREQUAL "${PICK_SIM}" AND + NOT USE_HEXAGON_DEVICE STREQUAL "${PICK_HW}") + message(SEND_ERROR "USE_HEXAGON_DEVICE must be one of " + "[${PICK_NONE}|${PICK_SIM}|${PICK_HW}]") + return() endif() endif() -# If USE_HEXAGON_DEVICE/LAUNCHER is set to a valid value, make sure that USE_HEXAGON_SDK -# is defined. -if(NOT USE_HEXAGON_SDK) - message(SEND_ERROR "Please set USE_HEXAGON_SDK to the Hexagon SDK root") - return() -endif() +# If no Hexagon support is enabled (other than some stub code), cmake +# execution should stop before reaching this point. -if(USE_HEXAGON_LAUNCHER STREQUAL "ON" OR - USE_HEXAGON_PROXY_RPC STREQUAL "ON") - if(DEFINED USE_ANDROID_TOOLCHAIN) - if(NOT DEFINED ANDROID_PLATFORM) - message(SEND_ERROR "Please set ANDROID_PLATFORM " - "when providing an Android cmake toolchain.") - endif() - if(NOT DEFINED ANDROID_ABI) - message(SEND_ERROR "Please set ANDROID_ABI " - "when providing an Android cmake toolchain.") - endif() - else() - message(SEND_ERROR "Please set USE_ANDROID_TOOLCHAIN to build the android " - " launcher for hexagon.") - endif() +if(NOT USE_HEXAGON_SDK OR NOT USE_HEXAGON_ARCH) + message(SEND_ERROR "Please set USE_HEXAGON_SDK to the Hexagon SDK root, " + "and USE_HEXAGON_ARCH to the Hexagon architecture version") + return() endif() if(USE_HEXAGON_LAUNCHER STREQUAL "ON") - set(LAUNCHER_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/apps_hexagon_launcher") - ExternalProject_Add(launcher_android - SOURCE_DIR "${CMAKE_SOURCE_DIR}/apps/hexagon_launcher/cmake/android" - INSTALL_DIR "${LAUNCHER_BINARY_DIR}" - BUILD_ALWAYS ON - CMAKE_ARGS - "-DCMAKE_TOOLCHAIN_FILE=${USE_ANDROID_TOOLCHAIN}" - "-DANDROID_PLATFORM=${ANDROID_PLATFORM}" - "-DANDROID_ABI=${ANDROID_ABI}" - "-DFASTRPC_LIBS=STUB" - "-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}" - "-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}" - INSTALL_COMMAND "" - ) - ExternalProject_Get_Property(launcher_android BINARY_DIR) - ExternalProject_Add_Step(launcher_android copy_binaries - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${BINARY_DIR}/launcher_android ${BINARY_DIR}/libtvm_runtime.so - ${LAUNCHER_BINARY_DIR} - DEPENDEES install - ) - ExternalProject_Add(launcher_hexagon - SOURCE_DIR "${CMAKE_SOURCE_DIR}/apps/hexagon_launcher/cmake/hexagon" - INSTALL_DIR "${LAUNCHER_BINARY_DIR}" - BUILD_ALWAYS ON - CMAKE_ARGS - "-DCMAKE_C_COMPILER=${USE_HEXAGON_TOOLCHAIN}/bin/hexagon-clang" - "-DCMAKE_CXX_COMPILER=${USE_HEXAGON_TOOLCHAIN}/bin/hexagon-clang++" - "-DFASTRPC_LIBS=SKEL" - "-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}" - "-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}" - INSTALL_COMMAND "" - ) - ExternalProject_Get_Property(launcher_hexagon BINARY_DIR) - ExternalProject_Add_Step(launcher_hexagon copy_binaries - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${BINARY_DIR}/liblauncher_rpc_skel.so - ${LAUNCHER_BINARY_DIR} - DEPENDEES install - ) - - set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${LAUNCHER_BINARY_DIR}") - + message(SEND_ERROR "USE_HEXAGON_LAUNCHER is deprecated, please build apps separately") endif() if(USE_HEXAGON_PROXY_RPC STREQUAL "ON") - set(RPC_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/apps_hexagon_proxy_rpc") - ExternalProject_Add(proxy_rpc_android - SOURCE_DIR "${CMAKE_SOURCE_DIR}/apps/hexagon_proxy_rpc/cmake/android" - INSTALL_DIR "${RPC_BINARY_DIR}" - BUILD_ALWAYS ON - CMAKE_ARGS - "-DCMAKE_TOOLCHAIN_FILE=${USE_ANDROID_TOOLCHAIN}" - "-DANDROID_PLATFORM=${ANDROID_PLATFORM}" - "-DANDROID_ABI=${ANDROID_ABI}" - "-DFASTRPC_LIBS=STUB" - "-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}" - "-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}" - INSTALL_COMMAND "" - ) - ExternalProject_Get_Property(proxy_rpc_android BINARY_DIR) - ExternalProject_Add_Step(proxy_rpc_android copy_binaries - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${BINARY_DIR}/libtvm_runtime.so ${BINARY_DIR}/librpc_env.so ${BINARY_DIR}/tvm_rpc - ${RPC_BINARY_DIR} - DEPENDEES install - ) - ExternalProject_Add(proxy_rpc_hexagon - SOURCE_DIR "${CMAKE_SOURCE_DIR}/apps/hexagon_proxy_rpc/cmake/hexagon" - INSTALL_DIR "${RPC_BINARY_DIR}" - BUILD_ALWAYS ON - CMAKE_ARGS - "-DCMAKE_C_COMPILER=${USE_HEXAGON_TOOLCHAIN}/Tools/bin/hexagon-clang" - "-DCMAKE_CXX_COMPILER=${USE_HEXAGON_TOOLCHAIN}/Tools/bin/hexagon-clang++" - "-DFASTRPC_LIBS=SKEL" - "-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}" - "-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}" - INSTALL_COMMAND "" - ) - ExternalProject_Get_Property(proxy_rpc_hexagon BINARY_DIR) - ExternalProject_Add_Step(proxy_rpc_hexagon copy_binaries - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${BINARY_DIR}/libhexagon_proxy_rpc_skel.so - ${RPC_BINARY_DIR} - DEPENDEES install - ) - - set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${RPC_BINARY_DIR}") + message(SEND_ERROR "USE_HEXAGON_PROXY_RPC is deprecated, please build apps separately") endif() -if(USE_HEXAGON_RPC) - if(DEFINED USE_ANDROID_TOOLCHAIN) - if(NOT DEFINED ANDROID_PLATFORM) - message(SEND_ERROR "Please set ANDROID_PLATFORM " - "when providing an Android cmake toolchain.") - endif() - if(NOT DEFINED ANDROID_ABI) - message(SEND_ERROR "Please set ANDROID_ABI " - "when providing an Android cmake toolchain.") - endif() - else() - message(SEND_ERROR "Please set USE_ANDROID_TOOLCHAIN to build the android " - "RPC server for Hexagon.") - endif() - - if(NOT DEFINED USE_HEXAGON_SDK) - message(SEND_ERROR "Please set USE_HEXAGON_SDK to build the android " - "RPC server for Hexagon RPC.") - endif() - if(NOT DEFINED USE_HEXAGON_ARCH) - message(SEND_ERROR "Please set USE_HEXAGON_ARCH to build the android " - "RPC server for Hexagon RPC.") - endif() - find_hexagon_sdk_root("${USE_HEXAGON_SDK}" "${USE_HEXAGON_ARCH}") +# find_hexagon_sdk_root has been called at this point. +if(USE_HEXAGON_RPC) set(HEXAGON_RPC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/hexagon_rpc") file(MAKE_DIRECTORY ${HEXAGON_RPC_OUTPUT}) - # Android Part - ExternalProject_Add(android_runtime_rpc - SOURCE_DIR "${CMAKE_SOURCE_DIR}" - BUILD_COMMAND $(MAKE) runtime tvm_rpc - CMAKE_ARGS - "-DCMAKE_TOOLCHAIN_FILE=${USE_ANDROID_TOOLCHAIN}" - "-DUSE_ANDROID_TOOLCHAIN=${USE_ANDROID_TOOLCHAIN}" - "-DANDROID_PLATFORM=${ANDROID_PLATFORM}" - "-DANDROID_ABI=${ANDROID_ABI}" - "-DCMAKE_CXX_STANDARD=14" - "-DUSE_LIBBACKTRACE=OFF" - "-DUSE_LLVM=OFF" - "-DUSE_RPC=ON" - "-DUSE_CPP_RPC=ON" - "-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}" - "-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}" - "-DCMAKE_VERBOSE_MAKEFILE=ON" - INSTALL_COMMAND "" - BUILD_ALWAYS ON - ) - ExternalProject_Get_Property(android_runtime_rpc BINARY_DIR) - ExternalProject_Add_Step(android_runtime_rpc copy_binary_runtime - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${BINARY_DIR}/libtvm_runtime.so - ${HEXAGON_RPC_OUTPUT}/libtvm_runtime.so - DEPENDEES install - ) - ExternalProject_Add_Step(android_runtime_rpc copy_binary_rpc - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${BINARY_DIR}/tvm_rpc - ${HEXAGON_RPC_OUTPUT}/tvm_rpc_android - DEPENDEES install - ) - - if("${USE_HEXAGON_TOOLCHAIN}" STREQUAL "") - message(SEND_ERROR "Please set USE_HEXAGON_TOOLCHAIN to build the hexagon " - "RPC SKEL.") - endif() - find_hexagon_toolchain() - message(STATUS "HEXAGON_TOOLCHAIN: ${HEXAGON_TOOLCHAIN}") + set(TVMRT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src/runtime") + set(QAIC_EXE "${HEXAGON_QAIC_EXE}") + foreach(INCDIR IN LISTS HEXAGON_SDK_INCLUDES HEXAGON_REMOTE_ROOT) + list(APPEND QAIC_FLAGS "-I${INCDIR}") + endforeach() - # Hexagon Part - ExternalProject_Add(hexagon_rpc_skel - SOURCE_DIR "${CMAKE_SOURCE_DIR}/cmake/libs/hexagon_rpc_skel" - INSTALL_DIR "${LAUNCHER_BINARY_DIR}" - CMAKE_ARGS - "-DCMAKE_C_COMPILER=${HEXAGON_TOOLCHAIN}/bin/hexagon-clang" - "-DCMAKE_CXX_COMPILER=${HEXAGON_TOOLCHAIN}/bin/hexagon-clang++" - "-DFASTRPC_LIBS=SKEL" - "-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}" - "-DUSE_HEXAGON_SDK=${USE_HEXAGON_SDK}" - INSTALL_COMMAND "" - BUILD_ALWAYS ON - ) - ExternalProject_Get_Property(hexagon_rpc_skel BINARY_DIR) - ExternalProject_Add_Step(hexagon_rpc_skel copy_hexagon_skel - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${BINARY_DIR}/libhexagon_rpc_skel.so - ${HEXAGON_RPC_OUTPUT}/libhexagon_rpc_skel.so - DEPENDEES install + add_custom_command( + OUTPUT + "${TVMRT_SOURCE_DIR}/hexagon/rpc/hexagon_rpc.h" + "${TVMRT_SOURCE_DIR}/hexagon/rpc/hexagon_rpc_skel.c" + "${TVMRT_SOURCE_DIR}/hexagon/rpc/hexagon_rpc_stub.c" + COMMAND + ${QAIC_EXE} ${QAIC_FLAGS} "${TVMRT_SOURCE_DIR}/hexagon/rpc/hexagon_rpc.idl" + -o "${TVMRT_SOURCE_DIR}/hexagon/rpc" + MAIN_DEPENDENCY "${TVMRT_SOURCE_DIR}/hexagon/rpc/hexagon_rpc.idl" ) - # copy android_bash template file - configure_file("${CMAKE_SOURCE_DIR}/src/runtime/hexagon/rpc/android_bash.sh.template" - ${HEXAGON_RPC_OUTPUT} COPYONLY) + if(BUILD_FOR_ANDROID) + # Android part + tvm_file_glob(GLOB RUNTIME_HEXAGON_SRCS src/runtime/hexagon/host/*.cc) + tvm_file_glob(GLOB RUNTIME_HEXAGON_SRCS "${TVMRT_SOURCE_DIR}/hexagon/rpc/android/*.cc") + list(APPEND RUNTIME_HEXAGON_SRCS "${TVMRT_SOURCE_DIR}/hexagon/rpc/hexagon_rpc_stub.c") + + # copy android_bash template file + configure_file("${TVMRT_SOURCE_DIR}/hexagon/rpc/android_bash.sh.template" + ${HEXAGON_RPC_OUTPUT} COPYONLY) + + elseif(BUILD_FOR_HEXAGON) + # Hexagon part + find_hexagon_toolchain() + message(STATUS "HEXAGON_TOOLCHAIN: ${HEXAGON_TOOLCHAIN}") + + add_library(hexagon_rpc_skel SHARED + "${TVMRT_SOURCE_DIR}/hexagon/rpc/hexagon_rpc_skel.c" + "${TVMRT_SOURCE_DIR}/hexagon/rpc/hexagon/rpc_server.cc" + "${TVMRT_SOURCE_DIR}/minrpc/minrpc_server.h" + "${TVMRT_SOURCE_DIR}/minrpc/rpc_reference.h" + "${TVMRT_SOURCE_DIR}/rpc/rpc_module.cc" + "${TVMRT_SOURCE_DIR}/rpc/rpc_endpoint.cc" + "${TVMRT_SOURCE_DIR}/rpc/rpc_session.cc" + "${TVMRT_SOURCE_DIR}/rpc/rpc_local_session.cc" + ) + target_include_directories(hexagon_rpc_skel + SYSTEM PRIVATE "${TVMRT_SOURCE_DIR}/hexagon/rpc" + ) + endif() set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${HEXAGON_RPC_OUTPUT}") - - # Used in `src/target/llvm/llvm_common.h` - add_definitions(-DTVM_USE_HEXAGON_LLVM) endif() if(USE_HEXAGON_DEVICE STREQUAL "${PICK_SIM}") @@ -344,7 +196,6 @@ if (USE_HEXAGON_DEVICE STREQUAL "${PICK_NONE}") if(BUILD_FOR_HEXAGON) tvm_file_glob(GLOB RUNTIME_HEXAGON_SRCS src/runtime/hexagon/hexagon/*.cc) elseif(BUILD_FOR_ANDROID AND HEXAGON_SDK_PATH_DEFINED) - list(APPEND RUNTIME_HEXAGON_SRCS src/runtime/hexagon/proxy_rpc/device_api.cc) else() tvm_file_glob(GLOB RUNTIME_HEXAGON_SRCS src/runtime/hexagon/host/*.cc) endif() @@ -352,33 +203,9 @@ else() tvm_file_glob(GLOB RUNTIME_HEXAGON_SRCS src/runtime/hexagon/android/*.cc) endif() -if(USE_HEXAGON_RPC) - file(GLOB RUNTIME_HEXAGON_SRCS src/runtime/hexagon/host/*.cc) -endif() - -if(USE_HEXAGON_SDK AND BUILD_FOR_ANDROID) - find_hexagon_sdk_root("${USE_HEXAGON_SDK}" "${USE_HEXAGON_ARCH}") - include_directories(SYSTEM ${HEXAGON_SDK_INCLUDES} ${HEXAGON_REMOTE_ROOT}) - - set(QAIC_EXE "${HEXAGON_QAIC_EXE}") - foreach(INCDIR IN LISTS HEXAGON_SDK_INCLUDES HEXAGON_REMOTE_ROOT) - list(APPEND QAIC_FLAGS "-I${INCDIR}") - endforeach() - - set(HEXAGON_RPC_DIR "${CMAKE_SOURCE_DIR}/src/runtime/hexagon/rpc") - set(RPC_IDL "hexagon_rpc.idl") - set(RPC_H "hexagon_rpc.h") - set(RPC_STUB_C "hexagon_rpc_stub.c") - - add_custom_command( - OUTPUT "${HEXAGON_RPC_DIR}/${RPC_STUB_C}" "${HEXAGON_RPC_DIR}/${RPC_H}" - COMMAND ${QAIC_EXE} ${QAIC_FLAGS} "${HEXAGON_RPC_DIR}/${RPC_IDL}" -o ${HEXAGON_RPC_DIR} - MAIN_DEPENDENCY "${HEXAGON_RPC_DIR}/${RPC_IDL}" - ) - file(GLOB HEXAGON_RPC_CPP "${HEXAGON_RPC_DIR}/android/*.cc") - set(HEXAGON_RPC_STUB_C "${HEXAGON_RPC_DIR}/${RPC_STUB_C}") -endif() - -list(APPEND RUNTIME_SRCS ${RUNTIME_HEXAGON_SRCS} ${RUNTIME_HEXAGON_SIM_SRCS} - ${RUNTIME_HEXAGON_DEVICE_SRCS} ${HEXAGON_RPC_CPP} ${HEXAGON_RPC_STUB_C} - ${RUNTIME_HEXAGON_COMMON_SRCS}) +list(APPEND RUNTIME_SRCS + ${RUNTIME_HEXAGON_SRCS} + ${RUNTIME_HEXAGON_SIM_SRCS} + ${RUNTIME_HEXAGON_DEVICE_SRCS} + ${RUNTIME_HEXAGON_COMMON_SRCS} +) diff --git a/src/runtime/hexagon/proxy_rpc/device_api.cc b/src/runtime/hexagon/proxy_rpc/device_api.cc deleted file mode 100644 index 2d4610423fd7..000000000000 --- a/src/runtime/hexagon/proxy_rpc/device_api.cc +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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. - */ - -/*! - * \file device_api.cc - * \brief Shim RPC Device API that forwards to/from Hexagon - * over FastRPC. - */ - -#if !defined(__ANDROID__) -#error HexagonRPCDeviceAPI is meant only for compilation on Android. -#endif - -#include -#include -#include - -#include "../hexagon/hexagon_common.h" - -namespace tvm { -namespace runtime { - -class MirroredBuffer { - public: - MirroredBuffer(Device dev, int ndim, const int64_t* shape, DLDataType dtype, - Optional scope) { - DLTensor t; - t.shape = const_cast(shape); - t.ndim = ndim; - t.dtype = dtype; - t.device = dev; - rpc_mem_size_ = GetDataSize(t); - rpc_mem_ = reinterpret_cast( - rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, rpc_mem_size_)); - - TVMValue value; - value.v_handle = &t; - TVMArgValue mem_scope; - if (scope.defined()) { - TVMValue s; - s.v_str = scope.value().c_str(); - mem_scope = TVMArgValue(s, kTVMStr); - } - - auto* f = runtime::Registry::Get("tvm.rpc.hexagon.allocate"); - hexagon_buffer_id_ = (*f)(TVMArgValue(value, kTVMDLTensorHandle), mem_scope); - } - void Read() { - auto* f = runtime::Registry::Get("tvm.rpc.hexagon.read_to_host"); - (*f)(rpc_mem_, rpc_mem_size_, hexagon_buffer_id_); - } - void Write() { - auto* f = runtime::Registry::Get("tvm.rpc.hexagon.write_from_host"); - (*f)(hexagon_buffer_id_, rpc_mem_, rpc_mem_size_); - } - ~MirroredBuffer() { - auto* f = runtime::Registry::Get("tvm.rpc.hexagon.release"); - (*f)(hexagon_buffer_id_); - rpcmem_free(rpc_mem_); - } - void* GetRPCMem() { return rpc_mem_; } - int32_t GetHexagonHandle() { return hexagon_buffer_id_; } - - private: - void* rpc_mem_ = nullptr; - size_t rpc_mem_size_ = 0; - int32_t hexagon_buffer_id_ = 0; -}; - -class HexagonRPCDeviceAPI final : public DeviceAPI { - public: - void* AllocDataSpace(Device dev, size_t nbytes, size_t alignment, DLDataType type_hint) final { - throw tvm::runtime::Error("HexagonRPCDeviceAPI::AllocDataSpace is unimplemented"); - } - void* AllocDataSpace(Device dev, int ndim, const int64_t* shape, DLDataType dtype, - Optional mem_scope) final { - return new MirroredBuffer(dev, ndim, shape, dtype, mem_scope); - } - void CopyDataFromTo(DLTensor* from, DLTensor* to, TVMStreamHandle stream) final { - ICHECK((IsHexagonDevice(from->device) && IsHexagonDevice(to->device)) == false) - << "Unimplimented"; - if (IsHexagonDevice(from->device) && to->device.device_type == kDLCPU) { - MirroredBuffer* mirror = static_cast(from->data); - mirror->Read(); - memcpy(static_cast(to->data) + to->byte_offset, - static_cast(mirror->GetRPCMem()) + from->byte_offset, GetDataSize(*from)); - } else if (from->device.device_type == kDLCPU && IsHexagonDevice(to->device)) { - MirroredBuffer* mirror = static_cast(to->data); - memcpy(static_cast(mirror->GetRPCMem()) + to->byte_offset, - static_cast(from->data) + from->byte_offset, GetDataSize(*from)); - mirror->Write(); - } else { - CHECK(false) << "Expect copy between DLTensor devices of types kDLHexagon and kDLCPU only."; - } - } - void FreeDataSpace(Device dev, void* ptr) final { - MirroredBuffer* mirror = static_cast(ptr); - delete mirror; - } - - void SetDevice(Device dev) final {} - void GetAttr(Device dev, DeviceAttrKind kind, TVMRetValue* rv) final { - if (kind == kExist) { - *rv = 1; - } - } - void StreamSync(Device dev, TVMStreamHandle stream) final {} - void* AllocWorkspace(Device dev, size_t size, DLDataType type_hint) final { - throw tvm::runtime::Error("HexagonRPCDeviceAPI::AllocWorkspace is unimplemented"); - }; - void FreeWorkspace(Device dev, void* data) final { - throw tvm::runtime::Error("HexagonRPCDeviceAPI::FreeWorkspace is unimplemented"); - }; - - static HexagonRPCDeviceAPI* Global() { - static auto* inst = new HexagonRPCDeviceAPI(); - return inst; - } - - protected: - void CopyDataFromTo(const void* from, size_t from_offset, void* to, size_t to_offset, size_t size, - Device dev_from, Device dev_to, DLDataType type_hint, - TVMStreamHandle stream) final { - throw tvm::runtime::Error("HexagonRPCDeviceAPI::CopyDataFromTo is unimplemented"); - } -}; - -TVM_REGISTER_GLOBAL("runtime.hexagon.GetHandle").set_body([](TVMArgs args, TVMRetValue* rv) { - auto* buf = static_cast(static_cast(args[0])); - *rv = buf->GetHexagonHandle(); -}); - -TVM_REGISTER_GLOBAL("device_api.hexagon").set_body([](TVMArgs args, TVMRetValue* rv) { - DeviceAPI* ptr = HexagonRPCDeviceAPI::Global(); - *rv = static_cast(ptr); -}); - -} // namespace runtime -} // namespace tvm From 4df5956c633ca6a19ec7184c933cc795852b0105 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 20 Jan 2022 09:03:24 -0800 Subject: [PATCH 2/4] Add README.md --- apps/hexagon_api/README.md | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 apps/hexagon_api/README.md diff --git a/apps/hexagon_api/README.md b/apps/hexagon_api/README.md new file mode 100644 index 000000000000..0903f169ad7f --- /dev/null +++ b/apps/hexagon_api/README.md @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + +# Hexagon API app + +This is a meta-app that build the necessary binaries for use with +the `HexagonLauncher` utility from `tvm.contrib.hexagon`. + +It will build the TVM runtime for Android, the RPC server application +for Android, and the RPC library for Hexagon with the TVM runtime for +Hexagon built into it. + +## Configuration + +There is a set of configuration variables that are required for cmake: +- `ANDROID_ABI`: Set this to `arm64-v8a`. +- `ANDROID_PLATFORM`: This can be `android-28`. +- `USE_ANDROID_TOOLCHAIN`: The path to the Android toolchain file, i.e. +`android.toolchain.cmake`. This file is a part of the Android NDK. +- `USE_HEXAGON_ARCH`: The version string of the Hexagon architecture +to use, i.e. vNN. The typical setting would be `v68` or later. +- `USE_HEXAGON_SDK`: The path to the Hexagon SDK. Set this path in such +a way that `${USE_HEXAGON_SDK}/setup_sdk_env.source` exists. +- `USE_HEXAGON_TOOLCHAIN`: Path to Hexagon toolchain. It can be the +Hexagon toolchain included in the SDK, for example +`${USE_HEXAGON_TOOLCHAIN}/tools/HEXAGON_Tools/x.y.z/Tools`. The `x.y.z` +in the path is the toolchain version number, which is specific to the +version of the SDK. + +## Build + +The build will create a subdirectory `hexagon_rpc` with the following +binaries +- `tvm_runtime.so`: TVM runtime for Android (shared library). +- `tvm_rpc_android`: RPC server for Android. +- `libhexagon_rpc_skel.so`: RPC library for Hexagon. +- `libtvm_runtime.a`: TVM runtime for Hexagon (static library). + +The RPC library for Hexagon contains the TVM runtime, so the static +TVM runtime for Hexagon is not strictly necessary. From 4986594331f12bdc47b511010c83cc18df7dd0b0 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 20 Jan 2022 12:40:31 -0800 Subject: [PATCH 3/4] Restart CI From a851a47b5344ff9ead09b5e1f35e9c5420c9a290 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 20 Jan 2022 14:17:32 -0800 Subject: [PATCH 4/4] Add optional variable to set output directory --- apps/hexagon_api/CMakeLists.txt | 9 ++++++++- apps/hexagon_api/README.md | 8 ++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/hexagon_api/CMakeLists.txt b/apps/hexagon_api/CMakeLists.txt index 4f0e724cce9a..3c5eb616f1da 100644 --- a/apps/hexagon_api/CMakeLists.txt +++ b/apps/hexagon_api/CMakeLists.txt @@ -11,10 +11,17 @@ include(ExternalProject) # USE_HEXAGON_ARCH # USE_HEXAGON_SDK # USE_HEXAGON_TOOLCHAIN (Path to Hexagon toolchain ending with "Tools") +# Optional variable: +# USE_OUTPUT_BINARY_DIR (Path to copy the output binaries to) set(TVM_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../..") -set(HEXAGON_API_BINARY_DIR "${CMAKE_BINARY_DIR}/hexagon_rpc") +if(DEFINED USE_OUTPUT_BINARY_DIR) + set(HEXAGON_API_BINARY_DIR "${USE_OUTPUT_BINARY_DIR}") +else() + set(HEXAGON_API_BINARY_DIR "${CMAKE_BINARY_DIR}/hexagon_rpc") +endif() +file(MAKE_DIRECTORY ${HEXAGON_API_BINARY_DIR}) # Build Android binaries: # - libtvm_runtime.so diff --git a/apps/hexagon_api/README.md b/apps/hexagon_api/README.md index 0903f169ad7f..cddb3e90d699 100644 --- a/apps/hexagon_api/README.md +++ b/apps/hexagon_api/README.md @@ -41,10 +41,14 @@ Hexagon toolchain included in the SDK, for example in the path is the toolchain version number, which is specific to the version of the SDK. +Additionally, the variable `USE_OUTPUT_BINARY_DIR` can be set to indicate +the location where the generated binaries will be placed. If not set, it +defaults to `hexagon_rpc` subdirectory in the current build directory. + + ## Build -The build will create a subdirectory `hexagon_rpc` with the following -binaries +The build will generate the following binaries: - `tvm_runtime.so`: TVM runtime for Android (shared library). - `tvm_rpc_android`: RPC server for Android. - `libhexagon_rpc_skel.so`: RPC library for Hexagon.