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 #3163

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Expand Up @@ -27,6 +27,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 "Build with Hexagon" OFF)
tvm_option(USE_HEXAGON_SDK "Path to the Hexagon SDK root (required for Hexagon support)" /path/to/sdk)
kparzysz-quic marked this conversation as resolved.
Show resolved Hide resolved
tvm_option(USE_RPC "Build with RPC" ON)
tvm_option(USE_LLVM "Build with LLVM, can be set to specific llvm-config path" OFF)
tvm_option(USE_STACKVM_RUNTIME "Include stackvm into the runtime" OFF)
Expand Down Expand Up @@ -201,6 +203,7 @@ endif(USE_GRAPH_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/Vulkan.cmake)
Expand Down
14 changes: 14 additions & 0 deletions NOTICE
@@ -1 +1,15 @@
TVM End to End Deep Learning Compiler Stack: https://tvm.ai/

This product includes contributions provided by Qualcomm Technologies, Inc.,
a Delaware corporation, or its subsidiary Qualcomm Innovation Center, Inc.,
a California corporation, under certain additional terms and conditions
pursuant to Section 5 of the Apache 2.0 license. In this regard, with
respect to these Contributions, the term "Work" in Section 1 of the
Apache 2.0 license means only the specific subdirectory within the TVM repo
(currently at https://github.com/dmlc/tvm) to which these Contribution were
made.
In any case, these submissions are "Not a Contribution" with respect to its
permitted use with any of the "vta" and "verilog" subdirectories in the TVM
repo.
Qualcomm Technologies, Inc. and Qualcomm Innovation Center, Inc. retain
copyright of their respective Contributions.
3 changes: 3 additions & 0 deletions cmake/config.cmake
Expand Up @@ -135,3 +135,6 @@ set(USE_ANTLR OFF)
# Whether use Relay debug mode
set(USE_RELAY_DEBUG OFF)

# Whether to use hexagon device
set(USE_HEXAGON OFF)
set(USE_HEXAGON_SDK /path/to/sdk)
104 changes: 104 additions & 0 deletions cmake/modules/Hexagon.cmake
@@ -0,0 +1,104 @@
# 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.

# This Contribution is being provided by Qualcomm Technologies, Inc.,
# a Delaware corporation, or its subsidiary Qualcomm Innovation Center, Inc.,
# a California corporation, under certain additional terms and conditions
# pursuant to Section 5 of the Apache 2.0 license. In this regard, with
# respect to this Contribution, the term "Work" in Section 1 of the
# Apache 2.0 license means only the specific subdirectory within the TVM repo
# (currently at https://github.com/dmlc/tvm) to which this Contribution is
# made.
# In any case, this submission is "Not a Contribution" with respect to its
# permitted use with any of the "vta" and "verilog" subdirectories in the TVM
# repo.
# Qualcomm Technologies, Inc. and Qualcomm Innovation Center, Inc. retain
# copyright of their respective Contributions.

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 STREQUAL "OFF")
return()
elseif(NOT USE_HEXAGON STREQUAL "sim" AND
NOT USE_HEXAGON STREQUAL "device")
message(SEND_ERROR "USE_HEXAGON must be one of [OFF|sim|device]")
return()
endif()
# If USE_HEXAGON 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 STREQUAL "sim")
find_hexagon_toolchain()
message(STATUS "Hexagon toolchain: ${HEXAGON_TOOLCHAIN}")
add_definitions("-DHEXAGON_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 STREQUAL "device")
find_hexagon_sdk_root()
find_hexagon_toolchain()
message(STATUS "Hexagon SDK: ${HEXAGON_SDK_ROOT}")
add_definitions("-DHEXAGON_TOOLCHAIN=\"${HEXAGON_TOOLCHAIN}\"")
file(GLOB RUNTIME_HEXAGON_DEVICE_SRCS src/runtime/hexagon/device/*.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")
include_directories("${HEXAGON_TOOLCHAIN}/include/iss")
list(APPEND TVM_RUNTIME_LINKER_LIBS "-ldl")
endif()

add_definitions("-DDMLC_LOG_FATAL_THROW=0")
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
Expand Up @@ -82,6 +82,7 @@ typedef enum {
kDLSDAccel = 6,
kOpenGL = 11,
// AddExtraTVMType which is not in DLPack here
Copy link
Member

Choose a reason for hiding this comment

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

Move this comment after kDLHexagon = 13

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do.

kDLHexagon = 13,
} TVMDeviceExtType;

/*!
Expand Down
5 changes: 3 additions & 2 deletions include/tvm/runtime/device_api.h
Expand Up @@ -46,10 +46,10 @@ enum DeviceAttrKind : int {
};

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

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

Choose a reason for hiding this comment

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

How about this? https://github.com/dmlc/tvm/blob/master/src/pass/ir_util.h#L174 I think we should handle it specially for Hexagon.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Someone suggested having a target-specific function that gets the required alignment, instead of having global constants. I think that would be a better solution. This patch simply has what we've done about it.
I haven't looked into it yet, is there a precedent for implementing such a thing? Do you have any suggestions as to how it should be done?

Copy link
Member

Choose a reason for hiding this comment

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

I also suggest we have a target-specific function that gets the required alignment. Then in GetTempAllocaAlignment we could get this alignment and just simply return it for Hexagon (Need detect the target is Hexagon, for example we define the macro USE_HEXAGON in CMakeLists.txt).

Copy link
Member

Choose a reason for hiding this comment

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

Same comment. How about create target-specific function alignment?


/*! \brief Maximum size that can be allocated on stack */
constexpr int kMaxStackAlloca = 1024;
Expand Down Expand Up @@ -215,6 +215,7 @@ inline const char* DeviceName(int type) {
case kDLROCM: return "rocm";
case kOpenGL: return "opengl";
case kDLExtDev: return "ext_dev";
case kDLHexagon: return "hexagon";
default: LOG(FATAL) << "unknown type =" << type; return "Unknown";
}
}
Expand Down
2 changes: 1 addition & 1 deletion python/tvm/__init__.py
Expand Up @@ -42,7 +42,7 @@

from . import ndarray as nd
from .ndarray import context, cpu, gpu, opencl, cl, vulkan, metal, mtl
from .ndarray import vpi, rocm, opengl, ext_dev
from .ndarray import vpi, rocm, opengl, ext_dev, hexagon

from ._ffi.runtime_ctypes import TypeCode, TVMType
from ._ffi.ndarray import TVMContext
Expand Down
2 changes: 2 additions & 0 deletions python/tvm/_ffi/runtime_ctypes.py
Expand Up @@ -143,6 +143,7 @@ class TVMContext(ctypes.Structure):
10: 'rocm',
11: 'opengl',
12: 'ext_dev',
13: 'hexagon',
}
STR2MASK = {
'llvm': 1,
Expand All @@ -163,6 +164,7 @@ class TVMContext(ctypes.Structure):
'rocm': 10,
'opengl': 11,
'ext_dev': 12,
'hexagon': 13,
}
def __init__(self, device_type, device_id):
super(TVMContext, self).__init__()
Expand Down
15 changes: 15 additions & 0 deletions python/tvm/ndarray.py
Expand Up @@ -188,6 +188,21 @@ def ext_dev(dev_id=0):
"""
return TVMContext(12, 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(13, dev_id)


cl = opencl
mtl = metal
Expand Down
4 changes: 4 additions & 0 deletions python/tvm/rpc/client.py
Expand Up @@ -175,6 +175,10 @@ def ext_dev(self, dev_id=0):
"""Construct extension device."""
return self.context(12, dev_id)

def hexagon(self, dev_id=0):
"""Construct extension device."""
Copy link
Member

Choose a reason for hiding this comment

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

extension be Hexagon

return self.context(13, dev_id)


class LocalSession(RPCSession):
"""RPCSession interface backed by local environment.
Expand Down
12 changes: 12 additions & 0 deletions python/tvm/target.py
Expand Up @@ -495,6 +495,18 @@ def vta(model='unknown', options=None):
ret = _api_internal._TargetCreate("ext_dev", *opts)
return ret

def hexagon(options=None):
"""Returns a Hexagon target.

Parameters
----------
options : str or list of str
Additional options
"""
# No extra options, but pass an empty list instead of None to avoid
# an assertion in packed_func.h in conversion to std::string().
opts = _merge_opts([], options)
return _api_internal._TargetCreate("hexagon", *opts)

def create(target_str):
"""Get a target given target string.
Expand Down
7 changes: 5 additions & 2 deletions src/codegen/build_module.cc
Expand Up @@ -44,8 +44,8 @@ TVM_STATIC_IR_FUNCTOR(IRPrinter, vtable)
/*!
* \brief Construct a Target node from the given name and options.
* \param target_name The major target name. Should be one of
* {"aocl", "aocl_sw_emu", "c", "cuda", "ext_dev", "hybrid", "llvm", "metal",
* "nvptx", "opencl", "opengl", "rocm", "sdaccel", "stackvm", "vulkan"}
* {"aocl", "aocl_sw_emu", "c", "cuda", "ext_dev", "hexagon", "hybrid", "llvm",
* "metal","nvptx", "opencl", "opengl", "rocm", "sdaccel", "stackvm", "vulkan"}
* \param options Additional options appended to the target
* \return The constructed Target
*/
Expand Down Expand Up @@ -132,6 +132,9 @@ Target CreateTarget(const std::string& target_name,
t->device_type = kDLExtDev;
} else if (target_name == "hybrid") {
t->device_type = kDLCPU;
} else if (target_name == "hexagon") {
t->keys_array.push_back(ir::StringImm::make("hexagon"));
t->device_type = kDLHexagon;
} else {
LOG(ERROR) << "Unknown target name " << target_name;
return target::stackvm();
Expand Down