From 0a034252c691c2b4258ddd34b9d3f33fd8a35978 Mon Sep 17 00:00:00 2001 From: "zhao.xia" Date: Fri, 14 May 2021 17:04:55 +0800 Subject: [PATCH] Support tim-lite Lite module for vip lite driver. Signed-off-by: zhao.xia --- BUILD | 34 +++++ include/tim/lite/execution.h | 50 +++++++ include/tim/lite/handle.h | 50 +++++++ src/tim/lite/execution.cc | 217 +++++++++++++++++++++++++++++++ src/tim/lite/execution_private.h | 55 ++++++++ src/tim/lite/handle.cc | 74 +++++++++++ src/tim/lite/handle_private.h | 62 +++++++++ 7 files changed, 542 insertions(+) create mode 100644 include/tim/lite/execution.h create mode 100644 include/tim/lite/handle.h create mode 100644 src/tim/lite/execution.cc create mode 100644 src/tim/lite/execution_private.h create mode 100644 src/tim/lite/handle.cc create mode 100644 src/tim/lite/handle_private.h diff --git a/BUILD b/BUILD index 53012e8..967c001 100644 --- a/BUILD +++ b/BUILD @@ -54,6 +54,40 @@ cc_binary( ], ) +cc_library( + name = "tim-lite_interface", + copts = ["-std=c++14", "-Werror", "-fvisibility=default"], + includes = [ + "include", + "src/tim/lite", + ], + hdrs = [ + "include/tim/lite/execution.h", + "include/tim/lite/handle.h", + ], + srcs = [ + "src/tim/lite/execution_private.h", + "src/tim/lite/execution.cc", + "src/tim/lite/handle_private.h", + "src/tim/lite/handle.cc", + ], + deps = [ + "//viplite:VIP_LITE_LIB", + ], + linkstatic = True, + strip_include_prefix = "include", +) + +cc_binary( + name = "libtim-lite.so", + linkshared = True, + linkstatic = False, + deps = [ + "tim-lite_interface", + ], +) + + ############################################################################## # unit test ############################################################################## diff --git a/include/tim/lite/execution.h b/include/tim/lite/execution.h new file mode 100644 index 0000000..5256502 --- /dev/null +++ b/include/tim/lite/execution.h @@ -0,0 +1,50 @@ +/**************************************************************************** +* +* Copyright (c) 2021 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef __TIM_LITE_EXECUTION_H__ +#define __TIM_LITE_EXECUTION_H__ + +#include +#include +#include "tim/lite/handle.h" + +namespace tim { +namespace lite { + +class Execution { + public: + static std::shared_ptr Create( + const void* executable, size_t executable_size); + template + std::shared_ptr RegisterHandle(Params... parameters) { + return std::make_shared(parameters...); + }; + virtual Execution& BindInputs(std::vector> handles) = 0; + virtual Execution& BindOutputs(std::vector> handles) = 0; + virtual bool Exec() = 0; +}; + +} +} +#endif \ No newline at end of file diff --git a/include/tim/lite/handle.h b/include/tim/lite/handle.h new file mode 100644 index 0000000..5b9b9af --- /dev/null +++ b/include/tim/lite/handle.h @@ -0,0 +1,50 @@ +/**************************************************************************** +* +* Copyright (c) 2021 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef __TIM_LITE_HANDLE_H__ +#define __TIM_LITE_HANDLE_H__ + +#include + +namespace tim { +namespace lite { + +class HandleImpl; + +class Handle { + public: + std::unique_ptr& impl() { return impl_; } + protected: + std::unique_ptr impl_; +}; + +class UserHandle : public Handle { + public: + UserHandle(void* buffer, size_t size); + ~UserHandle(); +}; + +} +} +#endif diff --git a/src/tim/lite/execution.cc b/src/tim/lite/execution.cc new file mode 100644 index 0000000..ea1493f --- /dev/null +++ b/src/tim/lite/execution.cc @@ -0,0 +1,217 @@ +/**************************************************************************** +* +* Copyright (c) 2021 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#include "execution_private.h" + +#include +#include +#include +#include +#include "handle_private.h" + +#include "vip_lite.h" + +namespace tim { +namespace lite { + +static bool _query_input_buffer_parameters( + vip_buffer_create_params_t& param, uint32_t index, vip_network network) { + uint32_t count = 0; + vip_query_network(network, VIP_NETWORK_PROP_INPUT_COUNT, &count); + if (index >= count) { + return false; + } + memset(¶m, 0, sizeof(param)); + param.memory_type = VIP_BUFFER_MEMORY_TYPE_DEFAULT; + vip_query_input(network, index, VIP_BUFFER_PROP_DATA_FORMAT, ¶m.data_format); + vip_query_input(network, index, VIP_BUFFER_PROP_NUM_OF_DIMENSION, ¶m.num_of_dims); + vip_query_input(network, index, VIP_BUFFER_PROP_SIZES_OF_DIMENSION, param.sizes); + vip_query_input(network, index, VIP_BUFFER_PROP_QUANT_FORMAT, ¶m.quant_format); + switch(param.quant_format) { + case VIP_BUFFER_QUANTIZE_DYNAMIC_FIXED_POINT: + vip_query_input(network, index, VIP_BUFFER_PROP_FIXED_POINT_POS, + ¶m.quant_data.dfp.fixed_point_pos); + break; + case VIP_BUFFER_QUANTIZE_TF_ASYMM: + vip_query_input(network, index, VIP_BUFFER_PROP_TF_SCALE, + ¶m.quant_data.affine.scale); + vip_query_input(network, index, VIP_BUFFER_PROP_TF_ZERO_POINT, + ¶m.quant_data.affine.zeroPoint); + default: + break; + } + return true; +} + +static bool _query_output_buffer_parameters( + vip_buffer_create_params_t& param, uint32_t index, vip_network network) { + uint32_t count = 0; + vip_query_network(network, VIP_NETWORK_PROP_OUTPUT_COUNT, &count); + if (index >= count) { + return false; + } + memset(¶m, 0, sizeof(param)); + param.memory_type = VIP_BUFFER_MEMORY_TYPE_DEFAULT; + vip_query_output(network, index, VIP_BUFFER_PROP_DATA_FORMAT, ¶m.data_format); + vip_query_output(network, index, VIP_BUFFER_PROP_NUM_OF_DIMENSION, ¶m.num_of_dims); + vip_query_output(network, index, VIP_BUFFER_PROP_SIZES_OF_DIMENSION, param.sizes); + vip_query_output(network, index, VIP_BUFFER_PROP_QUANT_FORMAT, ¶m.quant_format); + switch(param.quant_format) { + case VIP_BUFFER_QUANTIZE_DYNAMIC_FIXED_POINT: + vip_query_output(network, index, VIP_BUFFER_PROP_FIXED_POINT_POS, + ¶m.quant_data.dfp.fixed_point_pos); + break; + case VIP_BUFFER_QUANTIZE_TF_ASYMM: + vip_query_output(network, index, VIP_BUFFER_PROP_TF_SCALE, + ¶m.quant_data.affine.scale); + vip_query_output(network, index, VIP_BUFFER_PROP_TF_ZERO_POINT, + ¶m.quant_data.affine.zeroPoint); + break; + default: + break; + } + return true; +} + +ExecutionImpl::ExecutionImpl(const void* executable, size_t executable_size) { + vip_status_e status = VIP_SUCCESS; + vip_network network = nullptr; + std::vector data(executable_size); + valid_ = false; + status = vip_init(); + if (status != VIP_SUCCESS) { + return; + } + memcpy(data.data(), executable, executable_size); + status = vip_create_network(data.data(), data.size(), + VIP_CREATE_NETWORK_FROM_MEMORY, &network); + if (status == VIP_SUCCESS && network) { + status = vip_prepare_network(network); + if (status == VIP_SUCCESS) { + network_ = network; + valid_ = true; + } else { + vip_destroy_network(network); + } + } + if (!valid_) { + vip_destroy(); + } +} + +ExecutionImpl::~ExecutionImpl() { + if (!valid_) { + return; + } + if (network_) { + vip_finish_network(network_); + vip_destroy_network(network_); + } + inputs_.clear(); + outputs_.clear(); + vip_destroy(); +} + +Execution& ExecutionImpl::BindInputs(std::vector> handles) { + if (!IsValid()) { + return *this; + } + vip_status_e status = VIP_SUCCESS; + vip_buffer_create_params_t param = { 0 }; + for (uint32_t i = 0; i < handles.size(); i ++) { + auto handle = handles[i]; + if (!handle) { + status = VIP_ERROR_FAILURE; + break; + } + if (!_query_input_buffer_parameters(param, i, network_)) { + status = VIP_ERROR_FAILURE; + break; + } + if (!handle->impl()->Register(param)) { + status = VIP_ERROR_FAILURE; + break; + } + status = vip_set_input(network_, i, handle->impl()->handle()); + if (status != VIP_SUCCESS) { + break; + } + } + // Copy handles + inputs_ = handles; + return *this; +}; + +Execution& ExecutionImpl::BindOutputs(std::vector> handles) { + if (!IsValid()) { + return *this; + } + vip_status_e status = VIP_SUCCESS; + vip_buffer_create_params_t param = { 0 }; + for (uint32_t i = 0; i < handles.size(); i ++) { + auto handle = handles[i]; + if (!handle) { + status = VIP_ERROR_FAILURE; + break; + } + if (!_query_output_buffer_parameters(param, i, network_)) { + status = VIP_ERROR_FAILURE; + break; + } + if (!handle->impl()->Register(param)) { + status = VIP_ERROR_FAILURE; + break; + } + status = vip_set_output(network_, i, handle->impl()->handle()); + if (status != VIP_SUCCESS) { + break; + } + } + // Copy handles + outputs_ = handles; + return *this; +}; + +bool ExecutionImpl::Exec() { + if (!IsValid()) { + return false; + } + vip_status_e status = vip_run_network(network_); + return status == VIP_SUCCESS; +}; + +std::shared_ptr Execution::Create( + const void* executable, size_t executable_size) { + std::shared_ptr exec; + if (executable && executable_size) { + exec = std::make_shared(executable, executable_size); + if (!exec->IsValid()) { + exec.reset(); + } + } + return exec; +} + +} +} diff --git a/src/tim/lite/execution_private.h b/src/tim/lite/execution_private.h new file mode 100644 index 0000000..7511262 --- /dev/null +++ b/src/tim/lite/execution_private.h @@ -0,0 +1,55 @@ +/**************************************************************************** +* +* Copyright (c) 2021 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ +#ifndef __TIM_LITE_EXECUTION_PRIVATE_H__ +#define __TIM_LITE_EXECUTION_PRIVATE_H__ + +#include +#include + +#include "tim/lite/execution.h" +#include "handle_private.h" +#include "vip_lite.h" + +namespace tim { +namespace lite { + +class ExecutionImpl : public Execution { + public : + ExecutionImpl(const void* executable, size_t executable_size); + ~ExecutionImpl(); + Execution& BindInputs(std::vector> handles) override; + Execution& BindOutputs(std::vector> handles) override; + bool Exec() override; + bool IsValid() const { return valid_; }; + vip_network network() { return network_; }; + private: + std::vector> inputs_; + std::vector> outputs_; + bool valid_; + vip_network network_; +}; + +} +} +#endif \ No newline at end of file diff --git a/src/tim/lite/handle.cc b/src/tim/lite/handle.cc new file mode 100644 index 0000000..f48a12e --- /dev/null +++ b/src/tim/lite/handle.cc @@ -0,0 +1,74 @@ +/**************************************************************************** +* +* Copyright (c) 2021 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#include "handle_private.h" + +#include +#include +#include "execution_private.h" +#include "vip_lite.h" + +#define _64_BYTES_ALIGN (64ul) + +namespace tim { +namespace lite { + +UserHandle::UserHandle(void* buffer, size_t size) { + assert((reinterpret_cast(buffer) % _64_BYTES_ALIGN) == 0); + impl_ = std::make_unique(buffer, size); +} + +UserHandle::~UserHandle() { + impl()->Unregister(); +} + +bool UserHandleImpl::Register(vip_buffer_create_params_t& params) { + bool ret = true; + std::call_once(register_once_, [&ret, ¶ms, this]() { + vip_status_e status = VIP_SUCCESS; + vip_buffer internal_buffer = nullptr; + status = vip_create_buffer_from_handle(¶ms, + this->user_buffer(), + this->user_buffer_size(), + &internal_buffer); + if (status == VIP_SUCCESS) { + this->handle_ = internal_buffer; + ret = true; + } else { + ret = false; + } + }); + return ret; +} + +bool UserHandleImpl::Unregister() { + if (handle_) { + vip_destroy_buffer(handle_); + handle_ = nullptr; + } + return true; +} + +} +} diff --git a/src/tim/lite/handle_private.h b/src/tim/lite/handle_private.h new file mode 100644 index 0000000..7713c53 --- /dev/null +++ b/src/tim/lite/handle_private.h @@ -0,0 +1,62 @@ +/**************************************************************************** +* +* Copyright (c) 2021 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef __TIME_LITE_HANDLE_PRIVATE_H__ +#define __TIME_LITE_HANDLE_PRIVATE_H__ + +#include +#include "tim/lite/handle.h" +#include "vip_lite.h" + +namespace tim { +namespace lite { + +class HandleImpl { + public: + HandleImpl() : handle_(nullptr) {} + virtual bool Register(vip_buffer_create_params_t& params) = 0; + virtual bool Unregister() = 0; + vip_buffer handle() { return handle_; } + protected: + vip_buffer handle_; +}; + +class UserHandleImpl : public HandleImpl { + public: + UserHandleImpl(void* buffer, size_t size) + : user_buffer_(buffer), user_buffer_size_(size) {} + bool Register(vip_buffer_create_params_t& params) override; + bool Unregister() override; + size_t user_buffer_size() const { return user_buffer_size_; } + void* user_buffer() { return user_buffer_; } + private: + void* user_buffer_; + size_t user_buffer_size_; + std::once_flag register_once_; +}; + +} +} + +#endif \ No newline at end of file