mirror of
https://github.com/m5stack/StackFlow.git
synced 2026-05-20 11:32:11 -07:00
[update] kws support axmodel
This commit is contained in:
@@ -4,10 +4,10 @@ Import('env')
|
||||
with open(env['PROJECT_TOOL_S']) as f:
|
||||
exec(f.read())
|
||||
|
||||
SRCS = Glob('src/*.c*')
|
||||
SRCS = append_srcs_dir(ADir('src'))
|
||||
INCLUDE = [ADir('include'), ADir('.')]
|
||||
PRIVATE_INCLUDE = []
|
||||
REQUIREMENTS = ['pthread', 'dl', 'utilities', 'eventpp', 'StackFlow', 'single_header_libs']
|
||||
REQUIREMENTS = ['pthread', 'dl', 'utilities', 'ax_msp', 'eventpp', 'StackFlow', 'single_header_libs']
|
||||
STATIC_LIB = []
|
||||
DYNAMIC_LIB = []
|
||||
DEFINITIONS = []
|
||||
@@ -22,7 +22,8 @@ DEFINITIONS += ['-std=c++17']
|
||||
LDFLAGS+=['-Wl,-rpath=/opt/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib/gcc-10.3', '-Wl,-rpath=/opt/lib', '-Wl,-rpath=/opt/usr/lib', '-Wl,-rpath=./']
|
||||
LINK_SEARCH_PATH += [ADir('../static_lib')]
|
||||
|
||||
INCLUDE += [ADir('../static_lib/include/sherpa'),
|
||||
INCLUDE += [ADir('src/runner'),
|
||||
ADir('../static_lib/include/sherpa'),
|
||||
ADir('../static_lib/include/sherpa/fbank'),
|
||||
ADir('../static_lib/include/sherpa/sherpa-onnx'),
|
||||
ADir('../static_lib/include/sherpa/sherpa-onnx/onnxruntime-src'),
|
||||
@@ -30,6 +31,7 @@ INCLUDE += [ADir('../static_lib/include/sherpa'),
|
||||
]
|
||||
|
||||
LINK_SEARCH_PATH += [ADir('../static_lib/sherpa/onnx')]
|
||||
REQUIREMENTS += ['ax_engine', 'ax_interpreter', 'ax_sys']
|
||||
REQUIREMENTS += ['onnxruntime']
|
||||
|
||||
LDFLAGS += ['-l:libsherpa-onnx-core.a', '-l:libkaldi-native-fbank-core.a','-l:libkissfft-float.a',
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
*/
|
||||
#include "StackFlow.h"
|
||||
|
||||
#include "EngineWrapper.hpp"
|
||||
#include "ax_sys_api.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@@ -34,9 +37,6 @@ static std::string base_model_config_path_;
|
||||
typedef std::function<void(const std::string &data, bool finish)> task_callback_t;
|
||||
|
||||
#include "sherpa-onnx/csrc/keyword-spotter.h"
|
||||
#include "sherpa-onnx/csrc/parse-options.h"
|
||||
|
||||
#include <onnxruntime_cxx_api.h>
|
||||
#include "kaldi-native-fbank/csrc/online-feature.h"
|
||||
|
||||
typedef struct mode_config_onnx {
|
||||
@@ -61,6 +61,7 @@ private:
|
||||
bool enstream_ = false;
|
||||
bool enwake_audio_ = true;
|
||||
std::atomic_bool audio_flage_;
|
||||
static int ax_init_flage_;
|
||||
task_callback_t out_callback_;
|
||||
buffer_t *pcmdata;
|
||||
std::string wake_wav_file_;
|
||||
@@ -72,8 +73,8 @@ private:
|
||||
std::unique_ptr<sherpa_onnx::OnlineStream> sherpa_stream_;
|
||||
|
||||
kws_config_onnx onnx_config_;
|
||||
std::vector<float> onnx_cache_;
|
||||
std::unique_ptr<Ort::Session> onnx_session_;
|
||||
std::vector<float> axera_cache_;
|
||||
std::unique_ptr<EngineWrapper> axera_session_;
|
||||
knf::FbankOptions fbank_opts_;
|
||||
std::unique_ptr<knf::OnlineFbank> fbank_;
|
||||
Ort::Env onnx_env_{ORT_LOGGING_LEVEL_WARNING, "kws"};
|
||||
@@ -328,16 +329,20 @@ public:
|
||||
}
|
||||
std::string base_model = base_model_path_ + model_ + "/";
|
||||
SLOGI("base_model %s", base_model.c_str());
|
||||
std::string model_file = base_model + "kws.onnx";
|
||||
std::string model_file = base_model + "kws.axmodel";
|
||||
|
||||
if (config_body.contains("wake_wav_file"))
|
||||
wake_wav_file_ = config_body["wake_wav_file"];
|
||||
else if (file_body["mode_param"].contains("wake_wav_file"))
|
||||
wake_wav_file_ = file_body["mode_param"]["wake_wav_file"];
|
||||
|
||||
onnx_session_ = std::make_unique<Ort::Session>(onnx_env_, model_file.c_str(), session_options_);
|
||||
axera_session_ = std::make_unique<EngineWrapper>();
|
||||
if (0 != axera_session_->Init(model_file.c_str())) {
|
||||
SLOGE("Init axera model failed!");
|
||||
return -5;
|
||||
}
|
||||
|
||||
onnx_cache_.assign(1 * 32 * 88, 0.0f);
|
||||
axera_cache_.assign(1 * 32 * 88, 0.0f);
|
||||
|
||||
auto &mp = file_body["mode_param"];
|
||||
CONFIG_AUTO_SET_ONNX(mp, chunk_size);
|
||||
@@ -414,37 +419,46 @@ public:
|
||||
|
||||
std::vector<float> run_inference(const std::vector<float> &audio_chunk_16k)
|
||||
{
|
||||
std::vector<std::vector<float>> fbank_feats;
|
||||
fbank_feats = compute_fbank_kaldi(audio_chunk_16k, onnx_config_.RESAMPLE_RATE, onnx_config_.FEAT_DIM);
|
||||
if (fbank_feats.empty()) {
|
||||
std::vector<std::vector<float>> fbank_feats =
|
||||
compute_fbank_kaldi(audio_chunk_16k, onnx_config_.RESAMPLE_RATE, onnx_config_.FEAT_DIM);
|
||||
if (fbank_feats.empty()) return {};
|
||||
|
||||
constexpr int FIX_T = 32;
|
||||
const int FEAT_DIM = onnx_config_.FEAT_DIM;
|
||||
|
||||
std::vector<float> mat_flattened;
|
||||
mat_flattened.resize(FIX_T * FEAT_DIM, 0.0f);
|
||||
|
||||
const int T_in = static_cast<int>(fbank_feats.size());
|
||||
const int T_copy = std::min(T_in, FIX_T);
|
||||
|
||||
for (int t = 0; t < T_copy; ++t) {
|
||||
if ((int)fbank_feats[t].size() < FEAT_DIM) continue;
|
||||
std::memcpy(mat_flattened.data() + t * FEAT_DIM, fbank_feats[t].data(), sizeof(float) * FEAT_DIM);
|
||||
}
|
||||
|
||||
axera_session_->SetInput(mat_flattened.data(), 0);
|
||||
|
||||
axera_session_->SetInput(axera_cache_.data(), 1);
|
||||
|
||||
int ret = axera_session_->Run();
|
||||
if (ret) {
|
||||
SLOGE("axera_session run failed!");
|
||||
return {};
|
||||
}
|
||||
int T = fbank_feats.size();
|
||||
std::vector<float> mat_flattened;
|
||||
for (const auto &feat : fbank_feats) {
|
||||
mat_flattened.insert(mat_flattened.end(), feat.begin(), feat.end());
|
||||
|
||||
const float *out_ptr = reinterpret_cast<const float *>(axera_session_->GetOutputPtr(0));
|
||||
size_t out_size_f = axera_session_->GetOutputSize(0) / sizeof(float);
|
||||
std::vector<float> out_chunk(out_ptr, out_ptr + out_size_f);
|
||||
|
||||
const float *cache_ptr = reinterpret_cast<const float *>(axera_session_->GetOutputPtr(1));
|
||||
size_t cache_size_f = axera_session_->GetOutputSize(1) / sizeof(float);
|
||||
if (cache_size_f != axera_cache_.size()) {
|
||||
SLOGE("cache size mismatch: out=%zu, local=%zu", cache_size_f, axera_cache_.size());
|
||||
return out_chunk;
|
||||
}
|
||||
std::vector<int64_t> input_shape = {1, static_cast<int64_t>(T), onnx_config_.FEAT_DIM};
|
||||
std::vector<int64_t> cache_shape = {1, 32, 88};
|
||||
Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeDefault);
|
||||
Ort::Value input_tensor = Ort::Value::CreateTensor<float>(
|
||||
memory_info, mat_flattened.data(), mat_flattened.size(), input_shape.data(), input_shape.size());
|
||||
Ort::Value cache_tensor = Ort::Value::CreateTensor<float>(memory_info, onnx_cache_.data(), onnx_cache_.size(),
|
||||
cache_shape.data(), cache_shape.size());
|
||||
const char *input_names[] = {"input", "cache"};
|
||||
const char *output_names[] = {"output", "r_cache"};
|
||||
std::vector<Ort::Value> inputs;
|
||||
inputs.push_back(std::move(input_tensor));
|
||||
inputs.push_back(std::move(cache_tensor));
|
||||
auto output_tensors =
|
||||
onnx_session_->Run(Ort::RunOptions{nullptr}, input_names, inputs.data(), 2, output_names, 2);
|
||||
float *out_data = output_tensors[0].GetTensorMutableData<float>();
|
||||
float *cache_out_data = output_tensors[1].GetTensorMutableData<float>();
|
||||
std::vector<int64_t> out_shape = output_tensors[0].GetTensorTypeAndShapeInfo().GetShape();
|
||||
size_t out_size = 1;
|
||||
for (auto dim : out_shape) out_size *= dim;
|
||||
std::vector<float> out_chunk(out_data, out_data + out_size);
|
||||
std::copy(cache_out_data, cache_out_data + onnx_cache_.size(), onnx_cache_.begin());
|
||||
std::memcpy(axera_cache_.data(), cache_ptr, axera_cache_.size() * sizeof(float));
|
||||
|
||||
return out_chunk;
|
||||
}
|
||||
|
||||
@@ -531,16 +545,45 @@ public:
|
||||
|
||||
bool delete_model()
|
||||
{
|
||||
sherpa_spotter_.reset();
|
||||
sherpa_stream_.reset();
|
||||
onnx_session_.reset();
|
||||
fbank_.reset();
|
||||
if (sherpa_spotter_) sherpa_spotter_.reset();
|
||||
if (sherpa_stream_) sherpa_stream_.reset();
|
||||
if (axera_session_) axera_session_->Release();
|
||||
if (fbank_) fbank_.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
llm_task(const std::string &workid) : audio_flage_(false)
|
||||
{
|
||||
pcmdata = buffer_create();
|
||||
_ax_init();
|
||||
}
|
||||
|
||||
void _ax_init()
|
||||
{
|
||||
if (!ax_init_flage_) {
|
||||
int ret = AX_SYS_Init();
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "AX_SYS_Init failed! ret = 0x%x\n", ret);
|
||||
}
|
||||
AX_ENGINE_NPU_ATTR_T npu_attr;
|
||||
memset(&npu_attr, 0, sizeof(npu_attr));
|
||||
ret = AX_ENGINE_Init(&npu_attr);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "Init ax-engine failed{0x%8x}.\n", ret);
|
||||
}
|
||||
}
|
||||
ax_init_flage_++;
|
||||
}
|
||||
|
||||
void _ax_deinit()
|
||||
{
|
||||
if (ax_init_flage_ > 0) {
|
||||
--ax_init_flage_;
|
||||
if (!ax_init_flage_) {
|
||||
AX_ENGINE_Deinit();
|
||||
AX_SYS_Deinit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void start()
|
||||
@@ -555,9 +598,13 @@ public:
|
||||
{
|
||||
stop();
|
||||
buffer_destroy(pcmdata);
|
||||
if (axera_session_) axera_session_->Release();
|
||||
_ax_deinit();
|
||||
}
|
||||
};
|
||||
|
||||
int llm_task::ax_init_flage_ = 0;
|
||||
|
||||
class llm_kws : public StackFlow {
|
||||
private:
|
||||
enum { EVENT_TRIGGER = EVENT_EXPORT + 1 };
|
||||
|
||||
@@ -0,0 +1,357 @@
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2023 Axera Semiconductor (Ningbo) Co., Ltd. All Rights Reserved.
|
||||
*
|
||||
* This source file is the property of Axera Semiconductor (Ningbo) Co., Ltd. and
|
||||
* may not be copied or distributed in any isomorphic form without the prior
|
||||
* written consent of Axera Semiconductor (Ningbo) Co., Ltd.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
#include "EngineWrapper.hpp"
|
||||
#include "utils/io.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <global_config.h>
|
||||
|
||||
#if defined(CONFIG_AX_650C_MSP_ENABLED)
|
||||
static const char *strAlgoModelType[AX_ENGINE_MODEL_TYPE_BUTT] = {"3.6T", "7.2T", "18T"};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_AX_620E_MSP_ENABLED) || defined(CONFIG_AX_620Q_MSP_ENABLED)
|
||||
static const char *strAlgoModelType[AX_ENGINE_MODEL_TYPE_BUTT] = {"HalfOCM", "FullOCM"};
|
||||
#endif
|
||||
|
||||
/// @brief npu type
|
||||
typedef enum axNPU_TYPE_E {
|
||||
AX_NPU_DEFAULT = 0, /* running under default NPU according to system */
|
||||
AX_STD_VNPU_1 = (1 << 0), /* running under STD VNPU1 */
|
||||
AX_STD_VNPU_2 = (1 << 1), /* running under STD VNPU2 */
|
||||
AX_STD_VNPU_3 = (1 << 2), /* running under STD VNPU3 */
|
||||
AX_BL_VNPU_1 = (1 << 3), /* running under BIG-LITTLE VNPU1 */
|
||||
AX_BL_VNPU_2 = (1 << 4) /* running under BIG-LITTLE VNPU2 */
|
||||
} AX_NPU_TYPE_E;
|
||||
|
||||
#if defined(CONFIG_AX_650C_MSP_ENABLED)
|
||||
static AX_S32 CheckModelVNpu(const std::string &strModel, const AX_ENGINE_MODEL_TYPE_T &eModelType,
|
||||
const AX_S32 &nNpuType, AX_U32 &nNpuSet)
|
||||
{
|
||||
AX_ENGINE_NPU_ATTR_T stNpuAttr;
|
||||
memset(&stNpuAttr, 0x00, sizeof(stNpuAttr));
|
||||
|
||||
auto ret = AX_ENGINE_GetVNPUAttr(&stNpuAttr);
|
||||
if (ret == 0) {
|
||||
// VNPU DISABLE
|
||||
if (stNpuAttr.eHardMode == AX_ENGINE_VIRTUAL_NPU_DISABLE) {
|
||||
nNpuSet = 0x01; // NON-VNPU (0b111)
|
||||
// printf("%s will run under VNPU-DISABLE [%s]\n", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
}
|
||||
// STD VNPU
|
||||
else if (stNpuAttr.eHardMode == AX_ENGINE_VIRTUAL_NPU_STD) {
|
||||
// 7.2T & 10.8T no allow
|
||||
if (eModelType == AX_ENGINE_MODEL_TYPE1 || eModelType == AX_ENGINE_MODEL_TYPE2) {
|
||||
// printf("%s model type%d: [%s], no allow run under STD VNPU\n", strModel.c_str(), eModelType,
|
||||
// strAlgoModelType[eModelType]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// default STD VNPU2
|
||||
if (nNpuType == 0) {
|
||||
nNpuSet = 0x02; // VNPU2 (0b010)
|
||||
// printf("%s will run under default STD-VNPU2 [%s]\n", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
} else {
|
||||
if (nNpuType & AX_STD_VNPU_1) {
|
||||
nNpuSet |= 0x01; // VNPU1 (0b001)
|
||||
// printf("%s will run under STD-VNPU1 [%s]\n", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
}
|
||||
if (nNpuType & AX_STD_VNPU_2) {
|
||||
nNpuSet |= 0x02; // VNPU2 (0b010)
|
||||
// printf("%s will run under STD-VNPU2 [%s]\n", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
}
|
||||
if (nNpuType & AX_STD_VNPU_3) {
|
||||
nNpuSet |= 0x04; // VNPU3 (0b100)
|
||||
// printf("%s will run under STD-VNPU3 [%s]\n", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// BL VNPU
|
||||
else if (stNpuAttr.eHardMode == AX_ENGINE_VIRTUAL_NPU_BIG_LITTLE) {
|
||||
// 10.8T no allow
|
||||
if (eModelType == AX_ENGINE_MODEL_TYPE2) {
|
||||
// printf("%s model type%d: [%s], no allow run under BL VNPU\n", strModel.c_str(), eModelType,
|
||||
// strAlgoModelType[eModelType]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// default BL VNPU
|
||||
if (nNpuType == 0) {
|
||||
// 7.2T default BL VNPU1
|
||||
if (eModelType == AX_ENGINE_MODEL_TYPE1) {
|
||||
nNpuSet = 0x01; // VNPU1 (0b001)
|
||||
// printf("%s will run under default BL-VNPU1 [%s]\n", strModel.c_str(),
|
||||
// strAlgoModelType[eModelType]);
|
||||
}
|
||||
// 3.6T default BL VNPU2
|
||||
else {
|
||||
nNpuSet = 0x02; // VNPU2 (0b010)
|
||||
// printf("%s will run under default BL-VNPU2 [%s]\n", strModel.c_str(),
|
||||
// strAlgoModelType[eModelType]);
|
||||
}
|
||||
} else {
|
||||
// 7.2T
|
||||
if (eModelType == AX_ENGINE_MODEL_TYPE1) {
|
||||
// no allow set to BL VNPU2
|
||||
if (nNpuType & AX_BL_VNPU_2) {
|
||||
// printf("%s model type%d: [%s], no allow run under BL VNPU2\n", strModel.c_str(), eModelType,
|
||||
// strAlgoModelType[eModelType]);
|
||||
return -1;
|
||||
}
|
||||
if (nNpuType & AX_BL_VNPU_1) {
|
||||
nNpuSet |= 0x01; // VNPU1 (0b001)
|
||||
// printf("%s will run under BL-VNPU1 [%s]\n", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
}
|
||||
}
|
||||
// 3.6T
|
||||
else {
|
||||
if (nNpuType & AX_BL_VNPU_1) {
|
||||
nNpuSet |= 0x01; // VNPU1 (0b001)
|
||||
// printf("%s will run under BL-VNPU1 [%s]\n", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
}
|
||||
if (nNpuType & AX_BL_VNPU_2) {
|
||||
nNpuSet |= 0x02; // VNPU2 (0b010)
|
||||
// printf("%s will run under BL-VNPU2 [%s]\n", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("AX_ENGINE_GetVNPUAttr fail ret = %x\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_AX_620E_MSP_ENABLED) || defined(CONFIG_AX_620Q_MSP_ENABLED)
|
||||
static AX_S32 CheckModelVNpu(const std::string &strModel, const AX_ENGINE_MODEL_TYPE_T &eModelType,
|
||||
const AX_S32 &nNpuType, AX_U32 &nNpuSet)
|
||||
{
|
||||
AX_ENGINE_NPU_ATTR_T stNpuAttr;
|
||||
memset(&stNpuAttr, 0x00, sizeof(stNpuAttr));
|
||||
|
||||
auto ret = AX_ENGINE_GetVNPUAttr(&stNpuAttr);
|
||||
if (ret == 0) {
|
||||
// VNPU DISABLE
|
||||
if (stNpuAttr.eHardMode == AX_ENGINE_VIRTUAL_NPU_DISABLE) {
|
||||
nNpuSet = 0x01; // NON-VNPU (0b111)
|
||||
// ALOGN("%s will run under VNPU-DISABLE [%s]", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
}
|
||||
// STD VNPU
|
||||
else if (stNpuAttr.eHardMode == AX_ENGINE_VIRTUAL_NPU_ENABLE) {
|
||||
// full ocm model was no allowned
|
||||
if (eModelType == AX_ENGINE_MODEL_TYPE1) {
|
||||
// printf("%s model type%d: [%s], no allow run under STD VNPU", strModel.c_str(), eModelType,
|
||||
// strAlgoModelType[eModelType]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// default STD VNPU2
|
||||
if (nNpuType == 0) {
|
||||
nNpuSet = 0x02; // VNPU2 (0b010)
|
||||
// printf("%s will run under default STD-VNPU2 [%s]", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
} else {
|
||||
if (nNpuType & AX_STD_VNPU_1) {
|
||||
nNpuSet |= 0x01; // VNPU1 (0b001)
|
||||
// printf("%s will run under STD-VNPU1 [%s]", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
}
|
||||
if (nNpuType & AX_STD_VNPU_2) {
|
||||
nNpuSet |= 0x02; // VNPU2 (0b010)
|
||||
// printf("%s will run under STD-VNPU2 [%s]", strModel.c_str(), strAlgoModelType[eModelType]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("AX_ENGINE_GetVNPUAttr fail ret = %x", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int EngineWrapper::Init(const char *strModelPath, uint32_t nNpuType)
|
||||
{
|
||||
AX_S32 ret = 0;
|
||||
|
||||
// 1. load model
|
||||
AX_BOOL bLoadModelUseCmm = AX_TRUE;
|
||||
AX_CHAR *pModelBufferVirAddr = nullptr;
|
||||
AX_U64 u64ModelBufferPhyAddr = 0;
|
||||
AX_U32 nModelBufferSize = 0;
|
||||
|
||||
std::vector<char> model_buffer;
|
||||
|
||||
if (bLoadModelUseCmm) {
|
||||
if (!utils::read_file(strModelPath, (AX_VOID **)&pModelBufferVirAddr, u64ModelBufferPhyAddr,
|
||||
nModelBufferSize)) {
|
||||
printf("ALGO read model(%s) fail\n", strModelPath);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (!utils::read_file(strModelPath, model_buffer)) {
|
||||
printf("ALGO read model(%s) fail\n", strModelPath);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pModelBufferVirAddr = model_buffer.data();
|
||||
nModelBufferSize = model_buffer.size();
|
||||
}
|
||||
|
||||
auto freeModelBuffer = [&]() {
|
||||
if (bLoadModelUseCmm) {
|
||||
if (u64ModelBufferPhyAddr != 0) {
|
||||
AX_SYS_MemFree(u64ModelBufferPhyAddr, &pModelBufferVirAddr);
|
||||
}
|
||||
} else {
|
||||
std::vector<char>().swap(model_buffer);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
// 1.1 Get Model Type
|
||||
AX_ENGINE_MODEL_TYPE_T eModelType = AX_ENGINE_MODEL_TYPE0;
|
||||
ret = AX_ENGINE_GetModelType(pModelBufferVirAddr, nModelBufferSize, &eModelType);
|
||||
if (0 != ret || eModelType >= AX_ENGINE_MODEL_TYPE_BUTT) {
|
||||
printf("%s AX_ENGINE_GetModelType fail ret=%x, eModelType=%d\n", strModelPath, eModelType);
|
||||
freeModelBuffer();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 1.2 Check VNPU
|
||||
AX_ENGINE_NPU_SET_T nNpuSet = 0;
|
||||
ret = CheckModelVNpu(strModelPath, eModelType, nNpuType, nNpuSet);
|
||||
if (0 != ret) {
|
||||
printf("ALGO CheckModelVNpu fail\n");
|
||||
freeModelBuffer();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. create handle
|
||||
AX_ENGINE_HANDLE handle = nullptr;
|
||||
ret = AX_ENGINE_CreateHandle(&handle, pModelBufferVirAddr, nModelBufferSize);
|
||||
auto deinit_handle = [&handle]() {
|
||||
if (handle) {
|
||||
AX_ENGINE_DestroyHandle(handle);
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
freeModelBuffer();
|
||||
|
||||
if (0 != ret || !handle) {
|
||||
printf("ALGO Create model(%s) handle fail\n", strModelPath);
|
||||
|
||||
return deinit_handle();
|
||||
}
|
||||
|
||||
// 3. create context
|
||||
ret = AX_ENGINE_CreateContext(handle);
|
||||
if (0 != ret) {
|
||||
return deinit_handle();
|
||||
}
|
||||
|
||||
// 4. set io
|
||||
m_io_info = nullptr;
|
||||
ret = AX_ENGINE_GetIOInfo(handle, &m_io_info);
|
||||
if (0 != ret) {
|
||||
return deinit_handle();
|
||||
}
|
||||
m_input_num = m_io_info->nInputSize;
|
||||
m_output_num = m_io_info->nOutputSize;
|
||||
|
||||
// 4.1 query io
|
||||
// AX_IMG_FORMAT_E eDtype;
|
||||
// ret = utils::query_model_input_size(m_io_info, m_input_size, eDtype);//FIXME.
|
||||
// if (0 != ret) {
|
||||
// printf("model(%s) query model input size fail\n", strModelPath.c_str());
|
||||
// return deinit_handle();
|
||||
// }
|
||||
|
||||
// if (!(eDtype == AX_FORMAT_YUV420_SEMIPLANAR || eDtype == AX_FORMAT_YUV420_SEMIPLANAR_VU ||
|
||||
// eDtype == AX_FORMAT_RGB888 || eDtype == AX_FORMAT_BGR888)) {
|
||||
// printf("model(%s) data type is: 0x%02X, unsupport\n", strModelPath, eDtype);
|
||||
// return deinit_handle();
|
||||
// }
|
||||
|
||||
// 4.2 brief io
|
||||
#ifdef __DEBUG__
|
||||
printf("brief_io_info\n");
|
||||
utils::brief_io_info(strModelPath, m_io_info);
|
||||
#endif
|
||||
|
||||
// 5. Config VNPU
|
||||
// printf("model(%s) nNpuSet: 0x%08X\n", strModelPath.c_str(), nNpuSet);
|
||||
// will do nothing for using create handle v2 api
|
||||
|
||||
// 6. prepare io
|
||||
// AX_U32 nIoDepth = (stCtx.vecOutputBufferFlag.size() == 0) ? 1 : stCtx.vecOutputBufferFlag.size();
|
||||
ret = utils::prepare_io(strModelPath, m_io_info, m_io, utils::IO_BUFFER_STRATEGY_DEFAULT);
|
||||
if (0 != ret) {
|
||||
printf("prepare io failed!\n");
|
||||
utils::free_io(m_io);
|
||||
return deinit_handle();
|
||||
}
|
||||
|
||||
m_handle = handle;
|
||||
m_hasInit = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EngineWrapper::SetInput(void *pInput, int index)
|
||||
{
|
||||
return utils::push_io_input(pInput, index, m_io);
|
||||
}
|
||||
|
||||
int EngineWrapper::Run()
|
||||
{
|
||||
if (!m_hasInit) return -1;
|
||||
|
||||
// 7.3 run & benchmark
|
||||
auto ret = AX_ENGINE_RunSync(m_handle, &m_io);
|
||||
if (0 != ret) {
|
||||
printf("AX_ENGINE_RunSync failed. ret=0x%x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EngineWrapper::GetOutput(void *pOutput, int index)
|
||||
{
|
||||
return utils::push_io_output(pOutput, index, m_io);
|
||||
}
|
||||
|
||||
int EngineWrapper::GetInputSize(int index)
|
||||
{
|
||||
return m_io.pInputs[index].nSize;
|
||||
}
|
||||
|
||||
int EngineWrapper::GetOutputSize(int index)
|
||||
{
|
||||
return m_io.pOutputs[index].nSize;
|
||||
}
|
||||
|
||||
void *EngineWrapper::GetOutputPtr(int index)
|
||||
{
|
||||
utils::cache_io_flush(&m_io.pOutputs[index]);
|
||||
return m_io.pOutputs[index].pVirAddr;
|
||||
}
|
||||
|
||||
int EngineWrapper::Release()
|
||||
{
|
||||
if (m_handle) {
|
||||
utils::free_io(m_io);
|
||||
AX_ENGINE_DestroyHandle(m_handle);
|
||||
m_handle = nullptr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2023 Axera Semiconductor (Ningbo) Co., Ltd. All Rights Reserved.
|
||||
*
|
||||
* This source file is the property of Axera Semiconductor (Ningbo) Co., Ltd. and
|
||||
* may not be copied or distributed in any isomorphic form without the prior
|
||||
* written consent of Axera Semiconductor (Ningbo) Co., Ltd.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
#include "ax_engine_api.h"
|
||||
|
||||
class EngineWrapper {
|
||||
public:
|
||||
EngineWrapper() : m_hasInit(false), m_handle(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
~EngineWrapper()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
int Init(const char* strModelPath, uint32_t nNpuType = 0);
|
||||
|
||||
int SetInput(void* pInput, int index);
|
||||
|
||||
int Run();
|
||||
|
||||
int GetOutput(void* pOutput, int index);
|
||||
|
||||
int GetInputSize(int index);
|
||||
int GetOutputSize(int index);
|
||||
|
||||
void* GetOutputPtr(int index);
|
||||
|
||||
int Release();
|
||||
|
||||
protected:
|
||||
bool m_hasInit;
|
||||
AX_ENGINE_HANDLE m_handle;
|
||||
AX_ENGINE_IO_INFO_T* m_io_info{};
|
||||
AX_ENGINE_IO_T m_io{};
|
||||
int m_input_num{}, m_output_num{};
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2023 Axera Semiconductor (Ningbo) Co., Ltd. All Rights Reserved.
|
||||
*
|
||||
* This source file is the property of Axera Semiconductor (Ningbo) Co., Ltd. and
|
||||
* may not be copied or distributed in any isomorphic form without the prior
|
||||
* written consent of Axera Semiconductor (Ningbo) Co., Ltd.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef AX_CHECKER_H
|
||||
#define AX_CHECKER_H
|
||||
|
||||
#include "utils/logger.h"
|
||||
|
||||
#define CHECK_PTR(p) \
|
||||
do { \
|
||||
if (!p) { \
|
||||
ALOGE("%s nil pointer\n", #p); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_INITED(p) \
|
||||
do { \
|
||||
if (!p->HasInit()) { \
|
||||
ALOGE("%s has not init\n", #p); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif // AX_CHECKER_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2023 Axera Semiconductor (Ningbo) Co., Ltd. All Rights Reserved.
|
||||
*
|
||||
* This source file is the property of Axera Semiconductor (Ningbo) Co., Ltd. and
|
||||
* may not be copied or distributed in any isomorphic form without the prior
|
||||
* written consent of Axera Semiconductor (Ningbo) Co., Ltd.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef SKEL_LOGGER_H
|
||||
#define SKEL_LOGGER_H
|
||||
|
||||
#include "ax_global_type.h"
|
||||
#include "ax_sys_log.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// #define SKEL_LOG_TAG "SKEL"
|
||||
//
|
||||
// #define ALOGE(fmt, ...) AX_LOG_ERR_EX(SKEL_LOG_TAG, AX_ID_SKEL, fmt, ##__VA_ARGS__)
|
||||
// #define ALOGW(fmt, ...) AX_LOG_WARN_EX(SKEL_LOG_TAG, AX_ID_SKEL, fmt, ##__VA_ARGS__)
|
||||
// #define ALOGI(fmt, ...) AX_LOG_INFO_EX(SKEL_LOG_TAG, AX_ID_SKEL, fmt, ##__VA_ARGS__)
|
||||
// #define ALOGD(fmt, ...) AX_LOG_DBG_EX(SKEL_LOG_TAG, AX_ID_SKEL, fmt, ##__VA_ARGS__)
|
||||
// #define ALOGN(fmt, ...) AX_LOG_NOTICE_EX(SKEL_LOG_TAG, AX_ID_SKEL, fmt, ##__VA_ARGS__)
|
||||
|
||||
typedef enum {
|
||||
SKEL_LOG_MIN = -1,
|
||||
SKEL_LOG_EMERGENCY = 0,
|
||||
SKEL_LOG_ALERT = 1,
|
||||
SKEL_LOG_CRITICAL = 2,
|
||||
SKEL_LOG_ERROR = 3,
|
||||
SKEL_LOG_WARN = 4,
|
||||
SKEL_LOG_NOTICE = 5,
|
||||
SKEL_LOG_INFO = 6,
|
||||
SKEL_LOG_DEBUG = 7,
|
||||
SKEL_LOG_MAX
|
||||
} SKEL_LOG_LEVEL_E;
|
||||
|
||||
static SKEL_LOG_LEVEL_E log_level = SKEL_LOG_DEBUG;
|
||||
|
||||
#if 1
|
||||
#define MACRO_BLACK "\033[1;30;30m"
|
||||
#define MACRO_RED "\033[1;30;31m"
|
||||
#define MACRO_GREEN "\033[1;30;32m"
|
||||
#define MACRO_YELLOW "\033[1;30;33m"
|
||||
#define MACRO_BLUE "\033[1;30;34m"
|
||||
#define MACRO_PURPLE "\033[1;30;35m"
|
||||
#define MACRO_WHITE "\033[1;30;37m"
|
||||
#define MACRO_END "\033[0m"
|
||||
#else
|
||||
#define MACRO_BLACK
|
||||
#define MACRO_RED
|
||||
#define MACRO_GREEN
|
||||
#define MACRO_YELLOW
|
||||
#define MACRO_BLUE
|
||||
#define MACRO_PURPLE
|
||||
#define MACRO_WHITE
|
||||
#define MACRO_END
|
||||
#endif
|
||||
|
||||
#define ALOGE(fmt, ...) printf(MACRO_RED "[E][%32s][%4d]: " fmt MACRO_END "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define ALOGW(fmt, ...) \
|
||||
if (log_level >= SKEL_LOG_WARN) \
|
||||
printf(MACRO_YELLOW "[W][%32s][%4d]: " fmt MACRO_END "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define ALOGI(fmt, ...) \
|
||||
if (log_level >= SKEL_LOG_INFO) \
|
||||
printf(MACRO_GREEN "[I][%32s][%4d]: " fmt MACRO_END "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define ALOGD(fmt, ...) \
|
||||
if (log_level >= SKEL_LOG_DEBUG) \
|
||||
printf(MACRO_WHITE "[D][%32s][%4d]: " fmt MACRO_END "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define ALOGN(fmt, ...) \
|
||||
if (log_level >= SKEL_LOG_NOTICE) \
|
||||
printf(MACRO_PURPLE "[N][%32s][%4d]: " fmt MACRO_END "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SKEL_LOGGER_H
|
||||
Reference in New Issue
Block a user