update ovxlib virtual_device patch (#357)

This commit is contained in:
lucklee 2022-04-13 10:04:46 +08:00 committed by GitHub
parent c033cfc582
commit 1eaf326abf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 102 deletions

View File

@ -44,7 +44,6 @@ class IDevice {
bool GraphSubmit(vsi_nn_graph_t* graph, func_t func, data_t data); bool GraphSubmit(vsi_nn_graph_t* graph, func_t func, data_t data);
bool GraphRemove(const vsi_nn_graph_t* graph); bool GraphRemove(const vsi_nn_graph_t* graph);
bool ThreadExit(); bool ThreadExit();
bool ThreadIdle();
void WaitThreadIdle(); void WaitThreadIdle();
protected: protected:

View File

@ -32,10 +32,10 @@ Device::Device(uint32_t id){
graphqueue_ = std::make_unique<GraphQueue> (); graphqueue_ = std::make_unique<GraphQueue> ();
worker_ = std::make_unique<Worker> ();; worker_ = std::make_unique<Worker> ();;
ThreadInit(); ThreadInit();
StatusInit();
} }
Device::~Device() { Device::~Device() {
ThreadExit();
} }
uint32_t Device::Id() const{ uint32_t Device::Id() const{
@ -49,25 +49,15 @@ void Device::ThreadInit(){
} }
} }
void Device::StatusInit(){
// init thread status after thread id has been generated
for (std::size_t i = 0; i < threads_.size(); ++i){
VSILOGI("Init thread[%ld] status = %d", threads_[i].get_id(), IDLE);
threads_status_[threads_[i].get_id()] = IDLE;
}
}
bool Device::ThreadExit() { bool Device::ThreadExit() {
WaitThreadIdle();
for (std::size_t i = 0; i < threads_.size(); ++i) { for (std::size_t i = 0; i < threads_.size(); ++i) {
threads_status_[threads_[i].get_id()] = CANCEL; graphqueue_->Submit(nullptr, NULL, NULL); // submit fake graph to exit thread
}
for (std::size_t i = 0; i < threads_.size(); ++i){
graphqueue_->Submit(NULL, NULL, NULL); // submit fake graph to exit thread
} }
for (std::size_t i = 0; i < threads_.size(); ++i) { for (std::size_t i = 0; i < threads_.size(); ++i) {
if (threads_[i].joinable()) {
threads_[i].join(); threads_[i].join();
} }
}
return true; return true;
} }
@ -81,22 +71,9 @@ bool Device::GraphRemove(const vsi_nn_graph_t* graph){
return graphqueue_->Remove(graph); return graphqueue_->Remove(graph);
} }
bool Device::ThreadIdle(){
for (std::size_t i = 0; i < threads_.size(); ++i){
if (threads_status_[threads_[i].get_id()] != IDLE){
return false;
}
}
return true;
}
void Device::WaitThreadIdle() { void Device::WaitThreadIdle() {
if (!ThreadIdle()){ ThreadExit();
VSILOGI("Wait threads idle ..."); ThreadInit();
std::unique_lock<std::mutex> lck(idle_mtx_);
idle_cv_.wait(lck);
VSILOGI("Threads idle");
}
} }
Worker::Worker() { Worker::Worker() {
@ -110,12 +87,13 @@ void Worker::Handle(const QueueItem& item){
vsi_nn_graph_t* graph = item.graph; vsi_nn_graph_t* graph = item.graph;
func_t func = item.func; func_t func = item.func;
data_t data = item.data; data_t data = item.data;
if (graph != NULL){ size_t id = item.id;
VSILOGI("Start running graph%d in thread[%ld] ", item.id , std::this_thread::get_id()); if (nullptr != graph) {
VSILOGI("Start running graph%ld in thread[%ld] ", id , std::this_thread::get_id());
RunGraph(graph); RunGraph(graph);
VSILOGI("End running graph%d in thread[%ld]", item.id , std::this_thread::get_id()); VSILOGI("End running graph%ld in thread[%ld]", id , std::this_thread::get_id());
} }
if (func != NULL){ if (NULL != func) {
func(data); func(data);
} }
} }
@ -123,19 +101,18 @@ void Worker::Handle(const QueueItem& item){
void Device::HandleQueue() { void Device::HandleQueue() {
std::thread::id thd_id; std::thread::id thd_id;
thd_id = std::this_thread::get_id(); thd_id = std::this_thread::get_id();
// VSILOGI("Thread[%ld] status = %d", thd_id, threads_status_[thd_id]);
while (1) { while (1) {
QueueItem item = graphqueue_->Fetch(); QueueItem item = graphqueue_->Fetch();
if (threads_status_[thd_id] == IDLE) {threads_status_[thd_id] = RUNNING;} if (0 == item.id) { // exit when fetch fake graph
worker_->Handle(item); // VSILOGD("Thread[%ld] exit", thd_id);
if (threads_status_[thd_id] == RUNNING) {threads_status_[thd_id] = IDLE;} break;
if (threads_status_[thd_id] == CANCEL) {VSILOGI("Thread[%ld] exit", thd_id); break;} }
if ((graphqueue_->Empty()) && ThreadIdle()) {idle_cv_.notify_one();} worker_->Handle(item); // run graph
} }
} }
GraphQueue::GraphQueue() { GraphQueue::GraphQueue() {
gcount_ = 0; gcount_ = 1; // 0 for fake graph
} }
void GraphQueue::Show() { void GraphQueue::Show() {
@ -158,29 +135,38 @@ bool GraphQueue::Submit(vsi_nn_graph_t* graph, func_t func, data_t data){
item.graph = graph; item.graph = graph;
item.func = func; item.func = func;
item.data = data; item.data = data;
if (nullptr != graph) {
item.id = gcount_; item.id = gcount_;
queue_.push_back(item); VSILOGI("Submit graph%ld", item.id);
if (graph != NULL){
VSILOGI("Submit graph%d", item.id);
gcount_++; gcount_++;
if (size_t(-1) == gcount_) {
gcount_ = 1;
} }
}
else{
item.id = 0; // fake graph
}
queue_.push_back(item);
queue_mtx_.unlock(); queue_mtx_.unlock();
Notify(); Notify();
return true; return true;
} }
QueueItem GraphQueue::Fetch() { QueueItem GraphQueue::Fetch() {
QueueItem item;
if (queue_.empty()){
std::unique_lock<std::mutex> lock(queue_mtx_); std::unique_lock<std::mutex> lock(queue_mtx_);
QueueItem item = {(size_t)-1, nullptr, NULL, NULL};
if (queue_.empty()) {
cv_.wait(lock); cv_.wait(lock);
} }
queue_mtx_.lock();
if (!queue_.empty()) { if (!queue_.empty()) {
item = queue_.front(); auto first = queue_[0];
item.id = first.id;
item.graph = first.graph;
item.func = first.func;
item.data = first.data;
queue_.erase(queue_.begin()); queue_.erase(queue_.begin());
} }
queue_mtx_.unlock(); // VSILOGD("Fetch graph%ld[%p] in thread[%ld]", item.id, item.graph, std::this_thread::get_id());
return item; return item;
} }
@ -198,15 +184,25 @@ bool GraphQueue::Remove(const vsi_nn_graph_t* graph){
if (exist) { if (exist) {
auto gid = queue_[idx].id; auto gid = queue_[idx].id;
queue_.erase(queue_.begin() + idx); queue_.erase(queue_.begin() + idx);
VSILOGI("Remove graph%d", gid); VSILOGI("Remove graph%ld", gid);
} }
} }
queue_mtx_.unlock(); queue_mtx_.unlock();
return true; return true;
} }
bool GraphQueue::Empty() const{ bool GraphQueue::Empty() {
return queue_.empty(); queue_mtx_.lock();
bool status = queue_.empty();
queue_mtx_.unlock();
return status;
}
size_t GraphQueue::Size() {
queue_mtx_.lock();
size_t size = queue_.size();
queue_mtx_.unlock();
return size;
} }
IDevice::IDevice(uint32_t id) { IDevice::IDevice(uint32_t id) {
@ -233,10 +229,6 @@ bool IDevice::ThreadExit(){
return device_->ThreadExit(); return device_->ThreadExit();
} }
bool IDevice::ThreadIdle(){
return device_->ThreadIdle();
}
void IDevice::WaitThreadIdle() { void IDevice::WaitThreadIdle() {
device_->WaitThreadIdle(); device_->WaitThreadIdle();
} }

View File

@ -41,18 +41,13 @@ extern "C" {
namespace vip { namespace vip {
enum the_state {
CANCEL,
IDLE,
RUNNING,
};
using func_t = std::function<bool (const void*)>; using func_t = std::function<bool (const void*)>;
using data_t = const void*; using data_t = const void*;
typedef struct _Queueitem{ typedef struct _Queueitem{
size_t id;
vsi_nn_graph_t* graph; vsi_nn_graph_t* graph;
func_t func; func_t func;
data_t data; data_t data;
size_t id;
} QueueItem; } QueueItem;
class GraphQueue{ class GraphQueue{
@ -63,7 +58,8 @@ class GraphQueue{
bool Submit(vsi_nn_graph_t* graph, func_t func, data_t data); bool Submit(vsi_nn_graph_t* graph, func_t func, data_t data);
bool Remove(const vsi_nn_graph_t* graph); bool Remove(const vsi_nn_graph_t* graph);
QueueItem Fetch(); QueueItem Fetch();
bool Empty() const; bool Empty();
size_t Size();
void Notify(); void Notify();
protected: protected:
@ -99,11 +95,7 @@ class Device {
protected: protected:
uint32_t id_; uint32_t id_;
enum the_state thd_state_;
std::array<std::thread, 2> threads_; std::array<std::thread, 2> threads_;
std::map<std::thread::id, the_state> threads_status_;
std::condition_variable idle_cv_;
std::mutex idle_mtx_;
std::unique_ptr<GraphQueue> graphqueue_; std::unique_ptr<GraphQueue> graphqueue_;
std::unique_ptr<Worker> worker_; std::unique_ptr<Worker> worker_;
}; };

View File

@ -37,6 +37,7 @@ aux_source_directory(./vx/internal/src/quantization INTERNAL_QUANTIZATION)
aux_source_directory(./vx/internal/src/custom/ops INTERNAL_CUSTOM_OPS) aux_source_directory(./vx/internal/src/custom/ops INTERNAL_CUSTOM_OPS)
aux_source_directory(./vx/internal/src/custom/ops/kernel INTERNAL_CUSTOM_OPS_KERNEL) aux_source_directory(./vx/internal/src/custom/ops/kernel INTERNAL_CUSTOM_OPS_KERNEL)
aux_source_directory(./vx/internal/src/utils INTERNAL_UTILS) aux_source_directory(./vx/internal/src/utils INTERNAL_UTILS)
aux_source_directory(./vx/internal/src/vip INTERNAL_VIPS)
aux_source_directory(./vx/internal/src/POST POST) aux_source_directory(./vx/internal/src/POST POST)
list(APPEND ${TARGET_NAME}_SRCS list(APPEND ${TARGET_NAME}_SRCS
@ -51,5 +52,6 @@ list(APPEND ${TARGET_NAME}_SRCS
${INTERNAL_CUSTOM_OPS} ${INTERNAL_CUSTOM_OPS}
${INTERNAL_CUSTOM_OPS_KERNEL} ${INTERNAL_CUSTOM_OPS_KERNEL}
${INTERNAL_UTILS} ${INTERNAL_UTILS}
${INTERNAL_VIPS}
${POST} ${POST}
) )