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 GraphRemove(const vsi_nn_graph_t* graph);
bool ThreadExit();
bool ThreadIdle();
void WaitThreadIdle();
protected:

View File

@ -27,193 +27,189 @@
namespace vip {
Device::Device(uint32_t id){
Device::Device(uint32_t id) {
id_ = id;
graphqueue_ = std::make_unique<GraphQueue> ();
worker_ = std::make_unique<Worker> ();;
ThreadInit();
StatusInit();
}
Device::~Device(){
Device::~Device() {
ThreadExit();
}
uint32_t Device::Id() const{
return id_;
}
void Device::ThreadInit(){
for (std::size_t i = 0; i < threads_.size(); ++i){
void Device::ThreadInit() {
for (std::size_t i = 0; i < threads_.size(); ++i) {
std::thread t(&Device::HandleQueue, this);
threads_[i] = std::move(t);
}
}
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() {
for (std::size_t i = 0; i < threads_.size(); ++i) {
graphqueue_->Submit(nullptr, NULL, NULL); // submit fake graph to exit thread
}
}
bool Device::ThreadExit(){
WaitThreadIdle();
for (std::size_t i = 0; i < threads_.size(); ++i){
threads_status_[threads_[i].get_id()] = CANCEL;
}
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){
threads_[i].join();
for (std::size_t i = 0; i < threads_.size(); ++i) {
if (threads_[i].joinable()) {
threads_[i].join();
}
}
return true;
}
bool Device::GraphSubmit(vsi_nn_graph_t* graph, func_t func, data_t data){
bool Device::GraphSubmit(vsi_nn_graph_t* graph, func_t func, data_t data) {
bool status = false;
status = graphqueue_->Submit(graph, func, data);
return status;
}
bool Device::GraphRemove(const vsi_nn_graph_t* graph){
bool Device::GraphRemove(const vsi_nn_graph_t* 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() {
ThreadExit();
ThreadInit();
}
void Device::WaitThreadIdle(){
if (!ThreadIdle()){
VSILOGI("Wait threads idle ...");
std::unique_lock<std::mutex> lck(idle_mtx_);
idle_cv_.wait(lck);
VSILOGI("Threads idle");
}
Worker::Worker() {
}
Worker::Worker(){
}
void Worker::RunGraph(const vsi_nn_graph_t* graph){
void Worker::RunGraph(const vsi_nn_graph_t* graph) {
vsi_nn_RunGraph(graph);
}
void Worker::Handle(const QueueItem& item){
void Worker::Handle(const QueueItem& item) {
vsi_nn_graph_t* graph = item.graph;
func_t func = item.func;
data_t data = item.data;
if (graph != NULL){
VSILOGI("Start running graph%d in thread[%ld] ", item.id , std::this_thread::get_id());
size_t id = item.id;
if (nullptr != graph) {
VSILOGI("Start running graph%ld in thread[%ld] ", id , std::this_thread::get_id());
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);
}
}
void Device::HandleQueue(){
void Device::HandleQueue() {
std::thread::id thd_id;
thd_id = std::this_thread::get_id();
// VSILOGI("Thread[%ld] status = %d", thd_id, threads_status_[thd_id]);
while (1) {
QueueItem item = graphqueue_->Fetch();
if (threads_status_[thd_id] == IDLE) {threads_status_[thd_id] = RUNNING;}
worker_->Handle(item);
if (threads_status_[thd_id] == RUNNING) {threads_status_[thd_id] = IDLE;}
if (threads_status_[thd_id] == CANCEL) {VSILOGI("Thread[%ld] exit", thd_id); break;}
if ((graphqueue_->Empty()) && ThreadIdle()) {idle_cv_.notify_one();}
if (0 == item.id) { // exit when fetch fake graph
// VSILOGD("Thread[%ld] exit", thd_id);
break;
}
worker_->Handle(item); // run graph
}
}
GraphQueue::GraphQueue(){
gcount_ = 0;
GraphQueue::GraphQueue() {
gcount_ = 1; // 0 for fake graph
}
void GraphQueue::Show(){
void GraphQueue::Show() {
queue_mtx_.lock();
VSILOGI("Queue element:");
for (std::size_t i=0; i < queue_.size(); i++){
for (std::size_t i=0; i < queue_.size(); i++) {
auto gid = queue_[i].id;
VSILOGI("%d", gid);
}
queue_mtx_.unlock();
}
void GraphQueue::Notify(){
void GraphQueue::Notify() {
cv_.notify_one();
}
bool GraphQueue::Submit(vsi_nn_graph_t* graph, func_t func, data_t data){
bool GraphQueue::Submit(vsi_nn_graph_t* graph, func_t func, data_t data) {
queue_mtx_.lock();
QueueItem item;
item.graph = graph;
item.func = func;
item.data = data;
item.id = gcount_;
queue_.push_back(item);
if (graph != NULL){
VSILOGI("Submit graph%d", item.id);
if (nullptr != graph) {
item.id = gcount_;
VSILOGI("Submit graph%ld", item.id);
gcount_++;
if (size_t(-1) == gcount_) {
gcount_ = 1;
}
}
else{
item.id = 0; // fake graph
}
queue_.push_back(item);
queue_mtx_.unlock();
Notify();
return true;
}
QueueItem GraphQueue::Fetch(){
QueueItem item;
if (queue_.empty()){
std::unique_lock<std::mutex> lock(queue_mtx_);
QueueItem GraphQueue::Fetch() {
std::unique_lock<std::mutex> lock(queue_mtx_);
QueueItem item = {(size_t)-1, nullptr, NULL, NULL};
if (queue_.empty()) {
cv_.wait(lock);
}
queue_mtx_.lock();
if (!queue_.empty()){
item = queue_.front();
if (!queue_.empty()) {
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_mtx_.unlock();
// VSILOGD("Fetch graph%ld[%p] in thread[%ld]", item.id, item.graph, std::this_thread::get_id());
return item;
}
bool GraphQueue::Remove(const vsi_nn_graph_t* graph){
bool GraphQueue::Remove(const vsi_nn_graph_t* graph) {
queue_mtx_.lock();
std::size_t idx=0;
bool exist=false;
if (!queue_.empty()){
for (std::size_t i=0; i < queue_.size(); i++){
if (graph == queue_[i].graph){
if (!queue_.empty()) {
for (std::size_t i=0; i < queue_.size(); i++) {
if (graph == queue_[i].graph) {
idx = i;
exist = true;
}
}
if (exist){
if (exist) {
auto gid = queue_[idx].id;
queue_.erase(queue_.begin() + idx);
VSILOGI("Remove graph%d", gid);
VSILOGI("Remove graph%ld", gid);
}
}
queue_mtx_.unlock();
return true;
}
bool GraphQueue::Empty() const{
return queue_.empty();
bool GraphQueue::Empty() {
queue_mtx_.lock();
bool status = queue_.empty();
queue_mtx_.unlock();
return status;
}
IDevice::IDevice(uint32_t id){
size_t GraphQueue::Size() {
queue_mtx_.lock();
size_t size = queue_.size();
queue_mtx_.unlock();
return size;
}
IDevice::IDevice(uint32_t id) {
device_ = new Device(id);
}
IDevice::~IDevice(){
IDevice::~IDevice() {
delete device_;
}
@ -221,23 +217,19 @@ uint32_t IDevice::Id() const{
return device_->Id();
}
bool IDevice::GraphSubmit(vsi_nn_graph_t* graph, func_t func, data_t data){
bool IDevice::GraphSubmit(vsi_nn_graph_t* graph, func_t func, data_t data) {
return device_->GraphSubmit(graph, func, data);
}
bool IDevice::GraphRemove(const vsi_nn_graph_t* graph){
bool IDevice::GraphRemove(const vsi_nn_graph_t* graph) {
return device_->GraphRemove(graph);
}
bool IDevice::ThreadExit(){
bool IDevice::ThreadExit() {
return device_->ThreadExit();
}
bool IDevice::ThreadIdle(){
return device_->ThreadIdle();
}
void IDevice::WaitThreadIdle(){
void IDevice::WaitThreadIdle() {
device_->WaitThreadIdle();
}

View File

@ -41,18 +41,13 @@ extern "C" {
namespace vip {
enum the_state {
CANCEL,
IDLE,
RUNNING,
};
using func_t = std::function<bool (const void*)>;
using data_t = const void*;
typedef struct _Queueitem{
size_t id;
vsi_nn_graph_t* graph;
func_t func;
data_t data;
size_t id;
} QueueItem;
class GraphQueue{
@ -63,7 +58,8 @@ class GraphQueue{
bool Submit(vsi_nn_graph_t* graph, func_t func, data_t data);
bool Remove(const vsi_nn_graph_t* graph);
QueueItem Fetch();
bool Empty() const;
bool Empty();
size_t Size();
void Notify();
protected:
@ -99,11 +95,7 @@ class Device {
protected:
uint32_t id_;
enum the_state thd_state_;
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<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/kernel INTERNAL_CUSTOM_OPS_KERNEL)
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)
list(APPEND ${TARGET_NAME}_SRCS
@ -51,5 +52,6 @@ list(APPEND ${TARGET_NAME}_SRCS
${INTERNAL_CUSTOM_OPS}
${INTERNAL_CUSTOM_OPS_KERNEL}
${INTERNAL_UTILS}
${INTERNAL_VIPS}
${POST}
)