From df1a857929f7355274f3cef96a76e991d0e6ce75 Mon Sep 17 00:00:00 2001 From: Chris Sullivan Date: Tue, 5 Oct 2021 22:30:00 -0700 Subject: [PATCH 1/9] Compile hexagon device api from runtime/hexagon/hexagon when building for hexagon and USE_HEXAGON_DEVICE is not set. --- cmake/modules/Hexagon.cmake | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/cmake/modules/Hexagon.cmake b/cmake/modules/Hexagon.cmake index 1491a4558611..224c505ab958 100644 --- a/cmake/modules/Hexagon.cmake +++ b/cmake/modules/Hexagon.cmake @@ -53,18 +53,22 @@ if(BUILD_FOR_HEXAGON) include_directories(SYSTEM ${HEXAGON_SDK_INCLUDES} ${HEXAGON_QURT_INCLUDES}) endif() -if(USE_HEXAGON_LAUNCHER STREQUAL "ON") - set(USE_HEXAGON_DEVICE "${PICK_SIM}") -else() - 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() +# Don't run these checks when compiling Hexagon device code, +# e.g. when compiling the TVM runtime for Hexagon. +if (NOT BUILD_FOR_HEXAGON) + if(USE_HEXAGON_LAUNCHER STREQUAL "ON") + set(USE_HEXAGON_DEVICE "${PICK_SIM}") + else() + 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() endif() endif() From 27f21f7d42921ca97c1992994a5410e850c594f9 Mon Sep 17 00:00:00 2001 From: Chris Sullivan Date: Wed, 20 Oct 2021 16:04:06 -0700 Subject: [PATCH 2/9] Add hexagon_common.h utilities including custom tvm runtime logging for hexagon. --- src/runtime/hexagon/hexagon/hexagon_common.cc | 61 +++++++++++++++++++ src/runtime/hexagon/hexagon/hexagon_common.h | 50 +++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 src/runtime/hexagon/hexagon/hexagon_common.cc create mode 100644 src/runtime/hexagon/hexagon/hexagon_common.h diff --git a/src/runtime/hexagon/hexagon/hexagon_common.cc b/src/runtime/hexagon/hexagon/hexagon_common.cc new file mode 100644 index 000000000000..28f1fe841d49 --- /dev/null +++ b/src/runtime/hexagon/hexagon/hexagon_common.cc @@ -0,0 +1,61 @@ +/* + * 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 hexagon_common.cc + */ + +#include "hexagon_common.h" +#include + +#include +#include + +namespace { +std::vector SplitString(const std::string& str, char delim) { + std::vector lines; + auto ss = std::stringstream{str}; + for (std::string line; std::getline(ss, line, delim);) { + lines.push_back(line); + } + return lines; +} +void HexagonLog(const std::string& file, int lineno, const std::string& message) { + HEXAGON_PRINT(ALWAYS, "%s:%d:", file.c_str(), lineno); + std::vector err_lines = SplitString(message, '\n'); + for (auto& line : err_lines) { + HEXAGON_PRINT(ALWAYS, "%s", line.c_str()); + } +} +} // namespace + +namespace tvm { +namespace runtime { +namespace detail { +void LogFatalImpl(const std::string& file, int lineno, const std::string& message) { + HexagonLog(file, lineno, message); + throw InternalError(file, lineno, message); +} +void LogMessageImpl(const std::string& file, int lineno, const std::string& message) { + HexagonLog(file, lineno, message); +} + +} // namespace detail +} // namespace runtime +} // namespace tvm diff --git a/src/runtime/hexagon/hexagon/hexagon_common.h b/src/runtime/hexagon/hexagon/hexagon_common.h new file mode 100644 index 000000000000..23f7a28f1431 --- /dev/null +++ b/src/runtime/hexagon/hexagon/hexagon_common.h @@ -0,0 +1,50 @@ +/* + * 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 hexagon_utils.h + */ +#ifndef TVM_RUNTIME_HEXAGON_HEXAGON_COMMON_H_ +#define TVM_RUNTIME_HEXAGON_HEXAGON_COMMON_H_ + +#include +#include + +#if defined(__hexagon__) +#include +#define HEXAGON_PRINT(level, ...) FARF(level, __VA_ARGS__) +#else +#include +#define HEXAGON_PRINT(level, ...) printf(__VA_ARGS__) +#endif + +#define HEXAGON_SAFE_CALL(api_call) \ + do { \ + int result = api_call; \ + if (result != 0) { \ + HEXAGON_PRINT(ERROR, "ERROR: " #api_call " failed with error %d.", result); \ + } \ + } while (0) + + +inline bool IsHexagonDevice(DLDevice dev) { + return TVMDeviceExtType(dev.device_type) == kDLHexagon; +} + +#endif // TVM_RUNTIME_HEXAGON_HEXAGON_UTILS_H_ From fdbc9e0aeaefad3fc157791738ad8e13af69756f Mon Sep 17 00:00:00 2001 From: Chris Sullivan Date: Wed, 20 Oct 2021 21:56:01 -0700 Subject: [PATCH 3/9] Introduce HexagonBuffer class to store hexagon allocation metadata. --- src/runtime/hexagon/hexagon/hexagon_buffer.cc | 115 +++++++++++++++ src/runtime/hexagon/hexagon/hexagon_buffer.h | 136 ++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 src/runtime/hexagon/hexagon/hexagon_buffer.cc create mode 100644 src/runtime/hexagon/hexagon/hexagon_buffer.h diff --git a/src/runtime/hexagon/hexagon/hexagon_buffer.cc b/src/runtime/hexagon/hexagon/hexagon_buffer.cc new file mode 100644 index 000000000000..455980840f4f --- /dev/null +++ b/src/runtime/hexagon/hexagon/hexagon_buffer.cc @@ -0,0 +1,115 @@ +/* + * 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 "hexagon_buffer.h" + +#include + +#include "hexagon_common.h" + +namespace tvm { +namespace runtime { +namespace hexagon { + +static size_t GetDataAlignment(const DLDataType dtype) { + size_t align = (dtype.bits / 8) * dtype.lanes; + if (align < kAllocAlignment) return kAllocAlignment; + return align; +} + +HexagonBuffer::HexagonBuffer(int ndim, const int64_t* shape, DLDataType dtype, + Optional scope) { + ICHECK_LE(ndim, 1) << "Hexagon currently only supports flat allocations " + << "and arrays of flat allocations."; + + size_t alignment = GetDataAlignment(dtype); + // TODO(csullivan): Extend to support arrays of allocations. + // Move assignment from r-value constructed flat allocation. + *this = HexagonBuffer(shape[0] * (dtype.bits / 8) * dtype.lanes, alignment, scope); +} + +HexagonBuffer::HexagonBuffer(size_t nbytes, size_t alignment, Optional scope) { + void* ptr = nullptr; + int ret = posix_memalign(&ptr, alignment, nbytes); + if (ret != 0) { + throw std::bad_alloc(); + } + allocations_.push_back(ptr); + SetStorageScope(scope); +} + +HexagonBuffer::HexagonBuffer(void* data, Optional scope) : managed_{false} { + SetStorageScope(scope); + allocations_.push_back(data); +} + +HexagonBuffer::~HexagonBuffer() { + if (managed_) { + for (auto& ptr : allocations_) { + free(ptr); + } + } +} + +HexagonBuffer::HexagonBuffer(HexagonBuffer&& other) + : allocations_(other.allocations_), managed_(other.managed_), storage_scope_(other.storage_scope_) { + other.allocations_.clear(); + other.managed_ = false; + other.storage_scope_ = StorageScope::kDDR; +} + +HexagonBuffer& HexagonBuffer::operator=(HexagonBuffer&& other) { + std::swap(allocations_, other.allocations_); + std::swap(managed_, other.managed_); + std::swap(storage_scope_, other.storage_scope_); + return *this; +} + +void* HexagonBuffer::GetPointer() { + if (!allocations_.size()) { return nullptr; } + return (allocations_.size() > 1) ? allocations_.data() : allocations_[0]; +} + +HexagonBuffer::StorageScope HexagonBuffer::GetStorageScope() const { return storage_scope_; } + +void HexagonBuffer::SetStorageScope(Optional scope) { + if (!scope.defined()) { + storage_scope_ = StorageScope::kDDR; + } else { + if (scope.value() == "global") { + storage_scope_ = StorageScope::kDDR; + } else if (scope.value() == "global.vtcm") { + storage_scope_ = StorageScope::kVTCM; + } else { + CHECK(false) << "Encountered unknown HexagonBuffer storage scope: " + << std::string(scope.value()); + } + } +} + +HexagonBuffer* IsHexagonBuffer(DLTensor* tensor) { + if (TVMDeviceExtType(tensor->device.device_type) == kDLHexagon) { + return static_cast(tensor->data); + } + return nullptr; +} + +} // namespace hexagon +} // namespace runtime +} // namespace tvm diff --git a/src/runtime/hexagon/hexagon/hexagon_buffer.h b/src/runtime/hexagon/hexagon/hexagon_buffer.h new file mode 100644 index 000000000000..234178bbc873 --- /dev/null +++ b/src/runtime/hexagon/hexagon/hexagon_buffer.h @@ -0,0 +1,136 @@ +/* + * 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. + */ + +#ifndef TVM_RUNTIME_HEXAGON_HEXAGON_BUFFER_H_ +#define TVM_RUNTIME_HEXAGON_HEXAGON_BUFFER_H_ + +#include +#include +#include +#include +#include + +#include + +namespace tvm { +namespace runtime { +namespace hexagon { + +class HexagonBuffer { + public: + /* \brief Allocate memory within hexagon accessible memory + * scopes. + * + * \param ndim The number of dimensions of physical storage + * to allocate. + * + * \param shape The shape of the ndarray for which to allocate + * physical storage. + * + * \param dtype The data type of the physical storage. + * + * \param scope Optional storage scope indicating the memory + * space in which to allocate. Defaults to global system + * memory (DDR). + */ + HexagonBuffer(int ndim, const int64_t* shape, DLDataType dtype, + Optional scope); + + /* \brief Allocate memory within hexagon accessible memory + * scopes. + * + * \param nbytes The number of bytes of flat physical storage + * to allocate. + * + * \param alignment The byte alignment to be used when allocating. + * + * \param scope Optional storage scope indicating the memory + * space in which to allocate. Defaults to global system + * memory (DDR). + */ + HexagonBuffer(size_t nbytes, size_t alignment, Optional scope); + + /* \brief Construct a hexagon buffer from externally allocated storage. + * + * \param data The externally allocated storage. + * + * \param scope Optional storage scope indicating the memory + * space in the external allocation belongs. Assumes global system + * memory if not provided. + */ + HexagonBuffer(void* data, Optional scope = Optional()); + + //! \brief Destruction deallocates the underlying allocations. + ~HexagonBuffer(); + + //! \brief Prevent copy construction of HexagonBuffers. + HexagonBuffer(const HexagonBuffer&) = delete; + + //! \brief Prevent copy assignment with HexagonBuffers. + HexagonBuffer& operator=(const HexagonBuffer&) = delete; + + //! \brief Allow move construction. + HexagonBuffer(HexagonBuffer&&); + + //! \brief Allow move assignment. + HexagonBuffer& operator=(HexagonBuffer&&); + + //! \brief Return pointer to allocation or allocations. + void* GetPointer(); + + //! \brief Memory scopes managed by a Hexagon Buffer. + enum class StorageScope { + //! \brief System DDR corresponding to global storage. + kDDR, + /*! \brief Vector tightly coupled memory corresponding to + * global.vtcm storage. + */ + kVTCM, + }; + + //! \brief Return storage scope of underlying allocation. + StorageScope GetStorageScope() const; + + private: + //! \brief Assign a storage scope to the buffer. + void SetStorageScope(Optional scope); + /*! \brief Array of allocations required by the buffer. + * + * For a 1d (flat) storage, a single contiguous allocation will + * result. For 2d storage, (count, nbytes) = shape, which will + * result in `count` discrete allocations. + */ + std::vector allocations_; + /*! \brief Whether the allocation(s) present are managed + * and should be deallocated upon destruction. + */ + bool managed_{true}; + /*! \brief The underlying storage type in which the allocation + * resides. + */ + StorageScope storage_scope_; +}; + +HexagonBuffer* IsHexagonBuffer(DLTensor* tensor); + +} // namespace hexagon +} // namespace runtime +} // namespace tvm + +#endif // TVM_RUNTIME_HEXAGON_HEXAGON_BUFFER_H_ From 6dbb253076ad08369549667d53309b8ad16cd0c6 Mon Sep 17 00:00:00 2001 From: Chris Sullivan Date: Thu, 7 Oct 2021 12:36:15 -0700 Subject: [PATCH 4/9] Add HexagonDeviceAPIv2 for use on hexagon. --- .../hexagon/hexagon/hexagon_device_api_v2.cc | 129 ++++++++++++++++++ .../hexagon/hexagon/hexagon_device_api_v2.h | 104 ++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc create mode 100644 src/runtime/hexagon/hexagon/hexagon_device_api_v2.h diff --git a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc new file mode 100644 index 000000000000..41bad8758a64 --- /dev/null +++ b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc @@ -0,0 +1,129 @@ +/* + * 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 hexagon_device_api_v2.cc + */ + +#include "hexagon_device_api_v2.h" + +#include +#include +#include +#include + +#include +#include + +#include "../../workspace_pool.h" +#include "hexagon_buffer.h" +#include "hexagon_common.h" + +namespace tvm { +namespace runtime { +namespace hexagon { + +HexagonDeviceAPIv2* HexagonDeviceAPIv2::Global() { + static auto* inst = new HexagonDeviceAPIv2(); + return inst; +} + +void HexagonDeviceAPIv2::GetAttr(Device dev, DeviceAttrKind kind, TVMRetValue* rv) { + if (kind == kExist) { + *rv = 1; + } +} + +void* HexagonDeviceAPIv2::AllocDataSpace(Device dev, int ndim, const int64_t* shape, DLDataType dtype, + Optional mem_scope) { + return new HexagonBuffer(ndim, shape, dtype, + mem_scope.defined() ? mem_scope : String("global")); +} + +void* HexagonDeviceAPIv2::AllocDataSpace(Device dev, size_t nbytes, size_t alignment, DLDataType type_hint) { + return new HexagonBuffer(nbytes, alignment, String("global")); +} + +void HexagonDeviceAPIv2::FreeDataSpace(Device dev, void* ptr) { + auto* pbuf = static_cast(ptr); + delete pbuf; +} + +struct HexagonWorkspacePool : public WorkspacePool { + HexagonWorkspacePool() : WorkspacePool(kDLCPU, HexagonDeviceAPIv2::Global()) {} +}; + +void* HexagonDeviceAPIv2::AllocWorkspace(Device dev, size_t size, DLDataType type_hint) { + auto* buffer = static_cast( + dmlc::ThreadLocalStore::Get()->AllocWorkspace(dev, size)); + void* ptr = buffer->GetPointer(); + workspace_allocations_.insert({ptr, buffer}); + return ptr; +} + +void HexagonDeviceAPIv2::FreeWorkspace(Device dev, void* data) { + auto it = workspace_allocations_.find(data); + ICHECK(it != workspace_allocations_.end()) + << "Attempt made to free unknown or already freed workspace allocation"; + dmlc::ThreadLocalStore::Get()->FreeWorkspace(dev, it->second); + workspace_allocations_.erase(it); +} + +void HexagonDeviceAPIv2::CopyDataFromTo(DLTensor* from, DLTensor* to, TVMStreamHandle stream) { + if (IsHexagonDevice(from->device) && IsHexagonDevice(to->device)) { + HexagonBuffer* buffer_src = static_cast(from->data); + HexagonBuffer* buffer_dst = static_cast(to->data); + // Check storage scopes + if (buffer_src->GetStorageScope() == HexagonBuffer::StorageScope::kDDR && + buffer_dst->GetStorageScope() == HexagonBuffer::StorageScope::kDDR) { + memcpy(static_cast(buffer_dst->GetPointer()) + to->byte_offset, + static_cast(buffer_src->GetPointer()) + from->byte_offset, + GetDataSize(*from)); + } else { + ICHECK(false) << "Currently only copying between DDR storage is supported."; + } + } else if (IsHexagonDevice(from->device) && to->device.device_type == kDLCPU) { + HexagonBuffer* buffer_src = static_cast(from->data); + memcpy(static_cast(to->data) + to->byte_offset, + static_cast(buffer_src->GetPointer()) + from->byte_offset, + GetDataSize(*from)); + } else if (from->device.device_type == kDLCPU && IsHexagonDevice(to->device)) { + HexagonBuffer* buffer_dst = static_cast(to->data); + memcpy(static_cast(buffer_dst->GetPointer()) + to->byte_offset, + static_cast(from->data) + from->byte_offset, + GetDataSize(*from)); + } else { + CHECK(false) << "Expect copy between DLTensor devices of types kDLHexagon and kDLCPU (external) only."; + } +} + +void HexagonDeviceAPIv2::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) { + memcpy(static_cast(to) + to_offset, static_cast(from) + from_offset, size); +} + +TVM_REGISTER_GLOBAL("device_api.hexagon.v2").set_body([](TVMArgs args, TVMRetValue* rv) { + DeviceAPI* ptr = HexagonDeviceAPIv2::Global(); + *rv = static_cast(ptr); +}); + +} // namespace hexagon +} // namespace runtime +} // namespace tvm diff --git a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h new file mode 100644 index 000000000000..661580cd43c8 --- /dev/null +++ b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h @@ -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. + */ + +#ifndef TVM_RUNTIME_HEXAGON_HEXAGON_DEVICE_API_H_ +#define TVM_RUNTIME_HEXAGON_HEXAGON_DEVICE_API_H_ + +#include + +namespace tvm { +namespace runtime { +namespace hexagon { + +class HexagonBuffer; + +/*! + * \brief Hexagon Device API that is compiled and run on Hexagon. + */ +class HexagonDeviceAPIv2 final : public DeviceAPI { + public: + //! \brief Retrieve the global singleton instance of the HexagonDeviceAPIv2. + static HexagonDeviceAPIv2* Global(); + + //! \brief Constructor + HexagonDeviceAPIv2() {} + + //! \brief Destructor + ~HexagonDeviceAPIv2() {} + + /*! \brief Currently unimplemented interface to specify the active + * Hexagon device. + */ + void SetDevice(Device dev) final {}; + + //! \brief Return the queried Hexagon device attribute. + void GetAttr(Device dev, DeviceAttrKind kind, TVMRetValue * rv) final; + + //! \brief Currently unimplemented interface to synchronize a device stream. + void StreamSync(Device dev, TVMStreamHandle stream) final {} + + //! \note Standard memory allocation methods of the DeviceAPI interface. + //! \brief Allocate a flat allocation of global memory wrapped in a HexagonBuffer. + void* AllocDataSpace(Device dev, size_t nbytes, size_t alignment, DLDataType type_hint) final; + + //! \brief Free the allocated HexagonBuffer. + void FreeDataSpace(Device dev, void* ptr) final; + + /*! \brief Request a dynamically allocated HexagonBuffer from a workspace pool. + * \returns The underlying allocation pointer. + */ + void* AllocWorkspace(Device dev, size_t size, DLDataType type_hint) final; + + //! Dereference workspace pool and erase from tracked workspace_allocations_. + void FreeWorkspace(Device dev, void* data) final; + + /*! + * \brief Allocate an Nd data space on device with memory scope support. + * \param dev The device to perform the operation. + * \param ndim The number of dimensions of allocated tensor. + * \param shape The shape of allocated tensor. + * \param dtype The element type. + * \param mem_scope The memory scope of the allocated tensor. + * \return The allocated HexagonBuffer pointer. + */ + void* AllocDataSpace(Device dev, int ndim, const int64_t* shape, DLDataType dtype, + Optional mem_scope) final; + + /*! + * \brief Copy data from one storage to another. + * \note This API is designed to support special memory with shape dependent layout. + * DLTensor's are passed with shape information to support these cases. + * \param from The source array. + * \param to The target array. + * \param stream Optional stream object. + */ + void CopyDataFromTo(DLTensor* from, DLTensor* to, TVMStreamHandle stream) final; + protected: + //! Standard Device API interface to copy data from one storage to another. + 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; + private: + //! Lookup table for the HexagonBuffer managing a workspace allocation. + std::unordered_map workspace_allocations_; +}; +} // namespace hexagon +} // namespace runtime +} // namespace tvm +#endif // TVM_RUNTIME_HEXAGON_HEXAGON_DEVICE_API_H_ From 8acd1df546b2e2cf5192fbd824c12e3129d8241d Mon Sep 17 00:00:00 2001 From: Chris Sullivan Date: Wed, 20 Oct 2021 23:55:23 -0700 Subject: [PATCH 5/9] Add hexagon packed function wrapper. --- src/runtime/hexagon/hexagon/hexagon_common.cc | 39 ++++++++++++++++++- src/runtime/hexagon/hexagon/hexagon_common.h | 15 ++++++- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/runtime/hexagon/hexagon/hexagon_common.cc b/src/runtime/hexagon/hexagon/hexagon_common.cc index 28f1fe841d49..7bdf9662b3ca 100644 --- a/src/runtime/hexagon/hexagon/hexagon_common.cc +++ b/src/runtime/hexagon/hexagon/hexagon_common.cc @@ -27,6 +27,43 @@ #include #include +#include "hexagon_buffer.h" + +namespace tvm { +namespace runtime { +namespace hexagon { + +PackedFunc WrapPackedFunc(TVMBackendPackedCFunc faddr, const ObjectPtr& sptr_to_self) { + return PackedFunc([faddr, sptr_to_self](TVMArgs args, TVMRetValue* rv) { + TVMValue ret_value; + int ret_type_code = kTVMNullptr; + + TVMValue* arg_values = const_cast(args.values); + std::vector> buffer_args; + for(size_t i=0; i < args.num_args; i++) { + if (args.type_codes[i] == kTVMDLTensorHandle) { + DLTensor* tensor = static_cast(arg_values[i].v_handle); + buffer_args.emplace_back(i, static_cast(tensor->data)); + tensor->data = buffer_args.back().second->GetPointer(); + } + } + int ret = (*faddr)(const_cast(args.values), const_cast(args.type_codes), + args.num_args, &ret_value, &ret_type_code, nullptr); + ICHECK_EQ(ret, 0) << TVMGetLastError(); + + for (auto& arg : buffer_args) { + DLTensor* tensor = static_cast(arg_values[arg.first].v_handle); + tensor->data = arg.second; + } + + + if (ret_type_code != kTVMNullptr) { + *rv = TVMRetValue::MoveFromCHost(ret_value, ret_type_code); + } + }); +} +} // namespace hexagon + namespace { std::vector SplitString(const std::string& str, char delim) { std::vector lines; @@ -45,8 +82,6 @@ void HexagonLog(const std::string& file, int lineno, const std::string& message) } } // namespace -namespace tvm { -namespace runtime { namespace detail { void LogFatalImpl(const std::string& file, int lineno, const std::string& message) { HexagonLog(file, lineno, message); diff --git a/src/runtime/hexagon/hexagon/hexagon_common.h b/src/runtime/hexagon/hexagon/hexagon_common.h index 23f7a28f1431..8334d813ceb9 100644 --- a/src/runtime/hexagon/hexagon/hexagon_common.h +++ b/src/runtime/hexagon/hexagon/hexagon_common.h @@ -24,7 +24,7 @@ #define TVM_RUNTIME_HEXAGON_HEXAGON_COMMON_H_ #include -#include +#include #if defined(__hexagon__) #include @@ -42,7 +42,20 @@ } \ } while (0) +namespace tvm { +namespace runtime { +namespace hexagon { +/*! \brief Unpack HexagonBuffers in packed functions + * prior to invoking. + * \param faddr The function address. + * \param mptr The module pointer node. + * \return A packed function wrapping the requested function. + */ +PackedFunc WrapPackedFunc(TVMBackendPackedCFunc faddr, const ObjectPtr& mptr); +} +} +} inline bool IsHexagonDevice(DLDevice dev) { return TVMDeviceExtType(dev.device_type) == kDLHexagon; } From b781c158bac7c27de4a50ba854802b3c0025dfab Mon Sep 17 00:00:00 2001 From: Chris Sullivan Date: Wed, 20 Oct 2021 23:14:55 -0700 Subject: [PATCH 6/9] Add custom linked param lookup for hexagon that wraps params in an unmanaged HexagonBuffer. --- src/runtime/hexagon/hexagon/hexagon_common.cc | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/runtime/hexagon/hexagon/hexagon_common.cc b/src/runtime/hexagon/hexagon/hexagon_common.cc index 7bdf9662b3ca..d0fa205c7c86 100644 --- a/src/runtime/hexagon/hexagon/hexagon_common.cc +++ b/src/runtime/hexagon/hexagon/hexagon_common.cc @@ -22,10 +22,12 @@ */ #include "hexagon_common.h" + #include +#include -#include #include +#include #include "hexagon_buffer.h" @@ -33,6 +35,41 @@ namespace tvm { namespace runtime { namespace hexagon { +void HexagonLookupLinkedParam(TVMArgs args, TVMRetValue* rv) { + Module mod = args[0]; + int64_t storage_id = args[1]; + DLTensor* template_tensor = args[2]; + Device dev = args[3]; + auto lookup_linked_param = mod.GetFunction(::tvm::runtime::symbol::tvm_lookup_linked_param, true); + if (lookup_linked_param == nullptr) { + *rv = nullptr; + return; + } + + TVMRetValue opaque_handle = lookup_linked_param(storage_id); + if (opaque_handle.type_code() == kTVMNullptr) { + *rv = nullptr; + return; + } + + std::vector shape_vec{template_tensor->shape, + template_tensor->shape + template_tensor->ndim}; + + auto* param_buffer = new HexagonBuffer(static_cast(opaque_handle)); + auto* container = new NDArray::Container(static_cast(param_buffer), shape_vec, + template_tensor->dtype, dev); + container->SetDeleter([](Object* container) { + // The NDArray::Container needs to be deleted + // along with the HexagonBuffer wrapper. However the + // buffer's data points to global const memory and + // so should not be deleted. + auto* ptr = static_cast(container); + delete static_cast(ptr->dl_tensor.data); + delete ptr; + }); + *rv = NDArray(GetObjectPtr(container)); +} + PackedFunc WrapPackedFunc(TVMBackendPackedCFunc faddr, const ObjectPtr& sptr_to_self) { return PackedFunc([faddr, sptr_to_self](TVMArgs args, TVMRetValue* rv) { TVMValue ret_value; @@ -90,7 +127,8 @@ void LogFatalImpl(const std::string& file, int lineno, const std::string& messag void LogMessageImpl(const std::string& file, int lineno, const std::string& message) { HexagonLog(file, lineno, message); } - } // namespace detail + +TVM_REGISTER_GLOBAL("tvm.runtime.hexagon.lookup_linked_params").set_body(hexagon::HexagonLookupLinkedParam); } // namespace runtime } // namespace tvm From eee5a12dfcf2e72bfdc936cad1904266cf0395b9 Mon Sep 17 00:00:00 2001 From: Chris Sullivan Date: Thu, 21 Oct 2021 00:12:35 -0700 Subject: [PATCH 7/9] Add custom hexagon module based of library module node. --- src/runtime/hexagon/hexagon/hexagon_module.cc | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/runtime/hexagon/hexagon/hexagon_module.cc diff --git a/src/runtime/hexagon/hexagon/hexagon_module.cc b/src/runtime/hexagon/hexagon/hexagon_module.cc new file mode 100644 index 000000000000..eebd9fdb49a2 --- /dev/null +++ b/src/runtime/hexagon/hexagon/hexagon_module.cc @@ -0,0 +1,58 @@ +/* + * 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 hexagon_module.cc + * \brief The HexagonLibraryModuleNode + */ +#include "../hexagon_module.h" + +#include +#include +#include + +#include +#include +#include + +#include "../../dso_library.h" +#include "hexagon_common.h" +#include "hexagon_buffer.h" + +namespace tvm { +namespace runtime { + +Module HexagonModuleCreate(std::string data, std::string fmt, + std::unordered_map fmap, std::string asm_str, + std::string obj_str, std::string ir_str, std::string bc_str, + const std::set& packed_c_abi) { + CHECK(fmt == "so") << "Invalid format provided when constructing Hexagon runtime module: " << fmt + << ". Valid formats are: 'so'."; + auto n = make_object(); + n->Init(data); + return CreateModuleFromLibrary(n, hexagon::WrapPackedFunc); +} + +TVM_REGISTER_GLOBAL("runtime.module.loadfile_hexagon").set_body([](TVMArgs args, TVMRetValue* rv) { + auto n = make_object(); + n->Init(args[0]); + *rv = CreateModuleFromLibrary(n, hexagon::WrapPackedFunc); +}); +} // namespace runtime +} // namespace tvm From c68f9b16b9b12172aa4054e3101696d5f3391381 Mon Sep 17 00:00:00 2001 From: Chris Sullivan Date: Fri, 22 Oct 2021 09:20:53 -0700 Subject: [PATCH 8/9] Apply clang formatting --- src/runtime/hexagon/hexagon/hexagon_buffer.cc | 14 ++++++++----- src/runtime/hexagon/hexagon/hexagon_buffer.h | 3 +-- src/runtime/hexagon/hexagon/hexagon_common.cc | 6 +++--- src/runtime/hexagon/hexagon/hexagon_common.h | 16 +++++++------- .../hexagon/hexagon/hexagon_device_api_v2.cc | 21 ++++++++++--------- .../hexagon/hexagon/hexagon_device_api_v2.h | 10 +++++---- src/runtime/hexagon/hexagon/hexagon_module.cc | 2 +- 7 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/runtime/hexagon/hexagon/hexagon_buffer.cc b/src/runtime/hexagon/hexagon/hexagon_buffer.cc index 455980840f4f..82ff0201164e 100644 --- a/src/runtime/hexagon/hexagon/hexagon_buffer.cc +++ b/src/runtime/hexagon/hexagon/hexagon_buffer.cc @@ -68,10 +68,12 @@ HexagonBuffer::~HexagonBuffer() { } HexagonBuffer::HexagonBuffer(HexagonBuffer&& other) - : allocations_(other.allocations_), managed_(other.managed_), storage_scope_(other.storage_scope_) { - other.allocations_.clear(); - other.managed_ = false; - other.storage_scope_ = StorageScope::kDDR; + : allocations_(other.allocations_), + managed_(other.managed_), + storage_scope_(other.storage_scope_) { + other.allocations_.clear(); + other.managed_ = false; + other.storage_scope_ = StorageScope::kDDR; } HexagonBuffer& HexagonBuffer::operator=(HexagonBuffer&& other) { @@ -82,7 +84,9 @@ HexagonBuffer& HexagonBuffer::operator=(HexagonBuffer&& other) { } void* HexagonBuffer::GetPointer() { - if (!allocations_.size()) { return nullptr; } + if (!allocations_.size()) { + return nullptr; + } return (allocations_.size() > 1) ? allocations_.data() : allocations_[0]; } diff --git a/src/runtime/hexagon/hexagon/hexagon_buffer.h b/src/runtime/hexagon/hexagon/hexagon_buffer.h index 234178bbc873..66965db79d8c 100644 --- a/src/runtime/hexagon/hexagon/hexagon_buffer.h +++ b/src/runtime/hexagon/hexagon/hexagon_buffer.h @@ -49,8 +49,7 @@ class HexagonBuffer { * space in which to allocate. Defaults to global system * memory (DDR). */ - HexagonBuffer(int ndim, const int64_t* shape, DLDataType dtype, - Optional scope); + HexagonBuffer(int ndim, const int64_t* shape, DLDataType dtype, Optional scope); /* \brief Allocate memory within hexagon accessible memory * scopes. diff --git a/src/runtime/hexagon/hexagon/hexagon_common.cc b/src/runtime/hexagon/hexagon/hexagon_common.cc index d0fa205c7c86..26276d9a1144 100644 --- a/src/runtime/hexagon/hexagon/hexagon_common.cc +++ b/src/runtime/hexagon/hexagon/hexagon_common.cc @@ -77,7 +77,7 @@ PackedFunc WrapPackedFunc(TVMBackendPackedCFunc faddr, const ObjectPtr& TVMValue* arg_values = const_cast(args.values); std::vector> buffer_args; - for(size_t i=0; i < args.num_args; i++) { + for (size_t i = 0; i < args.num_args; i++) { if (args.type_codes[i] == kTVMDLTensorHandle) { DLTensor* tensor = static_cast(arg_values[i].v_handle); buffer_args.emplace_back(i, static_cast(tensor->data)); @@ -93,7 +93,6 @@ PackedFunc WrapPackedFunc(TVMBackendPackedCFunc faddr, const ObjectPtr& tensor->data = arg.second; } - if (ret_type_code != kTVMNullptr) { *rv = TVMRetValue::MoveFromCHost(ret_value, ret_type_code); } @@ -129,6 +128,7 @@ void LogMessageImpl(const std::string& file, int lineno, const std::string& mess } } // namespace detail -TVM_REGISTER_GLOBAL("tvm.runtime.hexagon.lookup_linked_params").set_body(hexagon::HexagonLookupLinkedParam); +TVM_REGISTER_GLOBAL("tvm.runtime.hexagon.lookup_linked_params") + .set_body(hexagon::HexagonLookupLinkedParam); } // namespace runtime } // namespace tvm diff --git a/src/runtime/hexagon/hexagon/hexagon_common.h b/src/runtime/hexagon/hexagon/hexagon_common.h index 8334d813ceb9..65ffad599201 100644 --- a/src/runtime/hexagon/hexagon/hexagon_common.h +++ b/src/runtime/hexagon/hexagon/hexagon_common.h @@ -34,12 +34,12 @@ #define HEXAGON_PRINT(level, ...) printf(__VA_ARGS__) #endif -#define HEXAGON_SAFE_CALL(api_call) \ - do { \ - int result = api_call; \ - if (result != 0) { \ +#define HEXAGON_SAFE_CALL(api_call) \ + do { \ + int result = api_call; \ + if (result != 0) { \ HEXAGON_PRINT(ERROR, "ERROR: " #api_call " failed with error %d.", result); \ - } \ + } \ } while (0) namespace tvm { @@ -53,9 +53,9 @@ namespace hexagon { * \return A packed function wrapping the requested function. */ PackedFunc WrapPackedFunc(TVMBackendPackedCFunc faddr, const ObjectPtr& mptr); -} -} -} +} // namespace hexagon +} // namespace runtime +} // namespace tvm inline bool IsHexagonDevice(DLDevice dev) { return TVMDeviceExtType(dev.device_type) == kDLHexagon; } diff --git a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc index 41bad8758a64..9c1f6ebd7d70 100644 --- a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc +++ b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc @@ -50,13 +50,13 @@ void HexagonDeviceAPIv2::GetAttr(Device dev, DeviceAttrKind kind, TVMRetValue* r } } -void* HexagonDeviceAPIv2::AllocDataSpace(Device dev, int ndim, const int64_t* shape, DLDataType dtype, - Optional mem_scope) { - return new HexagonBuffer(ndim, shape, dtype, - mem_scope.defined() ? mem_scope : String("global")); +void* HexagonDeviceAPIv2::AllocDataSpace(Device dev, int ndim, const int64_t* shape, + DLDataType dtype, Optional mem_scope) { + return new HexagonBuffer(ndim, shape, dtype, mem_scope.defined() ? mem_scope : String("global")); } -void* HexagonDeviceAPIv2::AllocDataSpace(Device dev, size_t nbytes, size_t alignment, DLDataType type_hint) { +void* HexagonDeviceAPIv2::AllocDataSpace(Device dev, size_t nbytes, size_t alignment, + DLDataType type_hint) { return new HexagonBuffer(nbytes, alignment, String("global")); } @@ -106,15 +106,16 @@ void HexagonDeviceAPIv2::CopyDataFromTo(DLTensor* from, DLTensor* to, TVMStreamH } else if (from->device.device_type == kDLCPU && IsHexagonDevice(to->device)) { HexagonBuffer* buffer_dst = static_cast(to->data); memcpy(static_cast(buffer_dst->GetPointer()) + to->byte_offset, - static_cast(from->data) + from->byte_offset, - GetDataSize(*from)); + static_cast(from->data) + from->byte_offset, GetDataSize(*from)); } else { - CHECK(false) << "Expect copy between DLTensor devices of types kDLHexagon and kDLCPU (external) only."; + CHECK(false) + << "Expect copy between DLTensor devices of types kDLHexagon and kDLCPU (external) only."; } } -void HexagonDeviceAPIv2::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, +void HexagonDeviceAPIv2::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) { memcpy(static_cast(to) + to_offset, static_cast(from) + from_offset, size); } diff --git a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h index 661580cd43c8..1b721c0f834b 100644 --- a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h +++ b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h @@ -45,10 +45,10 @@ class HexagonDeviceAPIv2 final : public DeviceAPI { /*! \brief Currently unimplemented interface to specify the active * Hexagon device. */ - void SetDevice(Device dev) final {}; + void SetDevice(Device dev) final{}; //! \brief Return the queried Hexagon device attribute. - void GetAttr(Device dev, DeviceAttrKind kind, TVMRetValue * rv) final; + void GetAttr(Device dev, DeviceAttrKind kind, TVMRetValue* rv) final; //! \brief Currently unimplemented interface to synchronize a device stream. void StreamSync(Device dev, TVMStreamHandle stream) final {} @@ -89,11 +89,13 @@ class HexagonDeviceAPIv2 final : public DeviceAPI { * \param stream Optional stream object. */ void CopyDataFromTo(DLTensor* from, DLTensor* to, TVMStreamHandle stream) final; + protected: //! Standard Device API interface to copy data from one storage to another. - 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, + 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; + private: //! Lookup table for the HexagonBuffer managing a workspace allocation. std::unordered_map workspace_allocations_; diff --git a/src/runtime/hexagon/hexagon/hexagon_module.cc b/src/runtime/hexagon/hexagon/hexagon_module.cc index eebd9fdb49a2..5fc6d71e00c9 100644 --- a/src/runtime/hexagon/hexagon/hexagon_module.cc +++ b/src/runtime/hexagon/hexagon/hexagon_module.cc @@ -32,8 +32,8 @@ #include #include "../../dso_library.h" -#include "hexagon_common.h" #include "hexagon_buffer.h" +#include "hexagon_common.h" namespace tvm { namespace runtime { From ac45bac41e6eda68e687a885c4f63ba42fdf88fd Mon Sep 17 00:00:00 2001 From: Chris Sullivan Date: Fri, 22 Oct 2021 14:16:22 -0700 Subject: [PATCH 9/9] Apply cpplint changes. --- src/runtime/hexagon/hexagon/hexagon_buffer.cc | 3 +++ src/runtime/hexagon/hexagon/hexagon_buffer.h | 8 ++++---- src/runtime/hexagon/hexagon/hexagon_common.cc | 2 ++ src/runtime/hexagon/hexagon/hexagon_common.h | 6 +++--- src/runtime/hexagon/hexagon/hexagon_device_api_v2.h | 8 +++++--- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/runtime/hexagon/hexagon/hexagon_buffer.cc b/src/runtime/hexagon/hexagon/hexagon_buffer.cc index 82ff0201164e..0760bab6c582 100644 --- a/src/runtime/hexagon/hexagon/hexagon_buffer.cc +++ b/src/runtime/hexagon/hexagon/hexagon_buffer.cc @@ -21,6 +21,9 @@ #include +#include +#include + #include "hexagon_common.h" namespace tvm { diff --git a/src/runtime/hexagon/hexagon/hexagon_buffer.h b/src/runtime/hexagon/hexagon/hexagon_buffer.h index 66965db79d8c..c62cee66b0d8 100644 --- a/src/runtime/hexagon/hexagon/hexagon_buffer.h +++ b/src/runtime/hexagon/hexagon/hexagon_buffer.h @@ -17,8 +17,8 @@ * under the License. */ -#ifndef TVM_RUNTIME_HEXAGON_HEXAGON_BUFFER_H_ -#define TVM_RUNTIME_HEXAGON_HEXAGON_BUFFER_H_ +#ifndef TVM_RUNTIME_HEXAGON_HEXAGON_HEXAGON_BUFFER_H_ +#define TVM_RUNTIME_HEXAGON_HEXAGON_HEXAGON_BUFFER_H_ #include #include @@ -73,7 +73,7 @@ class HexagonBuffer { * space in the external allocation belongs. Assumes global system * memory if not provided. */ - HexagonBuffer(void* data, Optional scope = Optional()); + explicit HexagonBuffer(void* data, Optional scope = Optional()); //! \brief Destruction deallocates the underlying allocations. ~HexagonBuffer(); @@ -132,4 +132,4 @@ HexagonBuffer* IsHexagonBuffer(DLTensor* tensor); } // namespace runtime } // namespace tvm -#endif // TVM_RUNTIME_HEXAGON_HEXAGON_BUFFER_H_ +#endif // TVM_RUNTIME_HEXAGON_HEXAGON_HEXAGON_BUFFER_H_ diff --git a/src/runtime/hexagon/hexagon/hexagon_common.cc b/src/runtime/hexagon/hexagon/hexagon_common.cc index 26276d9a1144..260b105ac43a 100644 --- a/src/runtime/hexagon/hexagon/hexagon_common.cc +++ b/src/runtime/hexagon/hexagon/hexagon_common.cc @@ -28,6 +28,8 @@ #include #include +#include +#include #include "hexagon_buffer.h" diff --git a/src/runtime/hexagon/hexagon/hexagon_common.h b/src/runtime/hexagon/hexagon/hexagon_common.h index 65ffad599201..a84ea4e20245 100644 --- a/src/runtime/hexagon/hexagon/hexagon_common.h +++ b/src/runtime/hexagon/hexagon/hexagon_common.h @@ -20,8 +20,8 @@ /*! * \file hexagon_utils.h */ -#ifndef TVM_RUNTIME_HEXAGON_HEXAGON_COMMON_H_ -#define TVM_RUNTIME_HEXAGON_HEXAGON_COMMON_H_ +#ifndef TVM_RUNTIME_HEXAGON_HEXAGON_HEXAGON_COMMON_H_ +#define TVM_RUNTIME_HEXAGON_HEXAGON_HEXAGON_COMMON_H_ #include #include @@ -60,4 +60,4 @@ inline bool IsHexagonDevice(DLDevice dev) { return TVMDeviceExtType(dev.device_type) == kDLHexagon; } -#endif // TVM_RUNTIME_HEXAGON_HEXAGON_UTILS_H_ +#endif // TVM_RUNTIME_HEXAGON_HEXAGON_HEXAGON_COMMON_H_ diff --git a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h index 1b721c0f834b..3d866307f17c 100644 --- a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h +++ b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h @@ -17,11 +17,13 @@ * under the License. */ -#ifndef TVM_RUNTIME_HEXAGON_HEXAGON_DEVICE_API_H_ -#define TVM_RUNTIME_HEXAGON_HEXAGON_DEVICE_API_H_ +#ifndef TVM_RUNTIME_HEXAGON_HEXAGON_HEXAGON_DEVICE_API_V2_H_ +#define TVM_RUNTIME_HEXAGON_HEXAGON_HEXAGON_DEVICE_API_V2_H_ #include +#include + namespace tvm { namespace runtime { namespace hexagon { @@ -103,4 +105,4 @@ class HexagonDeviceAPIv2 final : public DeviceAPI { } // namespace hexagon } // namespace runtime } // namespace tvm -#endif // TVM_RUNTIME_HEXAGON_HEXAGON_DEVICE_API_H_ +#endif // TVM_RUNTIME_HEXAGON_HEXAGON_HEXAGON_DEVICE_API_V2_H_