/**************************************************************************** * * 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 #include #include #include "handle_private.h" #include "vip_lite.h" namespace tim { namespace lite { 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_); } input_handles_.clear(); output_handles_.clear(); vip_destroy(); } std::shared_ptr ExecutionImpl::CreateInputHandle(uint32_t in_idx, uint8_t* buffer, size_t size) { auto handle = std::make_shared(buffer, size); if (handle->CreateVipInputBuffer(network_, in_idx)) { return handle; } else { return nullptr; } } std::shared_ptr ExecutionImpl::CreateOutputHandle(uint32_t out_idx, uint8_t* buffer, size_t size) { auto handle = std::make_shared(buffer, size); if (handle->CreateVipPOutputBuffer(network_, out_idx)) { return handle; } else { return nullptr; } } Execution& ExecutionImpl::BindInputs(const std::vector>& handles) { if (!IsValid()) { return *this; } for (auto handle : handles) { if (input_handles_.end() == std::find(input_handles_.begin(), input_handles_.end(), handle)) { input_handles_.push_back(handle); auto handle_impl = std::dynamic_pointer_cast(handle); vip_status_e status = vip_set_input(network_, handle_impl->Index(), handle_impl->VipHandle()); if (status != VIP_SUCCESS) { std::cout << "Set input for network failed." << std::endl; assert(false); } } else { std::cout << "The input handle has been binded, need not bind it again." << std::endl; } } return *this; }; Execution& ExecutionImpl::BindOutputs(const std::vector>& handles) { if (!IsValid()) { return *this; } for (auto handle : handles) { if (output_handles_.end() == std::find(output_handles_.begin(), output_handles_.end(), handle)) { output_handles_.push_back(handle); auto handle_impl = std::dynamic_pointer_cast(handle); vip_status_e status = vip_set_output(network_, handle_impl->Index(), handle_impl->VipHandle()); if (status != VIP_SUCCESS) { std::cout << "Set output for network failed." << std::endl; assert(false); } } else { std::cout << "The output handle has been binded, need not bind it again." << std::endl; } } return *this; }; Execution& ExecutionImpl::UnBindInput(const std::shared_ptr& handle) { auto it = std::find(input_handles_.begin(), input_handles_.end(), handle); if (input_handles_.end() != it) { input_handles_.erase(it); } return *this; } Execution& ExecutionImpl::UnBindOutput(const std::shared_ptr& handle) { auto it = std::find(output_handles_.begin(), output_handles_.end(), handle); if (output_handles_.end() != it) { output_handles_.erase(it); } return *this; } bool ExecutionImpl::Trigger() { 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; } } }