update ovxlib virtual_device patch (#357)
This commit is contained in:
parent
c033cfc582
commit
1eaf326abf
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -27,193 +27,189 @@
|
||||||
|
|
||||||
namespace vip {
|
namespace vip {
|
||||||
|
|
||||||
Device::Device(uint32_t id){
|
Device::Device(uint32_t id) {
|
||||||
id_ = id;
|
id_ = 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{
|
||||||
return id_;
|
return id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::ThreadInit(){
|
void Device::ThreadInit() {
|
||||||
for (std::size_t i = 0; i < threads_.size(); ++i){
|
for (std::size_t i = 0; i < threads_.size(); ++i) {
|
||||||
std::thread t(&Device::HandleQueue, this);
|
std::thread t(&Device::HandleQueue, this);
|
||||||
threads_[i] = std::move(t);
|
threads_[i] = std::move(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::StatusInit(){
|
bool Device::ThreadExit() {
|
||||||
// init thread status after thread id has been generated
|
for (std::size_t i = 0; i < threads_.size(); ++i) {
|
||||||
for (std::size_t i = 0; i < threads_.size(); ++i){
|
graphqueue_->Submit(nullptr, NULL, NULL); // submit fake graph to exit thread
|
||||||
VSILOGI("Init thread[%ld] status = %d", threads_[i].get_id(), IDLE);
|
|
||||||
threads_status_[threads_[i].get_id()] = IDLE;
|
|
||||||
}
|
}
|
||||||
}
|
for (std::size_t i = 0; i < threads_.size(); ++i) {
|
||||||
|
if (threads_[i].joinable()) {
|
||||||
bool Device::ThreadExit(){
|
threads_[i].join();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
return true;
|
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;
|
bool status = false;
|
||||||
status = graphqueue_->Submit(graph, func, data);
|
status = graphqueue_->Submit(graph, func, data);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::GraphRemove(const vsi_nn_graph_t* graph){
|
bool Device::GraphRemove(const vsi_nn_graph_t* graph) {
|
||||||
return graphqueue_->Remove(graph);
|
return graphqueue_->Remove(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::ThreadIdle(){
|
void Device::WaitThreadIdle() {
|
||||||
for (std::size_t i = 0; i < threads_.size(); ++i){
|
ThreadExit();
|
||||||
if (threads_status_[threads_[i].get_id()] != IDLE){
|
ThreadInit();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::WaitThreadIdle(){
|
Worker::Worker() {
|
||||||
if (!ThreadIdle()){
|
|
||||||
VSILOGI("Wait threads idle ...");
|
|
||||||
std::unique_lock<std::mutex> lck(idle_mtx_);
|
|
||||||
idle_cv_.wait(lck);
|
|
||||||
VSILOGI("Threads idle");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Worker::Worker(){
|
void Worker::RunGraph(const vsi_nn_graph_t* graph) {
|
||||||
}
|
|
||||||
|
|
||||||
void Worker::RunGraph(const vsi_nn_graph_t* graph){
|
|
||||||
vsi_nn_RunGraph(graph);
|
vsi_nn_RunGraph(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worker::Handle(const QueueItem& item){
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
||||||
queue_mtx_.lock();
|
queue_mtx_.lock();
|
||||||
VSILOGI("Queue element:");
|
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;
|
auto gid = queue_[i].id;
|
||||||
VSILOGI("%d", gid);
|
VSILOGI("%d", gid);
|
||||||
}
|
}
|
||||||
queue_mtx_.unlock();
|
queue_mtx_.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphQueue::Notify(){
|
void GraphQueue::Notify() {
|
||||||
cv_.notify_one();
|
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();
|
queue_mtx_.lock();
|
||||||
QueueItem item;
|
QueueItem item;
|
||||||
item.graph = graph;
|
item.graph = graph;
|
||||||
item.func = func;
|
item.func = func;
|
||||||
item.data = data;
|
item.data = data;
|
||||||
item.id = gcount_;
|
if (nullptr != graph) {
|
||||||
queue_.push_back(item);
|
item.id = gcount_;
|
||||||
if (graph != NULL){
|
VSILOGI("Submit graph%ld", item.id);
|
||||||
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;
|
std::unique_lock<std::mutex> lock(queue_mtx_);
|
||||||
if (queue_.empty()){
|
QueueItem item = {(size_t)-1, nullptr, NULL, NULL};
|
||||||
std::unique_lock<std::mutex> lock(queue_mtx_);
|
if (queue_.empty()) {
|
||||||
cv_.wait(lock);
|
cv_.wait(lock);
|
||||||
}
|
}
|
||||||
queue_mtx_.lock();
|
if (!queue_.empty()) {
|
||||||
if (!queue_.empty()){
|
auto first = queue_[0];
|
||||||
item = queue_.front();
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GraphQueue::Remove(const vsi_nn_graph_t* graph){
|
bool GraphQueue::Remove(const vsi_nn_graph_t* graph) {
|
||||||
queue_mtx_.lock();
|
queue_mtx_.lock();
|
||||||
std::size_t idx=0;
|
std::size_t idx=0;
|
||||||
bool exist=false;
|
bool exist=false;
|
||||||
if (!queue_.empty()){
|
if (!queue_.empty()) {
|
||||||
for (std::size_t i=0; i < queue_.size(); i++){
|
for (std::size_t i=0; i < queue_.size(); i++) {
|
||||||
if (graph == queue_[i].graph){
|
if (graph == queue_[i].graph) {
|
||||||
idx = i;
|
idx = i;
|
||||||
exist = true;
|
exist = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
device_ = new Device(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
IDevice::~IDevice(){
|
IDevice::~IDevice() {
|
||||||
delete device_;
|
delete device_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,23 +217,19 @@ uint32_t IDevice::Id() const{
|
||||||
return device_->Id();
|
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);
|
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);
|
return device_->GraphRemove(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IDevice::ThreadExit(){
|
bool IDevice::ThreadExit() {
|
||||||
return device_->ThreadExit();
|
return device_->ThreadExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IDevice::ThreadIdle(){
|
void IDevice::WaitThreadIdle() {
|
||||||
return device_->ThreadIdle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void IDevice::WaitThreadIdle(){
|
|
||||||
device_->WaitThreadIdle();
|
device_->WaitThreadIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue