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

[Hexagon] Add HexagonThreadManager #11653

Merged
merged 46 commits into from
Jun 13, 2022
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
5abca09
Adding initial threadmanager class
JosephTheOctonaut Apr 27, 2022
68a3a74
Fixed compile errors
JosephTheOctonaut May 4, 2022
ee8d191
Moving constant defines inside class
JosephTheOctonaut May 5, 2022
53efd21
Updating qurt includes
JosephTheOctonaut May 10, 2022
ca68c77
use default scope for hexagon buffers
JosephTheOctonaut May 11, 2022
691daba
Updating buffer allocations
JosephTheOctonaut May 16, 2022
12864d6
Fixed bug where array of pointers treated as array of structs
JosephTheOctonaut May 16, 2022
e76b5cc
- Updated HexgonDeviceAPI to use HexagonThreadManager
JosephTheOctonaut May 19, 2022
9ccd7f6
Bug fixes + interface addition + basic thread tests
JosephTheOctonaut May 20, 2022
0a78160
Adding initial ThreadManager tests
JosephTheOctonaut May 23, 2022
ad80f5c
HexagonThreadManager tests and refactor
adstraw May 25, 2022
c6afee0
remove stack / pipe size member vars
adstraw May 25, 2022
842e2c8
init pointers in the header file
adstraw May 25, 2022
e87c969
move all mem allocs to SpawnThreads
adstraw May 25, 2022
8fa3043
start_semaphore as object instead of pointer
adstraw May 25, 2022
f7a7da1
fix bug with WaitOnThreads deadlock + Wait/Signal off by one error
adstraw May 26, 2022
96190ad
add / refactor Signal / Wait tests
adstraw May 26, 2022
6ddc75e
add SyncFromTo test cases
adstraw May 26, 2022
39e08a2
add Dispatch test cases
adstraw May 31, 2022
31af076
add pipe fill and overflow cases
adstraw Jun 1, 2022
a13b8b1
Updating dispatch to return bool and fix pipe overflow problem
JosephTheOctonaut Jun 2, 2022
366c921
change around min / max values for stack / pipe
adstraw Jun 2, 2022
d30d3ab
integrate pipe fill / overflow tests back into HTM test suite
adstraw Jun 2, 2022
b5fa501
use HexagonBuffer
adstraw Jun 3, 2022
92213a6
assert if stack / pipe sizes fall below min
adstraw Jun 3, 2022
e6ef7b9
Changed semaphore vector to store pointers, not structs (fixes vector…
JosephTheOctonaut Jun 4, 2022
70c4918
add producer consumer, thread order test cases
adstraw Jun 6, 2022
2ee1b7d
change to unordered_map for semaphores and remove PreallocateSyncs
adstraw Jun 6, 2022
88c7c0a
tests running on device
adstraw Jun 7, 2022
65e3129
code cleanup for compile warnings
adstraw Jun 7, 2022
4f9b43d
remove #if defined(__hexagon__) guards
adstraw Jun 7, 2022
50b6f94
copyright, format, lint
adstraw Jun 8, 2022
c1d2138
add hexagon buffer map class
adstraw Jun 8, 2022
56c91ca
remove redundant thread manager tests
adstraw Jun 8, 2022
6b3b4c5
revert Hex Dev API changes for threading
adstraw Jun 8, 2022
b7ef394
add comments; remove untested code to dispatch / wrap a packed func
adstraw Jun 8, 2022
5461ae4
pass pipe address and not HTM pointer to thread context
adstraw Jun 8, 2022
e74ae69
rename to HexagonBufferManager
adstraw Jun 8, 2022
1a9cdfa
cleanup ahead of PR
adstraw Jun 9, 2022
ebc6f6a
use DLOG(INFO)
adstraw Jun 9, 2022
b8ae415
refactor GetStreamHandles to return a vector by value
adstraw Jun 9, 2022
be1426e
adjust HexagonBufferManager methods; use thread_manager file names
adstraw Jun 9, 2022
3cdc645
style guidelines and debug prints
adstraw Jun 10, 2022
54d092f
static cast for TVMStreamHandle
adstraw Jun 10, 2022
eeecedf
end member variables with underscore
adstraw Jun 10, 2022
9e8c7e4
Merge remote-tracking branch 'upstream/main' into hex-thread-mgr
adstraw Jun 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions src/runtime/hexagon/hexagon_buffer_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* 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_MANAGER_H_
#define TVM_RUNTIME_HEXAGON_HEXAGON_BUFFER_MANAGER_H_

#include <tvm/runtime/logging.h>

#include <memory>
#include <unordered_map>
#include <utility>

#include "hexagon_buffer.h"

namespace tvm {
namespace runtime {
namespace hexagon {

class HexagonBufferManager {
public:
/*!
* \brief Free a HexagonBuffer.
* \param ptr Address of the HexagonBuffer as returned by `AllocateHexagonBuffer`.
*/
void FreeHexagonBuffer(void* ptr) {
auto it = hexagon_buffer_map_.find(ptr);
CHECK(it != hexagon_buffer_map_.end())
<< "Attempt made to free unknown or already freed dataspace allocation";
CHECK(it->second != nullptr);
hexagon_buffer_map_.erase(it);
}
/*!
* \brief Allocate a HexagonBuffer.
* \param args Templated arguments to pass through to HexagonBuffer constructor.
*/
template <typename... Args>
void* AllocateHexagonBuffer(Args&&... args) {
auto buf = std::make_unique<HexagonBuffer>(std::forward<Args>(args)...);
void* ptr = buf->GetPointer();
hexagon_buffer_map_.insert({ptr, std::move(buf)});
return ptr;
}

//! \brief Returns whether the HexagonBuffer is in the map.
size_t count(void* ptr) { return hexagon_buffer_map_.count(ptr); }

//! \brief Returns an iterator to the HexagonBuffer within the map.
HexagonBuffer* find(void* ptr) {
auto it = hexagon_buffer_map_.find(ptr);
if (it != hexagon_buffer_map_.end()) {
return it->second.get();
}
return nullptr;
}

private:
//! \brief Contains the HexagonBuffer objects managed by this class.
std::unordered_map<void*, std::unique_ptr<HexagonBuffer>> hexagon_buffer_map_;
};

} // namespace hexagon
} // namespace runtime
} // namespace tvm

#endif // TVM_RUNTIME_HEXAGON_HEXAGON_BUFFER_MANAGER_H_
29 changes: 7 additions & 22 deletions src/runtime/hexagon/hexagon_device_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <cstring>

#include "../workspace_pool.h"
#include "hexagon_buffer.h"
#include "hexagon_common.h"

namespace tvm {
Expand Down Expand Up @@ -74,14 +73,14 @@ void* HexagonDeviceAPI::AllocDataSpace(Device dev, int ndim, const int64_t* shap
}

if (ndim == 0) {
return AllocateHexagonBuffer(typesize, alignment, mem_scope);
return hexbuffs.AllocateHexagonBuffer(typesize, alignment, mem_scope);
} else if (ndim == 1) {
size_t nbytes = shape[0] * typesize;
return AllocateHexagonBuffer(nbytes, alignment, mem_scope);
return hexbuffs.AllocateHexagonBuffer(nbytes, alignment, mem_scope);
} else if (ndim == 2) {
size_t nallocs = shape[0];
size_t nbytes = shape[1] * typesize;
return AllocateHexagonBuffer(nallocs, nbytes, alignment, mem_scope);
return hexbuffs.AllocateHexagonBuffer(nallocs, nbytes, alignment, mem_scope);
} else {
LOG(FATAL) << "Hexagon Device API supports only 1d and 2d allocations, but received ndim = "
<< ndim;
Expand All @@ -97,13 +96,13 @@ void* HexagonDeviceAPI::AllocDataSpace(Device dev, size_t nbytes, size_t alignme
if (alignment < kHexagonAllocAlignment) {
alignment = kHexagonAllocAlignment;
}
return AllocateHexagonBuffer(nbytes, alignment, String("global"));
return hexbuffs.AllocateHexagonBuffer(nbytes, alignment, String("global"));
}

void HexagonDeviceAPI::FreeDataSpace(Device dev, void* ptr) {
CHECK(ptr) << "buffer pointer is null";
CHECK(IsValidDevice(dev)) << "dev.device_type: " << dev.device_type;
FreeHexagonBuffer(ptr);
hexbuffs.FreeHexagonBuffer(ptr);
}

// WorkSpace: runtime allocations for Hexagon
Expand All @@ -119,7 +118,7 @@ void* HexagonDeviceAPI::AllocWorkspace(Device dev, size_t size, DLDataType type_

void HexagonDeviceAPI::FreeWorkspace(Device dev, void* data) {
CHECK(IsValidDevice(dev)) << "dev.device_type: " << dev.device_type;
CHECK(hexagon_buffer_map_.count(data) != 0)
CHECK(hexbuffs.count(data) != 0)
<< "Attempt made to free unknown or already freed workspace allocation";
dmlc::ThreadLocalStore<HexagonWorkspacePool>::Get()->FreeWorkspace(dev, data);
}
Expand All @@ -143,13 +142,7 @@ void HexagonDeviceAPI::CopyDataFromTo(DLTensor* from, DLTensor* to, TVMStreamHan
CHECK_EQ(to->byte_offset, 0);
CHECK_EQ(GetDataSize(*from), GetDataSize(*to));

auto lookup_hexagon_buffer = [this](void* ptr) -> HexagonBuffer* {
auto it = this->hexagon_buffer_map_.find(ptr);
if (it != this->hexagon_buffer_map_.end()) {
return it->second.get();
}
return nullptr;
};
auto lookup_hexagon_buffer = [this](void* ptr) -> HexagonBuffer* { return hexbuffs.find(ptr); };

HexagonBuffer* hex_from_buf = lookup_hexagon_buffer(from->data);
HexagonBuffer* hex_to_buf = lookup_hexagon_buffer(to->data);
Expand All @@ -172,14 +165,6 @@ void HexagonDeviceAPI::CopyDataFromTo(const void* from, size_t from_offset, void
memcpy(static_cast<char*>(to) + to_offset, static_cast<const char*>(from) + from_offset, size);
}

void HexagonDeviceAPI::FreeHexagonBuffer(void* ptr) {
auto it = hexagon_buffer_map_.find(ptr);
CHECK(it != hexagon_buffer_map_.end())
<< "Attempt made to free unknown or already freed dataspace allocation";
CHECK(it->second != nullptr);
hexagon_buffer_map_.erase(it);
}

TVM_REGISTER_GLOBAL("device_api.hexagon.mem_copy").set_body([](TVMArgs args, TVMRetValue* rv) {
void* dst = args[0];
void* src = args[1];
Expand Down
23 changes: 4 additions & 19 deletions src/runtime/hexagon/hexagon_device_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <vector>

#include "hexagon_buffer.h"
#include "hexagon_buffer_manager.h"

namespace tvm {
namespace runtime {
Expand Down Expand Up @@ -72,7 +73,7 @@ class HexagonDeviceAPI final : public DeviceAPI {
*/
void* AllocWorkspace(Device dev, size_t size, DLDataType type_hint) final;

//! Erase from tracked hexagon_buffer_map and free
//! Erase from HexagonBufferManager and free
void FreeWorkspace(Device dev, void* data) final;

/*!
Expand Down Expand Up @@ -127,18 +128,6 @@ class HexagonDeviceAPI final : public DeviceAPI {
TVMStreamHandle stream) final;

private:
/*! \brief Helper to allocate a HexagonBuffer and register the result
* in the owned buffer map.
* \return Raw data storage managed by the hexagon buffer
*/
template <typename... Args>
void* AllocateHexagonBuffer(Args&&... args) {
auto buf = std::make_unique<HexagonBuffer>(std::forward<Args>(args)...);
void* ptr = buf->GetPointer();
hexagon_buffer_map_.insert({ptr, std::move(buf)});
return ptr;
}

/*! \brief Helper to check if the device type is valid for the Hexagon Device API
* \return Boolean indicating whether the device type is valid
*/
Expand All @@ -148,12 +137,8 @@ class HexagonDeviceAPI final : public DeviceAPI {
(DLDeviceType(dev.device_type) == kDLCPU);
}

/*! \brief Helper to free a HexagonBuffer and unregister the result
* from the owned buffer map.
*/
void FreeHexagonBuffer(void* ptr);
//! Lookup table for the HexagonBuffer managing an allocation.
std::unordered_map<void*, std::unique_ptr<HexagonBuffer>> hexagon_buffer_map_;
//! \brief Manages underlying HexagonBuffer allocations
HexagonBufferManager hexbuffs;
};
} // namespace hexagon
} // namespace runtime
Expand Down
Loading