From 30c52ce980a115c19a6830a1aed1d46a36d574e8 Mon Sep 17 00:00:00 2001 From: Eric Lunderberg Date: Wed, 23 Mar 2022 15:38:50 -0500 Subject: [PATCH 1/5] [Hexagon] Support both 1-d and 2-d VTCM allocations Previously, all VTCM allocations were assumed to be 2-d buffers. This commit extends `HexagonDeviceAPIv2::AllocVtcmWorkspace` to allow both 1-d and 2-d VTCM allocations. Matching the semantics used in `CodeGenHexagon::CreateBufferPtr`, allocation of 1-d buffers returns a `void*`, and allocation of 2-d buffers returns a `void**`. Co-authored-by: Adam Straw --- src/runtime/hexagon/hexagon/hexagon_buffer.h | 3 ++ src/runtime/hexagon/hexagon/hexagon_common.cc | 6 +-- .../hexagon/hexagon/hexagon_device_api_v2.cc | 47 +++++++++---------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/runtime/hexagon/hexagon/hexagon_buffer.h b/src/runtime/hexagon/hexagon/hexagon_buffer.h index 0eacb0a322a0..97c93043aedc 100644 --- a/src/runtime/hexagon/hexagon/hexagon_buffer.h +++ b/src/runtime/hexagon/hexagon/hexagon_buffer.h @@ -97,6 +97,9 @@ class HexagonBuffer { //! \brief Return pointer to allocations. void** GetPointer(); + //! \brief Return number of allocations. + size_t GetNumAllocs() { return nallocs_; } + //! \brief Memory scopes managed by a Hexagon Buffer. enum class StorageScope { //! \brief System DDR corresponding to global storage. diff --git a/src/runtime/hexagon/hexagon/hexagon_common.cc b/src/runtime/hexagon/hexagon/hexagon_common.cc index acdb1b3a5a6a..b5701126fa56 100644 --- a/src/runtime/hexagon/hexagon/hexagon_common.cc +++ b/src/runtime/hexagon/hexagon/hexagon_common.cc @@ -95,9 +95,9 @@ PackedFunc WrapPackedFunc(TVMBackendPackedCFunc faddr, const ObjectPtr& if (args.type_codes[i] == kTVMDLTensorHandle) { DLTensor* tensor = static_cast(arg_values[i].v_handle); buffer_args.emplace_back(i, static_cast(tensor->data)); - // Assumes a single contiguous allocation - // TODO(Straw): Enable discontiguous allocation - tensor->data = buffer_args.back().second->GetPointer()[0]; + HexagonBuffer* hexbuf = buffer_args.back().second; + CHECK_EQ(hexbuf->GetNumAllocs(), 1); + tensor->data = hexbuf->GetPointer()[0]; } } int ret = (*faddr)(const_cast(args.values), const_cast(args.type_codes), diff --git a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc index 2ffb998a6b32..f73cc48c0571 100644 --- a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc +++ b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc @@ -60,21 +60,18 @@ 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) { CHECK(TVMDeviceExtType(dev.device_type) == kDLHexagon) << "dev.device_type: " << dev.device_type; - - // Forcing contiguous allocation, for now - // TODO(Straw): Enable discontiguous allocation - size_t nallocs = 1; - size_t nbytes = 1; - for (int i = 0; i < ndim; ++i) { - nbytes *= shape[i]; - } - size_t typesize = (dtype.bits / 8) * dtype.lanes; - nbytes *= typesize; - - size_t alignment = typesize; + CHECK((ndim == 1 || ndim == 2) && "Hexagon Device API supports only 1d and 2d allocations"); + size_t alignment = shape[ndim - 1]; if (alignment < kHexagonAllocAlignment) { alignment = kHexagonAllocAlignment; } + + size_t nallocs = 1; + size_t nbytes = shape[0]; + if (ndim == 2) { + nallocs = shape[0]; + nbytes = shape[1]; + } return new HexagonBuffer(nallocs, nbytes, alignment, mem_scope); } @@ -109,9 +106,12 @@ void* HexagonDeviceAPIv2::AllocWorkspace(Device dev, size_t size, DLDataType typ auto* hexbuf = static_cast( dmlc::ThreadLocalStore::Get()->AllocWorkspace(dev, size)); - // Assumes a single contiguous allocation - // TODO(Straw): Enable discontiguous allocation - void* ptr = hexbuf->GetPointer()[0]; + void* ptr = nullptr; + if (hexbuf->GetNumAllocs() == 1) { + ptr = hexbuf->GetPointer()[0]; + } else { + ptr = hexbuf->GetPointer(); + } workspace_allocations_.insert({ptr, hexbuf}); return ptr; } @@ -128,9 +128,7 @@ void HexagonDeviceAPIv2::FreeWorkspace(Device dev, void* data) { void* HexagonDeviceAPIv2::AllocVtcmWorkspace(Device dev, int ndim, const int64_t* shape, DLDataType dtype, Optional mem_scope) { CHECK(TVMDeviceExtType(dev.device_type) == kDLHexagon) << "dev.device_type: " << dev.device_type; - // Forcing contiguous allocation, for now - // TODO(Straw): Enable discontiguous allocation - CHECK_EQ(ndim, 1); + CHECK((ndim == 1 || ndim == 2) && "Hexagon Device API supports only 1d and 2d allocations"); return AllocDataSpace(dev, ndim, shape, dtype, mem_scope); } @@ -193,9 +191,7 @@ TVM_REGISTER_GLOBAL("device_api.hexagon.alloc_nd").set_body([](TVMArgs args, TVM std::string scope = args[4]; CHECK(scope.find("global.vtcm") != std::string::npos); int64_t ndim = args[5]; - // Forcing contiguous allocation, for now - // TODO(Straw): Enable discontiguous allocation - CHECK_EQ(ndim, 1); + CHECK((ndim == 1 || ndim == 2) && "Hexagon Device API supports only 1d and 2d allocations"); int64_t* shape = static_cast(static_cast(args[6])); Device dev; @@ -211,9 +207,12 @@ TVM_REGISTER_GLOBAL("device_api.hexagon.alloc_nd").set_body([](TVMArgs args, TVM HexagonBuffer* hexbuf = reinterpret_cast( hexapi->AllocVtcmWorkspace(dev, ndim, shape, type_hint, String(scope))); - // Assumes a single contiguous allocation - // TODO(Straw): Enable discontiguous allocation - void* ptr = hexbuf->GetPointer()[0]; + void* ptr = nullptr; + if (hexbuf->GetNumAllocs() == 1) { + ptr = hexbuf->GetPointer()[0]; + } else { + ptr = hexbuf->GetPointer(); + } vtcmallocs[ptr] = hexbuf; *rv = ptr; }); From 7ab8724904c35cd503297d56438690019b119d74 Mon Sep 17 00:00:00 2001 From: Eric Lunderberg Date: Mon, 28 Mar 2022 10:38:41 -0500 Subject: [PATCH 2/5] [Hexagon] Distinguish between 1-d buffer and single-alloc 2-d buffer Previously, HexagonBuffer represented 1-d buffers as 2-d buffers with `nallocs==1`. Since this is used to determine the return type of the data pointer exposed to the generated code, the ambiguity between `shape=[N]` and `shape=[1,N]` must be avoided. This commit replaces `HexagonBuffer::nallocs_` with `HexagonBuffer::ndim_`, avoiding this ambiguity. --- src/runtime/hexagon/hexagon/hexagon_buffer.cc | 61 +++++++++++-------- src/runtime/hexagon/hexagon/hexagon_buffer.h | 28 +++++++-- src/runtime/hexagon/hexagon/hexagon_common.cc | 3 +- .../hexagon/hexagon/hexagon_device_api_v2.cc | 37 ++++++----- 4 files changed, 74 insertions(+), 55 deletions(-) diff --git a/src/runtime/hexagon/hexagon/hexagon_buffer.cc b/src/runtime/hexagon/hexagon/hexagon_buffer.cc index 644f954cd1a6..6cb022b43494 100644 --- a/src/runtime/hexagon/hexagon/hexagon_buffer.cc +++ b/src/runtime/hexagon/hexagon/hexagon_buffer.cc @@ -129,7 +129,7 @@ std::unique_ptr Allocator(size_t } HexagonBuffer::HexagonBuffer(size_t nbytes, size_t alignment, Optional scope) - : nallocs_(1), nbytes_(nbytes) { + : ndim_(1), nbytes_per_allocation_(nbytes) { SetStorageScope(scope); std::unique_ptr alloca = nullptr; @@ -145,7 +145,7 @@ HexagonBuffer::HexagonBuffer(size_t nbytes, size_t alignment, Optional s HexagonBuffer::HexagonBuffer(size_t nallocs, size_t nbytes, size_t alignment, Optional scope) - : nallocs_(nallocs), nbytes_(nallocs * nbytes) { + : ndim_(2), nbytes_per_allocation_(nbytes) { SetStorageScope(scope); for (size_t i = 0; i < nallocs; ++i) { std::unique_ptr alloca = nullptr; @@ -161,7 +161,7 @@ HexagonBuffer::HexagonBuffer(size_t nallocs, size_t nbytes, size_t alignment, } HexagonBuffer::HexagonBuffer(void* data, size_t nbytes, Optional scope) - : nallocs_(1), nbytes_(nbytes) { + : ndim_(1), nbytes_per_allocation_(nbytes) { SetStorageScope(scope); // disallow external VTCM allocations CHECK(GetStorageScope() != HexagonBuffer::StorageScope::kVTCM); @@ -170,11 +170,19 @@ HexagonBuffer::HexagonBuffer(void* data, size_t nbytes, Optional scope) HexagonBuffer::~HexagonBuffer() { managed_allocations_.clear(); } -void** HexagonBuffer::GetPointer() { - if (!allocations_.size()) { +void* HexagonBuffer::GetPointer() { + ICHECK(allocations_.size()) + << "Internal failure, allocations_ should be set in HexagonBuffer constructor"; + + if (ndim_ == 1) { + ICHECK_EQ(allocations_.size(), 1); + return allocations_[0]; + } else if (ndim_ == 2) { + return allocations_.data(); + } else { + LOG(FATAL) << "HexagonBuffer should be either 1-d or 2-d, not " << ndim_ << "-d"; return nullptr; } - return allocations_.data(); } HexagonBuffer::StorageScope HexagonBuffer::GetStorageScope() const { return storage_scope_; } @@ -195,17 +203,16 @@ void HexagonBuffer::SetStorageScope(Optional scope) { } void HexagonBuffer::CopyTo(void* data, size_t nbytes) const { - CHECK_LE(nbytes, nbytes_); + CHECK_LE(nbytes, TotalBytes()); CHECK(managed_allocations_.size() && "CopyTo not supported on unmanaged `external` allocations"); size_t copied = 0; - for (size_t i = 0; i < nallocs_; ++i) { - size_t bytes_to_copy = std::min(nbytes - copied, managed_allocations_[i]->allocation_nbytes_); + for (const auto& managed_alloc : managed_allocations_) { + size_t bytes_to_copy = std::min(nbytes - copied, managed_alloc->allocation_nbytes_); if (bytes_to_copy == 0) break; void* data_plus_copied = static_cast((static_cast(data) + copied)); - int status = - hexagon_user_dma_1d_sync(data_plus_copied, managed_allocations_[i]->data_, bytes_to_copy); + int status = hexagon_user_dma_1d_sync(data_plus_copied, managed_alloc->data_, bytes_to_copy); CHECK_EQ(status, 0); copied += bytes_to_copy; @@ -213,18 +220,17 @@ void HexagonBuffer::CopyTo(void* data, size_t nbytes) const { } void HexagonBuffer::CopyFrom(void* data, size_t nbytes) { - CHECK_LE(nbytes, nbytes_); + CHECK_LE(nbytes, TotalBytes()); CHECK(managed_allocations_.size() && "CopyFrom not supported on unmanaged `external` allocations"); size_t copied = 0; - for (size_t i = 0; i < nallocs_; ++i) { - size_t bytes_to_copy = std::min(nbytes - copied, managed_allocations_[i]->allocation_nbytes_); + for (const auto& managed_alloc : managed_allocations_) { + size_t bytes_to_copy = std::min(nbytes - copied, managed_alloc->allocation_nbytes_); if (bytes_to_copy == 0) break; void* data_plus_copied = static_cast((static_cast(data) + copied)); - int status = - hexagon_user_dma_1d_sync(managed_allocations_[i]->data_, data_plus_copied, bytes_to_copy); + int status = hexagon_user_dma_1d_sync(managed_alloc->data_, data_plus_copied, bytes_to_copy); CHECK_EQ(status, 0); copied += bytes_to_copy; @@ -232,31 +238,32 @@ void HexagonBuffer::CopyFrom(void* data, size_t nbytes) { } void HexagonBuffer::CopyFrom(const HexagonBuffer& other, size_t nbytes) { - CHECK_LE(nbytes, nbytes_); - CHECK_LE(nbytes, other.nbytes_); + CHECK_LE(nbytes, TotalBytes()); + CHECK_LE(nbytes, other.TotalBytes()); CHECK(managed_allocations_.size() && "CopyFrom not supported on unmanaged `external` allocations"); CHECK(other.managed_allocations_.size() && "CopyFrom not supported on unmanaged `external` allocations"); - if (nallocs_ == other.nallocs_) { + if (managed_allocations_.size() == other.managed_allocations_.size()) { size_t copied = 0; - for (size_t i = 0; i < nallocs_; ++i) { - size_t bytes_to_copy = std::min(nbytes - copied, managed_allocations_[i]->allocation_nbytes_); + for (size_t i = 0; i < managed_allocations_.size(); ++i) { + const auto& this_alloc = managed_allocations_[i]; + const auto& other_alloc = other.managed_allocations_[i]; + + size_t bytes_to_copy = std::min(nbytes - copied, this_alloc->allocation_nbytes_); if (bytes_to_copy == 0) break; - CHECK_LE(other.managed_allocations_[i]->allocation_nbytes_, - managed_allocations_[i]->allocation_nbytes_); + CHECK_LE(other_alloc->allocation_nbytes_, this_alloc->allocation_nbytes_); - int status = hexagon_user_dma_1d_sync(managed_allocations_[i]->data_, - other.managed_allocations_[i]->data_, bytes_to_copy); + int status = hexagon_user_dma_1d_sync(this_alloc->data_, other_alloc->data_, bytes_to_copy); CHECK_EQ(status, 0); copied += bytes_to_copy; } - } else if (nallocs_ == 1) { + } else if (managed_allocations_.size() == 1) { return other.CopyTo(managed_allocations_[0]->data_, nbytes); - } else if (other.nallocs_ == 1) { + } else if (other.managed_allocations_.size() == 1) { return CopyFrom(other.managed_allocations_[0]->data_, nbytes); } else { CHECK(false) << "To copy between Hexagon Buffers they must either have the same number of " diff --git a/src/runtime/hexagon/hexagon/hexagon_buffer.h b/src/runtime/hexagon/hexagon/hexagon_buffer.h index 97c93043aedc..c26eb7628a27 100644 --- a/src/runtime/hexagon/hexagon/hexagon_buffer.h +++ b/src/runtime/hexagon/hexagon/hexagon_buffer.h @@ -94,11 +94,24 @@ class HexagonBuffer { //! \brief Prevent move assignment. HexagonBuffer& operator=(HexagonBuffer&&) = delete; - //! \brief Return pointer to allocations. - void** GetPointer(); + /*! \brief Return data pointer + * + * The return type depends on the buffer being + */ + void* GetPointer(); + + // //! \brief Return number of allocations. + // size_t GetNumAllocs() { return nallocs_; } - //! \brief Return number of allocations. - size_t GetNumAllocs() { return nallocs_; } + /*! \brief Return dimensionality of buffer + * + * Will always be either 1 or 2. If the buffer is 1-d, allocation + * returns a pointer to data, which is accessed by + * ((value_type*)ptr)[i]. If the buffer is 2-d, allocation returns + * a pointer to an array of pointers, which is accessed by + * ((value_type**)ptr)[i][j]. + */ + size_t GetBufferDimension() { return ndim_; } //! \brief Memory scopes managed by a Hexagon Buffer. enum class StorageScope { @@ -138,6 +151,9 @@ class HexagonBuffer { void CopyFrom(const HexagonBuffer& other, size_t nbytes); private: + //! \brief Return the total number of bytes in this buffer + size_t TotalBytes() const { return nbytes_per_allocation_ * allocations_.size(); } + //! \brief Assign a storage scope to the buffer. void SetStorageScope(Optional scope); /*! \brief Array of raw pointer allocations required by the buffer. @@ -153,8 +169,8 @@ class HexagonBuffer { /*! \brief The underlying storage type in which the allocation * resides. */ - size_t nallocs_; - size_t nbytes_; + size_t ndim_; + size_t nbytes_per_allocation_; StorageScope storage_scope_; }; diff --git a/src/runtime/hexagon/hexagon/hexagon_common.cc b/src/runtime/hexagon/hexagon/hexagon_common.cc index b5701126fa56..00d74f90111e 100644 --- a/src/runtime/hexagon/hexagon/hexagon_common.cc +++ b/src/runtime/hexagon/hexagon/hexagon_common.cc @@ -96,8 +96,7 @@ PackedFunc WrapPackedFunc(TVMBackendPackedCFunc faddr, const ObjectPtr& DLTensor* tensor = static_cast(arg_values[i].v_handle); buffer_args.emplace_back(i, static_cast(tensor->data)); HexagonBuffer* hexbuf = buffer_args.back().second; - CHECK_EQ(hexbuf->GetNumAllocs(), 1); - tensor->data = hexbuf->GetPointer()[0]; + tensor->data = hexbuf->GetPointer(); } } int ret = (*faddr)(const_cast(args.values), const_cast(args.type_codes), diff --git a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc index f73cc48c0571..66ea6f9e26a4 100644 --- a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc +++ b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc @@ -60,19 +60,26 @@ 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) { CHECK(TVMDeviceExtType(dev.device_type) == kDLHexagon) << "dev.device_type: " << dev.device_type; - CHECK((ndim == 1 || ndim == 2) && "Hexagon Device API supports only 1d and 2d allocations"); - size_t alignment = shape[ndim - 1]; + + size_t typesize = (dtype.bits / 8) * dtype.lanes; + + size_t alignment = shape[ndim - 1] * typesize; if (alignment < kHexagonAllocAlignment) { alignment = kHexagonAllocAlignment; } - size_t nallocs = 1; - size_t nbytes = shape[0]; - if (ndim == 2) { - nallocs = shape[0]; - nbytes = shape[1]; + if (ndim == 1) { + size_t nbytes = shape[0] * typesize; + return new HexagonBuffer(nbytes, alignment, mem_scope); + } else if (ndim == 2) { + size_t nallocs = shape[0]; + size_t nbytes = shape[1] * typesize; + return new HexagonBuffer(nallocs, nbytes, alignment, mem_scope); + } else { + LOG(FATAL) << "Hexagon Device API supports only 1d and 2d allocations, but received ndim = " + << ndim; + return nullptr; } - return new HexagonBuffer(nallocs, nbytes, alignment, mem_scope); } void* HexagonDeviceAPIv2::AllocDataSpace(Device dev, size_t nbytes, size_t alignment, @@ -106,12 +113,7 @@ void* HexagonDeviceAPIv2::AllocWorkspace(Device dev, size_t size, DLDataType typ auto* hexbuf = static_cast( dmlc::ThreadLocalStore::Get()->AllocWorkspace(dev, size)); - void* ptr = nullptr; - if (hexbuf->GetNumAllocs() == 1) { - ptr = hexbuf->GetPointer()[0]; - } else { - ptr = hexbuf->GetPointer(); - } + void* ptr = hexbuf->GetPointer(); workspace_allocations_.insert({ptr, hexbuf}); return ptr; } @@ -207,12 +209,7 @@ TVM_REGISTER_GLOBAL("device_api.hexagon.alloc_nd").set_body([](TVMArgs args, TVM HexagonBuffer* hexbuf = reinterpret_cast( hexapi->AllocVtcmWorkspace(dev, ndim, shape, type_hint, String(scope))); - void* ptr = nullptr; - if (hexbuf->GetNumAllocs() == 1) { - ptr = hexbuf->GetPointer()[0]; - } else { - ptr = hexbuf->GetPointer(); - } + void* ptr = hexbuf->GetPointer(); vtcmallocs[ptr] = hexbuf; *rv = ptr; }); From fd2d605506b5501bf39e759a398bb5feb1625518 Mon Sep 17 00:00:00 2001 From: Eric Lunderberg Date: Thu, 31 Mar 2022 11:53:10 -0500 Subject: [PATCH 3/5] [Hexagon] Treat "global" scope allocations as 1-d This updates `HexagonDeviceAPIv2::AllocDataSpace` to follow the semantics of `DeviceAPI::AllocDataSpace`, to avoid breaking caller assumptions in `tvm.nd.array` or graph_executor/aot allocation. --- src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc | 4 ++++ src/runtime/hexagon/hexagon/hexagon_device_api_v2.h | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc index 66ea6f9e26a4..2804b2d837a5 100644 --- a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc +++ b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.cc @@ -59,6 +59,10 @@ void HexagonDeviceAPIv2::GetAttr(Device dev, DeviceAttrKind kind, TVMRetValue* r // DataSpace: static allocations for Hexagon void* HexagonDeviceAPIv2::AllocDataSpace(Device dev, int ndim, const int64_t* shape, DLDataType dtype, Optional mem_scope) { + if (!mem_scope.defined() || mem_scope.value() == "global") { + return DeviceAPI::AllocDataSpace(dev, ndim, shape, dtype, mem_scope); + } + CHECK(TVMDeviceExtType(dev.device_type) == kDLHexagon) << "dev.device_type: " << dev.device_type; size_t typesize = (dtype.bits / 8) * dtype.lanes; diff --git a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h index 9e39fc0b0f97..43f4272f1943 100644 --- a/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h +++ b/src/runtime/hexagon/hexagon/hexagon_device_api_v2.h @@ -75,6 +75,15 @@ class HexagonDeviceAPIv2 final : public DeviceAPI { /*! * \brief Allocate an Nd data space on device with memory scope support. + * + * If mem_scope is undefined or is "global", treat shape as the + * tensor shape, to be flattened into an allocation of 1-d physical + * memory. This is done to maintain the semantics expected by callers of + * DeviceAPI::AllocDataSpace, in cases where it has a valid return value. + * + * For other values of mem_scope, the shape is the N-d physical + * shape of the allocation. + * * \param dev The device to perform the operation. * \param ndim The number of dimensions of allocated tensor. * \param shape The shape of allocated tensor. From 3d7ae573ae5b3d0f126df7e96c863910ad003919 Mon Sep 17 00:00:00 2001 From: Eric Lunderberg Date: Thu, 31 Mar 2022 12:57:49 -0500 Subject: [PATCH 4/5] Updated C++ unit tests for HexagonBuffer --- tests/cpp/runtime/hexagon_buffer.cc | 50 +++++++++++++---------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/tests/cpp/runtime/hexagon_buffer.cc b/tests/cpp/runtime/hexagon_buffer.cc index 6b777bbd9302..2bf86b126d98 100644 --- a/tests/cpp/runtime/hexagon_buffer.cc +++ b/tests/cpp/runtime/hexagon_buffer.cc @@ -54,7 +54,7 @@ TEST(HexagonBuffer, copy_from) { std::vector data{0, 1, 2, 3, 4, 5, 6, 7}; hb.CopyFrom(data.data(), data.size()); - uint8_t* ptr = static_cast(hb.GetPointer()[0]); + uint8_t* ptr = static_cast(hb.GetPointer()); for (size_t i = 0; i < data.size(); ++i) { EXPECT_EQ(ptr[i], data[i]); } @@ -103,17 +103,15 @@ TEST(HexagonBuffer, nd_copy_from) { std::vector data{0, 1, 2, 3, 4, 5, 6, 7}; hb.CopyFrom(data.data(), data.size()); - uint8_t* ptr = static_cast(hb.GetPointer()[0]); - EXPECT_EQ(ptr[0], data[0]); - EXPECT_EQ(ptr[1], data[1]); - EXPECT_EQ(ptr[2], data[2]); - EXPECT_EQ(ptr[3], data[3]); - - ptr = static_cast(hb.GetPointer()[1]); - EXPECT_EQ(ptr[0], data[4]); - EXPECT_EQ(ptr[1], data[5]); - EXPECT_EQ(ptr[2], data[6]); - EXPECT_EQ(ptr[3], data[7]); + uint8_t** ptr = static_cast(hb.GetPointer()); + EXPECT_EQ(ptr[0][0], data[0]); + EXPECT_EQ(ptr[0][1], data[1]); + EXPECT_EQ(ptr[0][2], data[2]); + EXPECT_EQ(ptr[0][3], data[3]); + EXPECT_EQ(ptr[1][0], data[4]); + EXPECT_EQ(ptr[1][1], data[5]); + EXPECT_EQ(ptr[1][2], data[6]); + EXPECT_EQ(ptr[1][3], data[7]); } TEST(HexagonBuffer, 1d_copy_from_1d) { @@ -127,7 +125,7 @@ TEST(HexagonBuffer, 1d_copy_from_1d) { from.CopyFrom(data.data(), data.size()); to.CopyFrom(from, 8); - uint8_t* ptr = static_cast(to.GetPointer()[0]); + uint8_t* ptr = static_cast(to.GetPointer()); for (size_t i = 0; i < data.size(); ++i) { EXPECT_EQ(ptr[i], data[i]); } @@ -144,17 +142,15 @@ TEST(HexagonBuffer, 2d_copy_from_1d) { hb1d.CopyFrom(data.data(), data.size()); hb2d.CopyFrom(hb1d, 8); - uint8_t* ptr = static_cast(hb2d.GetPointer()[0]); - EXPECT_EQ(ptr[0], data[0]); - EXPECT_EQ(ptr[1], data[1]); - EXPECT_EQ(ptr[2], data[2]); - EXPECT_EQ(ptr[3], data[3]); - - ptr = static_cast(hb2d.GetPointer()[1]); - EXPECT_EQ(ptr[0], data[4]); - EXPECT_EQ(ptr[1], data[5]); - EXPECT_EQ(ptr[2], data[6]); - EXPECT_EQ(ptr[3], data[7]); + uint8_t** ptr = static_cast(hb2d.GetPointer()); + EXPECT_EQ(ptr[0][0], data[0]); + EXPECT_EQ(ptr[0][1], data[1]); + EXPECT_EQ(ptr[0][2], data[2]); + EXPECT_EQ(ptr[0][3], data[3]); + EXPECT_EQ(ptr[1][0], data[4]); + EXPECT_EQ(ptr[1][1], data[5]); + EXPECT_EQ(ptr[1][2], data[6]); + EXPECT_EQ(ptr[1][3], data[7]); } TEST(HexagonBuffer, 1d_copy_from_2d) { @@ -168,7 +164,7 @@ TEST(HexagonBuffer, 1d_copy_from_2d) { hb2d.CopyFrom(data.data(), data.size()); hb1d.CopyFrom(hb2d, 8); - uint8_t* ptr = static_cast(hb1d.GetPointer()[0]); + uint8_t* ptr = static_cast(hb1d.GetPointer()); for (size_t i = 0; i < data.size(); ++i) { EXPECT_EQ(ptr[i], data[i]); } @@ -245,12 +241,12 @@ TEST(HexagonBuffer, external) { Optional def; HexagonBuffer hb_default(data.data(), data.size(), def); - EXPECT_EQ(hb_default.GetPointer()[0], data.data()); + EXPECT_EQ(hb_default.GetPointer(), data.data()); EXPECT_EQ(hb_default.GetStorageScope(), HexagonBuffer::StorageScope::kDDR); Optional global("global"); HexagonBuffer hb_global(data.data(), data.size(), global); - EXPECT_EQ(hb_global.GetPointer()[0], data.data()); + EXPECT_EQ(hb_global.GetPointer(), data.data()); EXPECT_EQ(hb_global.GetStorageScope(), HexagonBuffer::StorageScope::kDDR); Optional vtcm("global.vtcm"); From 691d260c1a1827de69a57afdd6c3e791d95bf313 Mon Sep 17 00:00:00 2001 From: Eric Lunderberg Date: Thu, 31 Mar 2022 21:06:47 -0500 Subject: [PATCH 5/5] Remove commented GetNumAllocs and unused GetBufferDimension --- src/runtime/hexagon/hexagon/hexagon_buffer.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/runtime/hexagon/hexagon/hexagon_buffer.h b/src/runtime/hexagon/hexagon/hexagon_buffer.h index c26eb7628a27..ad5d04312cf9 100644 --- a/src/runtime/hexagon/hexagon/hexagon_buffer.h +++ b/src/runtime/hexagon/hexagon/hexagon_buffer.h @@ -100,19 +100,6 @@ class HexagonBuffer { */ void* GetPointer(); - // //! \brief Return number of allocations. - // size_t GetNumAllocs() { return nallocs_; } - - /*! \brief Return dimensionality of buffer - * - * Will always be either 1 or 2. If the buffer is 1-d, allocation - * returns a pointer to data, which is accessed by - * ((value_type*)ptr)[i]. If the buffer is 2-d, allocation returns - * a pointer to an array of pointers, which is accessed by - * ((value_type**)ptr)[i][j]. - */ - size_t GetBufferDimension() { return ndim_; } - //! \brief Memory scopes managed by a Hexagon Buffer. enum class StorageScope { //! \brief System DDR corresponding to global storage.