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

[RUNTIME] Initial implementation of Hexagon runtime support #5252

Merged
merged 12 commits into from
Apr 10, 2020
53 changes: 50 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ tvm_option(USE_OPENGL "Build with OpenGL" OFF)
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_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)
Expand Down Expand Up @@ -78,7 +80,7 @@ include_directories(${PICOJSON_PATH})

# initial variables
set(TVM_LINKER_LIBS "")
set(TVM_RUNTIME_LINKER_LIBS ${CMAKE_DL_LIBS})
set(TVM_RUNTIME_LINKER_LIBS "")

# Generic compilation options
if(MSVC)
Expand Down Expand Up @@ -118,8 +120,33 @@ else(MSVC)
CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
set(CMAKE_CXX_FLAGS "-faligned-new ${CMAKE_CXX_FLAGS}")
endif()

# Detect if we're compiling for Hexagon.
set(TEST_FOR_HEXAGON_CXX
"#ifndef __hexagon__"
"#error"
"#endif"
"int main() {}"
# Define _start_main to avoid linking errors with -fPIC.
"extern \"C\" void _start_main() {}")
set(TEST_FOR_HEXAGON_DIR
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp")
set(TEST_FOR_HEXAGON_FILE "${TEST_FOR_HEXAGON_DIR}/test_for_hexagon.cc")
string(REPLACE ";" "\n" TEST_FOR_HEXAGON_CXX_TEXT "${TEST_FOR_HEXAGON_CXX}")
file(WRITE "${TEST_FOR_HEXAGON_FILE}" "${TEST_FOR_HEXAGON_CXX_TEXT}")
try_compile(BUILD_FOR_HEXAGON "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}"
"${TEST_FOR_HEXAGON_FILE}")
file(REMOVE "${TEST_FOR_HEXAGON_FILE}")
if(BUILD_FOR_HEXAGON)
message(STATUS "Building for Hexagon")
endif()
endif(MSVC)

# Hexagon has dlopen built into QuRT (no need for static library).
if(NOT BUILD_FOR_HEXAGON)
string(APPEND TVM_RUNTIME_LINKER_LIBS ${CMAKE_DL_LIBS})
endif()

# add source group
FILE(GLOB_RECURSE GROUP_SOURCE "src/*.cc")
FILE(GLOB_RECURSE GROUP_INCLUDE "src/*.h" "include/*.h")
Expand Down Expand Up @@ -177,6 +204,13 @@ if(USE_VM_PROFILER)
list(APPEND COMPILER_SRCS ${BACKEND_VM_PROFILER_SRCS})
endif(USE_VM_PROFILER)

if(BUILD_FOR_HEXAGON)
# Add file implementing posix_memalign.
list(APPEND RUNTIME_SRCS src/runtime/hexagon/hexagon_posix.cc)

add_definitions(-D_MACH_I32=int)
endif()

file(GLOB DATATYPE_SRCS src/target/datatype/*.cc)
list(APPEND COMPILER_SRCS ${DATATYPE_SRCS})

Expand Down Expand Up @@ -242,6 +276,7 @@ endif(USE_EXAMPLE_EXT_RUNTIME)
# Module rules
include(cmake/modules/VTA.cmake)
include(cmake/modules/CUDA.cmake)
include(cmake/modules/Hexagon.cmake)
include(cmake/modules/OpenCL.cmake)
include(cmake/modules/OpenGL.cmake)
include(cmake/modules/OpenMP.cmake)
Expand Down Expand Up @@ -283,15 +318,27 @@ else()
set_target_properties(tvm PROPERTIES COMPILE_DEFINITIONS "NDEBUG")
endif(USE_RELAY_DEBUG)

if(USE_THREADS)
if(BUILD_FOR_HEXAGON)
# Wrap pthread_create to allow setting custom stack size.
set_target_properties(tvm_runtime PROPERTIES LINK_FLAGS
"-Wl,--wrap=pthread_create")

target_include_directories(tvm_runtime
PUBLIC "${USE_HEXAGON_SDK}/libs/common/qurt/ADSPv62MP/include/posix"
PUBLIC "${USE_HEXAGON_SDK}/libs/common/qurt/ADSPv62MP/include/qurt"
PUBLIC "${USE_HEXAGON_SDK}/incs"
PUBLIC "${USE_HEXAGON_SDK}/incs/stddef")
endif()

if(USE_THREADS AND NOT BUILD_FOR_HEXAGON)
message(STATUS "Build with thread support...")
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
target_link_libraries(tvm Threads::Threads)
target_link_libraries(tvm_topi Threads::Threads)
target_link_libraries(tvm_runtime Threads::Threads)
endif(USE_THREADS)
endif()

target_link_libraries(tvm ${TVM_LINKER_LIBS} ${TVM_RUNTIME_LINKER_LIBS})
target_link_libraries(tvm_topi tvm ${TVM_LINKER_LIBS} ${TVM_RUNTIME_LINKER_LIBS})
Expand Down
3 changes: 3 additions & 0 deletions cmake/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,6 @@ set(USE_THRUST OFF)
# Whether to build the TensorFlow TVMDSOOp module
set(USE_TF_TVMDSOOP OFF)

# Whether to use hexagon device
set(USE_HEXAGON_DEVICE OFF)
set(USE_HEXAGON_SDK /path/to/sdk)
96 changes: 96 additions & 0 deletions cmake/modules/Hexagon.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# 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.

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

function(find_hexagon_toolchain)
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")
else(HEXAGON_CLANG)
message(SEND_ERROR "Cannot find Hexagon toolchain in ${TRY_PATH}")
endif()
endfunction()

function(find_hexagon_sdk_root)
message(STATUS "Checking Hexagon SDK root: ${USE_HEXAGON_SDK}")
file(GLOB_RECURSE HEXAGON_AEESTDDEF "${USE_HEXAGON_SDK}/*/AEEStdDef.h")
if(HEXAGON_AEESTDDEF)
# The path is ${HEXAGON_SDK_ROOT}/incs/stddef/AEEStdDef.h.
get_filename_component(HEXAGON_TMP0 "${HEXAGON_AEESTDDEF}" DIRECTORY)
get_filename_component(HEXAGON_TMP1 "${HEXAGON_TMP0}" DIRECTORY)
get_filename_component(HEXAGON_TMP2 "${HEXAGON_TMP1}" DIRECTORY)
set(HEXAGON_SDK_ROOT "${HEXAGON_TMP2}" CACHE PATH
"Root directory of Hexagon SDK")
else(HEXAGON_AEESTDDEF)
message(SEND_ERROR "Cannot validate Hexagon SDK in ${USE_HEXAGON_SDK}")
endif()
endfunction()

if(USE_HEXAGON_DEVICE STREQUAL "OFF")
list(APPEND COMPILER_SRCS src/target/opt/build_hexagon_off.cc)
return()
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 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(USE_HEXAGON_DEVICE STREQUAL "${PICK_SIM}")
find_hexagon_toolchain()
message(STATUS "Hexagon toolchain: ${HEXAGON_TOOLCHAIN}")
file(GLOB RUNTIME_HEXAGON_SIM_SRCS src/runtime/hexagon/sim/*.cc)
include_directories("${HEXAGON_TOOLCHAIN}/include/iss")
link_directories("${HEXAGON_TOOLCHAIN}/lib/iss")
list(APPEND TVM_RUNTIME_LINKER_LIBS "-lwrapper")
elseif(USE_HEXAGON_DEVICE STREQUAL "${PICK_HW}")
find_hexagon_sdk_root()
find_hexagon_toolchain()
message(STATUS "Hexagon SDK: ${HEXAGON_SDK_ROOT}")
file(GLOB RUNTIME_HEXAGON_DEVICE_SRCS src/runtime/hexagon/target/*.cc)
include_directories("${HEXAGON_SDK_ROOT}/incs/stddef")
include_directories("${HEXAGON_SDK_ROOT}/libs/common/rpcmem/inc")
include_directories(
"${HEXAGON_SDK_ROOT}/libs/common/remote/ship/android_Release_aarch64")
include_directories("${HEXAGON_TOOLCHAIN}/include/iss")
list(APPEND TVM_RUNTIME_LINKER_LIBS "-ldl")
endif()

file(GLOB RUNTIME_HEXAGON_SRCS src/runtime/hexagon/*.cc)
list(APPEND RUNTIME_SRCS ${RUNTIME_HEXAGON_SRCS} ${RUNTIME_HEXAGON_SIM_SRCS}
${RUNTIME_HEXAGON_DEVICE_SRCS})

1 change: 1 addition & 0 deletions include/tvm/runtime/c_runtime_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ typedef enum {
kDLSDAccel = 6,
kOpenGL = 11,
kDLMicroDev = 13,
kDLHexagon = 14,
// AddExtraTVMType which is not in DLPack here
} TVMDeviceExtType;

Expand Down
5 changes: 3 additions & 2 deletions include/tvm/runtime/device_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ enum DeviceAttrKind : int {
};

/*! \brief Number of bytes each allocation must align to */
constexpr int kAllocAlignment = 64;
constexpr int kAllocAlignment = 128;
tmoreau89 marked this conversation as resolved.
Show resolved Hide resolved

/*! \brief Number of bytes each allocation must align to in temporary allocation */
constexpr int kTempAllocaAlignment = 64;
constexpr int kTempAllocaAlignment = 128;

/*! \brief Maximum size that can be allocated on stack */
constexpr int kMaxStackAlloca = 1024;
Expand Down Expand Up @@ -218,6 +218,7 @@ inline const char* DeviceName(int type) {
case kOpenGL: return "opengl";
case kDLExtDev: return "ext_dev";
case kDLMicroDev: return "micro_dev";
case kDLHexagon: return "hexagon";
default: LOG(FATAL) << "unknown type =" << type; return "Unknown";
}
}
Expand Down
4 changes: 4 additions & 0 deletions include/tvm/target/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ TVM_DLL Target stackvm(const std::vector<std::string>& options =
/*! \return A target for external device */
TVM_DLL Target ext_dev(const std::vector<std::string>& options =
std::vector<std::string>());

/*! \return A target for hexagon */
TVM_DLL Target hexagon(const std::vector<std::string>& options =
std::vector<std::string>());
} // namespace target

/*!
Expand Down
15 changes: 15 additions & 0 deletions jvm/core/src/main/java/org/apache/tvm/TVMContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class TVMContext {
MASK2STR.put(7, "vulkan");
MASK2STR.put(8, "metal");
MASK2STR.put(9, "vpi");
MASK2STR.put(14, "hexagon");

STR2MASK.put("cpu", 1);
STR2MASK.put("gpu", 2);
Expand All @@ -42,6 +43,7 @@ public class TVMContext {
STR2MASK.put("vulkan", 7);
STR2MASK.put("metal", 8);
STR2MASK.put("vpi", 9);
STR2MASK.put("hexagon", 14);
}

/**
Expand Down Expand Up @@ -122,6 +124,19 @@ public static TVMContext vpi() {
return vpi(0);
}

/**
* Construct a Hexagon device.
* @param devId The device id
* @return The created context
*/
public static TVMContext hexagon(int devId) {
return new TVMContext(14, devId);
}

public static TVMContext hexagon() {
return hexagon(0);
}

public final int deviceType;
public final int deviceId;

Expand Down
2 changes: 1 addition & 1 deletion python/tvm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
# tvm.runtime
from .runtime.object import Object
from .runtime.ndarray import context, cpu, gpu, opencl, cl, vulkan, metal, mtl
from .runtime.ndarray import vpi, rocm, opengl, ext_dev, micro_dev
from .runtime.ndarray import vpi, rocm, opengl, ext_dev, micro_dev, hexagon
from .runtime import ndarray as nd

# tvm.error
Expand Down
2 changes: 2 additions & 0 deletions python/tvm/_ffi/runtime_ctypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class TVMContext(ctypes.Structure):
11: 'opengl',
12: 'ext_dev',
13: 'micro_dev',
14: 'hexagon',
}
STR2MASK = {
'llvm': 1,
Expand All @@ -166,6 +167,7 @@ class TVMContext(ctypes.Structure):
'opengl': 11,
'ext_dev': 12,
'micro_dev': 13,
'hexagon': 14,
}
def __init__(self, device_type, device_id):
super(TVMContext, self).__init__()
Expand Down
16 changes: 16 additions & 0 deletions python/tvm/runtime/ndarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,22 @@ def micro_dev(dev_id=0):
return TVMContext(13, dev_id)


def hexagon(dev_id=0):
"""Construct a Hexagon device
Parameters
----------
dev_id : int, optional
The integer device id
Returns
-------
ctx : TVMContext
The created context
"""
return TVMContext(14, dev_id)


cl = opencl
mtl = metal

Expand Down
2 changes: 1 addition & 1 deletion python/tvm/target/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
We can also use other specific function in this module to create specific targets.
"""
from .target import Target, create
from .target import cuda, rocm, mali, intel_graphics, opengl, arm_cpu, rasp, vta, bifrost
from .target import cuda, rocm, mali, intel_graphics, opengl, arm_cpu, rasp, vta, bifrost, hexagon
from .generic_func import GenericFunc
from .generic_func import generic_func, get_native_generic_func, override_native_generic_func
from . import datatype
Expand Down
Loading