1157 lines
60 KiB
C
1157 lines
60 KiB
C
/*
|
|
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
|
*/
|
|
|
|
#include "sample_common_nnie.h"
|
|
|
|
#include <limits.h>
|
|
#include "sample_common_svp.h"
|
|
#include "sample_comm.h"
|
|
#include "ss_mpi_nnie.h"
|
|
|
|
#define SAMPLE_SVP_NNIE_QUERY_SLEEP_TIME 100
|
|
#define SAMPLE_SVP_NNIE_RECT_THICK 2
|
|
|
|
static td_s32 sample_svp_nnie_align_byte(td_u32 num, td_u32 byte, td_u32 *stride)
|
|
{
|
|
sample_svp_check_exps_return(stride == TD_NULL, OT_ERR_SVP_NNIE_NULL_PTR, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, stride can't be TD_NULL!\n");
|
|
sample_svp_check_exps_return(byte == 0, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, byte can't be zero!\n");
|
|
sample_svp_check_exps_return(num == 0, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, num can't be zero!\n");
|
|
*stride = (num + byte - 1) / byte * byte;
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_fill_blob_info(sample_svp_nnie_cfg *cfg, sample_svp_nnie_param *param, td_s32 align_byte)
|
|
{
|
|
td_u32 i, j, num, byte_num, length;
|
|
td_s32 ret;
|
|
|
|
for (i = 0; i < param->model->net_seg_num; i++) {
|
|
/* fill src blob info */
|
|
for (j = 0; j < param->model->seg[i].src_num; j++) {
|
|
param->seg_data[i].src[j].type = param->model->seg[i].src_node[j].type;
|
|
param->seg_data[i].src[j].num = cfg->max_input_num;
|
|
/* Recurrent blob */
|
|
if (param->model->seg[i].src_node[j].type == OT_SVP_BLOB_TYPE_SEQ_S20Q12) {
|
|
param->seg_data[i].src[j].shape.seq.dim = param->model->seg[i].src_node[j].shape.dim;
|
|
param->seg_data[i].src[j].shape.seq.virt_addr_step =
|
|
cfg->step_virt_addr[i * SAMPLE_SVP_NNIE_EACH_SEG_STEP_ADDR_NUM];
|
|
length = param->seg_data[i].src[j].shape.seq.dim;
|
|
} else {
|
|
param->seg_data[i].src[j].shape.whc.chn = param->model->seg[i].src_node[j].shape.whc.chn;
|
|
param->seg_data[i].src[j].shape.whc.height = param->model->seg[i].src_node[j].shape.whc.height;
|
|
param->seg_data[i].src[j].shape.whc.width = param->model->seg[i].src_node[j].shape.whc.width;
|
|
length = param->seg_data[i].src[j].shape.whc.width;
|
|
}
|
|
ret = sample_common_svp_get_blob_data_byte_num(param->seg_data[i].src[j].type, &byte_num);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, get blob data byte num failed!\n");
|
|
ret = sample_svp_nnie_align_byte(byte_num * length, align_byte, &(param->seg_data[i].src[j].stride));
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, align failed!\n");
|
|
}
|
|
|
|
/* fill dst blob info */
|
|
num = (param->model->seg[i].net_type == OT_SVP_NNIE_NET_TYPE_ROI) ?
|
|
(cfg->max_roi_num * cfg->max_input_num) : cfg->max_input_num;
|
|
|
|
for (j = 0; j < param->model->seg[i].dst_num; j++) {
|
|
param->seg_data[i].dst[j].type = param->model->seg[i].dst_node[j].type;
|
|
param->seg_data[i].dst[j].num = num;
|
|
if (param->model->seg[i].dst_node[j].type == OT_SVP_BLOB_TYPE_SEQ_S20Q12) {
|
|
param->seg_data[i].dst[j].shape.seq.dim = param->model->seg[i].dst_node[j].shape.dim;
|
|
param->seg_data[i].dst[j].shape.seq.virt_addr_step =
|
|
cfg->step_virt_addr[i * SAMPLE_SVP_NNIE_EACH_SEG_STEP_ADDR_NUM + 1];
|
|
length = param->seg_data[i].dst[j].shape.seq.dim;
|
|
} else {
|
|
param->seg_data[i].dst[j].shape.whc.chn = param->model->seg[i].dst_node[j].shape.whc.chn;
|
|
param->seg_data[i].dst[j].shape.whc.height = param->model->seg[i].dst_node[j].shape.whc.height;
|
|
param->seg_data[i].dst[j].shape.whc.width = param->model->seg[i].dst_node[j].shape.whc.width;
|
|
length = param->seg_data[i].dst[j].shape.whc.width;
|
|
}
|
|
ret = sample_common_svp_get_blob_data_byte_num(param->seg_data[i].dst[j].type, &byte_num);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, get blob data byte num failed !\n");
|
|
ret = sample_svp_nnie_align_byte(byte_num * length, align_byte, &(param->seg_data[i].dst[j].stride));
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, align failed!\n");
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_fill_blob_addr(sample_svp_nnie_blob_size blob_size[], td_u32 blob_size_num,
|
|
td_u64 phys_addr, td_u64 virt_addr, sample_svp_nnie_param *param)
|
|
{
|
|
td_u32 i, j;
|
|
|
|
sample_svp_check_exps_return((param->model->net_seg_num == 0) || (param->model->net_seg_num > blob_size_num),
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, net_seg_num(%u) should be (0, %u]!\n",
|
|
param->model->net_seg_num, blob_size_num);
|
|
for (i = 0; i < param->model->net_seg_num; i++) {
|
|
/*
|
|
* first seg has src blobs, other seg's src blobs from the output blobs of
|
|
* those segs before it or from software output results
|
|
*/
|
|
if (i == 0) {
|
|
for (j = 0; j < param->model->seg[i].src_num; j++) {
|
|
param->seg_data[i].src[j].phys_addr = phys_addr;
|
|
param->seg_data[i].src[j].virt_addr = virt_addr;
|
|
phys_addr += blob_size[i].src_size[j];
|
|
virt_addr += blob_size[i].src_size[j];
|
|
}
|
|
}
|
|
|
|
/* fill the mem addrs of each seg's output blobs */
|
|
for (j = 0; j < param->model->seg[i].dst_num; j++) {
|
|
param->seg_data[i].dst[j].phys_addr = phys_addr;
|
|
param->seg_data[i].dst[j].virt_addr = virt_addr;
|
|
phys_addr += blob_size[i].dst_size[j];
|
|
virt_addr += blob_size[i].dst_size[j];
|
|
}
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_fill_forward_ctrl_info(sample_svp_nnie_cfg *cfg, sample_svp_nnie_param *param)
|
|
{
|
|
td_u32 i;
|
|
td_s32 ret;
|
|
|
|
for (i = 0; i < param->model->net_seg_num; i++) {
|
|
/* fill forwardCtrl info */
|
|
param->forward_ctrl[i].nnie_id = cfg->nnie_core_id[i];
|
|
param->forward_ctrl[i].src_num = param->model->seg[i].src_num;
|
|
param->forward_ctrl[i].dst_num = param->model->seg[i].dst_num;
|
|
param->forward_ctrl[i].net_seg_id = i;
|
|
|
|
if (param->model->seg[i].proposal_flag != 0) {
|
|
sample_svp_check_exps_return(cfg->threshold_num[i] == 0 ||
|
|
cfg->threshold_num[i] > OT_SVP_NNIE_MAX_THRESHOLD_NUM, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, %u-th threshold_num should be [1, %u]!\n",
|
|
i, OT_SVP_NNIE_MAX_THRESHOLD_NUM);
|
|
ret = memcpy_s(param->forward_ctrl[i].threshold, sizeof(ot_svp_nnie_threshold) * cfg->threshold_num[i],
|
|
cfg->threshold, sizeof(ot_svp_nnie_threshold) * cfg->threshold_num[i]);
|
|
sample_svp_check_exps_return(ret != EOK, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "memcpy_s failed!\n");
|
|
param->forward_ctrl[i].threshold_num = cfg->threshold_num[i];
|
|
}
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_void sample_svp_nnie_fill_forward_ctrl_addr(sample_svp_nnie_param *param)
|
|
{
|
|
td_u32 i;
|
|
td_u32 offset = 0;
|
|
|
|
/* fill forward ctrl addr */
|
|
for (i = 0; i < param->model->net_seg_num; i++) {
|
|
param->forward_ctrl[i].tmp_buf = param->tmp_buf;
|
|
param->forward_ctrl[i].task_buf.phys_addr = param->task_buf.phys_addr + offset;
|
|
param->forward_ctrl[i].task_buf.virt_addr = param->task_buf.virt_addr + offset;
|
|
param->forward_ctrl[i].task_buf.size = param->tsk_buf_info[i].task_buf_size;
|
|
|
|
offset += param->tsk_buf_info[i].task_buf_size;
|
|
}
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_get_blob_mem_size(ot_svp_blob blob[], td_u32 blob_num,
|
|
td_u32 total_step, td_u64 *total_size, td_u32 blob_size[])
|
|
{
|
|
td_u32 i;
|
|
td_u64 size;
|
|
|
|
for (i = 0; i < blob_num; i++) {
|
|
if (blob[i].type == OT_SVP_BLOB_TYPE_BSI_SQ32) {
|
|
size = sample_svp_nnie_align_32(blob[i].shape.whc.chn * sizeof(td_u32));
|
|
size += (td_u64)blob[i].num * blob[i].stride * blob[i].shape.whc.height * blob[i].shape.whc.chn;
|
|
} else if (blob[i].type == OT_SVP_BLOB_TYPE_SEQ_S20Q12) {
|
|
size = (td_u64)total_step * blob[i].stride;
|
|
} else {
|
|
size = (td_u64)blob[i].num * blob[i].stride * blob[i].shape.whc.height * blob[i].shape.whc.chn;
|
|
}
|
|
sample_svp_check_exps_return(((size == 0) || (size > SAMPLE_SVP_NNIE_MAX_U32)), OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, %u-th blob size(%llu) is greater than %u!\n",
|
|
i, size, SAMPLE_SVP_NNIE_MAX_U32);
|
|
blob_size[i] = (td_u32)size;
|
|
*total_size += size;
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_get_tmp_buf_and_blob_mem_size(sample_svp_nnie_param *param,
|
|
sample_svp_nnie_blob_size blob_size[], td_u32 blob_size_num, td_u64 *total_size)
|
|
{
|
|
td_u32 i, j, total_step, step;
|
|
td_s32 ret;
|
|
|
|
sample_svp_check_exps_return((param->model->net_seg_num == 0) || (param->model->net_seg_num > blob_size_num),
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, net_seg_num(%u) should be (0, %u]!\n",
|
|
param->model->net_seg_num, blob_size_num);
|
|
/* Get tmp buf size */
|
|
param->tmp_buf_size = param->model->tmp_buf_size;
|
|
*total_size += param->tmp_buf_size;
|
|
|
|
/* calculate Blob mem size */
|
|
for (i = 0; i < param->model->net_seg_num; i++) {
|
|
total_step = 0;
|
|
if (param->model->seg[i].net_type == OT_SVP_NNIE_NET_TYPE_RECURRENT) {
|
|
sample_svp_check_exps_return(param->seg_data[i].src[0].shape.seq.virt_addr_step == 0,
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, virt_addr_step can't be 0!\n");
|
|
for (j = 0; j < param->seg_data[i].src[0].num; j++) {
|
|
step = *(sample_svp_convert_addr_to_ptr(td_u32,
|
|
param->seg_data[i].src[0].shape.seq.virt_addr_step) + j);
|
|
sample_svp_check_exps_return(step > SAMPLE_SVP_NNIE_MAX_STEP, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, %u-th seg's %u-th step(%u) is greater than %u!\n",
|
|
i, j, step, SAMPLE_SVP_NNIE_MAX_STEP);
|
|
total_step += step;
|
|
}
|
|
}
|
|
/*
|
|
* the first seg's Src Blob mem size, other seg's src blobs from the output blobs of
|
|
* those segs before it or from software output results
|
|
*/
|
|
if (i == 0) {
|
|
ret = sample_svp_nnie_get_blob_mem_size(param->seg_data[i].src, param->model->seg[i].src_num,
|
|
total_step, total_size, blob_size[i].src_size);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, sample_svp_nnie_get_blob_mem_size failed!\n");
|
|
}
|
|
|
|
/* Get each seg's Dst Blob mem size */
|
|
ret = sample_svp_nnie_get_blob_mem_size(param->seg_data[i].dst, param->model->seg[i].dst_num,
|
|
total_step, total_size, blob_size[i].dst_size);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, sample_svp_nnie_get_blob_mem_size failed!\n");
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_param_init(sample_svp_nnie_cfg *cfg, sample_svp_nnie_param *param)
|
|
{
|
|
td_u64 total_size = 0;
|
|
td_u64 total_task_buf_size = 0;
|
|
td_s32 ret;
|
|
td_u32 i;
|
|
td_phys_addr_t phys_addr;
|
|
td_u64 virt_addr;
|
|
td_void *virt_ptr = TD_NULL;
|
|
sample_svp_nnie_blob_size blob_size[OT_SVP_NNIE_MAX_NET_SEG_NUM];
|
|
|
|
/* check param->model and get each seg's task buf size */
|
|
ret = ss_mpi_svp_nnie_get_task_buf_size(cfg->max_input_num, cfg->max_roi_num,
|
|
param->model, param->tsk_buf_info, param->model->net_seg_num);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, ss_mpi_svp_nnie_get_task_buf_size failed!\n");
|
|
|
|
/* Get total task buf size */
|
|
for (i = 0; i < param->model->net_seg_num; i++) {
|
|
total_task_buf_size += param->tsk_buf_info[i].task_buf_size;
|
|
}
|
|
sample_svp_check_exps_return(total_task_buf_size > SAMPLE_SVP_NNIE_MAX_U32, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, total_task_buf_size(%llu) is greater than %u!\n",
|
|
total_task_buf_size, SAMPLE_SVP_NNIE_MAX_U32);
|
|
total_size += total_task_buf_size;
|
|
|
|
/* fill forward info */
|
|
ret = sample_svp_nnie_fill_forward_ctrl_info(cfg, param);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, fill ctrl failed!\n");
|
|
|
|
ret = sample_svp_nnie_fill_blob_info(cfg, param, SAMPLE_SVP_NNIE_ALIGN_16);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, fill blob failed!\n");
|
|
|
|
/* Get tmp_buf and Blob mem size */
|
|
ret = sample_svp_nnie_get_tmp_buf_and_blob_mem_size(param, blob_size, OT_SVP_NNIE_MAX_NET_SEG_NUM, &total_size);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, sample_svp_nnie_get_task_and_blob_mem_size failed!\n");
|
|
|
|
/* Malloc mem */
|
|
ret = sample_common_svp_malloc_cached("sample_nnie_task", TD_NULL, &phys_addr, &virt_ptr, total_size);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,Malloc memory failed!\n");
|
|
(td_void)memset_s(virt_ptr, total_size, 0, total_size);
|
|
virt_addr = sample_svp_convert_ptr_to_addr(td_u64, virt_ptr);
|
|
ret = sample_common_svp_flush_cache(phys_addr, virt_ptr, total_size);
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, fail, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, flush cache failed!\n");
|
|
|
|
/* fill taskinfo mem addr */
|
|
param->task_buf.size = total_task_buf_size;
|
|
param->task_buf.phys_addr = (td_u64)phys_addr;
|
|
param->task_buf.virt_addr = virt_addr;
|
|
|
|
/* fill Tmp mem addr */
|
|
param->tmp_buf.size = param->tmp_buf_size;
|
|
param->tmp_buf.phys_addr = (td_u64)phys_addr + total_task_buf_size;
|
|
param->tmp_buf.virt_addr = virt_addr + total_task_buf_size;
|
|
|
|
/* fill forward ctrl addr */
|
|
(td_void)sample_svp_nnie_fill_forward_ctrl_addr(param);
|
|
|
|
/* fill each blob's mem addr */
|
|
phys_addr = phys_addr + total_task_buf_size + param->tmp_buf_size;
|
|
virt_addr = virt_addr + total_task_buf_size + param->tmp_buf_size;
|
|
ret = sample_svp_nnie_fill_blob_addr(blob_size, OT_SVP_NNIE_MAX_NET_SEG_NUM, (td_u64)phys_addr, virt_addr, param);
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, fail, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, fill blob addr failed!\n");
|
|
return TD_SUCCESS;
|
|
fail:
|
|
sample_svp_mmz_free(phys_addr, virt_addr);
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_flush_dst_blob(sample_svp_nnie_forward_info *forward_info,
|
|
sample_svp_nnie_param *nnie_param)
|
|
{
|
|
td_u32 i, j;
|
|
td_u32 total_step_num = 0;
|
|
td_u32 size, num;
|
|
td_s32 ret;
|
|
td_u32 seg_idx = forward_info->proc_seg_idx;
|
|
|
|
sample_svp_check_exps_return(seg_idx >= OT_SVP_NNIE_MAX_NET_SEG_NUM, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, seg_idx(%u) must be less than %u!\n", seg_idx, OT_SVP_NNIE_MAX_NET_SEG_NUM);
|
|
num = nnie_param->forward_ctrl[seg_idx].dst_num;
|
|
sample_svp_check_exps_return(num > OT_SVP_NNIE_MAX_OUT_NUM, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, dst_num(%u) must be less than %u!\n", num, OT_SVP_NNIE_MAX_OUT_NUM);
|
|
for (i = 0; i < nnie_param->forward_ctrl[seg_idx].dst_num; i++) {
|
|
if (nnie_param->seg_data[seg_idx].dst[i].type == OT_SVP_BLOB_TYPE_SEQ_S20Q12) {
|
|
sample_svp_check_exps_return(nnie_param->seg_data[seg_idx].dst[i].shape.seq.virt_addr_step == 0,
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, %d-th virt_addr_step is 0!\n", i);
|
|
for (j = 0; j < nnie_param->seg_data[seg_idx].dst[i].num; j++) {
|
|
total_step_num += *(sample_svp_convert_addr_to_ptr(td_u32,
|
|
nnie_param->seg_data[seg_idx].dst[i].shape.seq.virt_addr_step) + j);
|
|
}
|
|
ret = sample_common_svp_flush_cache(nnie_param->seg_data[seg_idx].dst[i].phys_addr,
|
|
sample_svp_convert_addr_to_ptr(td_void, nnie_param->seg_data[seg_idx].dst[i].virt_addr),
|
|
total_step_num * nnie_param->seg_data[seg_idx].dst[i].stride);
|
|
} else if (nnie_param->seg_data[seg_idx].dst[i].type == OT_SVP_BLOB_TYPE_BSI_SQ32) {
|
|
size = sample_svp_nnie_align_32(nnie_param->seg_data[seg_idx].dst[i].shape.whc.chn * sizeof(td_u32));
|
|
ret = sample_common_svp_flush_cache(nnie_param->seg_data[seg_idx].dst[i].phys_addr,
|
|
sample_svp_convert_addr_to_ptr(td_void, nnie_param->seg_data[seg_idx].dst[i].virt_addr),
|
|
nnie_param->seg_data[seg_idx].dst[i].num *
|
|
nnie_param->seg_data[seg_idx].dst[i].shape.whc.chn *
|
|
nnie_param->seg_data[seg_idx].dst[i].shape.whc.height *
|
|
nnie_param->seg_data[seg_idx].dst[i].stride + size);
|
|
} else {
|
|
ret = sample_common_svp_flush_cache(nnie_param->seg_data[seg_idx].dst[i].phys_addr,
|
|
sample_svp_convert_addr_to_ptr(td_void, nnie_param->seg_data[seg_idx].dst[i].virt_addr),
|
|
nnie_param->seg_data[seg_idx].dst[i].num *
|
|
nnie_param->seg_data[seg_idx].dst[i].shape.whc.chn *
|
|
nnie_param->seg_data[seg_idx].dst[i].shape.whc.height *
|
|
nnie_param->seg_data[seg_idx].dst[i].stride);
|
|
}
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, flush %u-th seg's %u-th dst blob failed!\n", seg_idx, i);
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_set_input_blob(sample_svp_nnie_forward_info *forward_info,
|
|
ot_svp_src_blob bbox[], td_u32 bbox_num, sample_svp_nnie_param *nnie_param)
|
|
{
|
|
td_u32 i, j;
|
|
td_u32 num;
|
|
td_s32 ret;
|
|
sample_svp_check_exps_return(forward_info->prev_seg_idx > forward_info->proc_seg_idx,
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, prev_seg_idx %u is greater than proc_seg_idx %u!\n",
|
|
forward_info->prev_seg_idx, forward_info->proc_seg_idx);
|
|
|
|
sample_svp_check_exps_return(forward_info->proc_seg_idx >= OT_SVP_NNIE_MAX_NET_SEG_NUM,
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, proc_seg_idx %u must be less than %u!\n", forward_info->proc_seg_idx, OT_SVP_NNIE_MAX_NET_SEG_NUM);
|
|
|
|
num = nnie_param->model->seg[forward_info->prev_seg_idx].dst_num;
|
|
sample_svp_check_exps_return(num > OT_SVP_NNIE_MAX_OUT_NUM, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, dst_num(%u) must be less than %u!\n", num, OT_SVP_NNIE_MAX_OUT_NUM);
|
|
|
|
num = (forward_info->proc_seg_idx != 0) ? nnie_param->model->seg[forward_info->proc_seg_idx].src_num : 0;
|
|
sample_svp_check_exps_return(num > OT_SVP_NNIE_MAX_IN_NUM, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, src_num(%u) must be less than %u!\n", num, OT_SVP_NNIE_MAX_IN_NUM);
|
|
/* set input blob according to node name */
|
|
for (i = 0; i < num; i++) {
|
|
for (j = 0; j < nnie_param->model->seg[forward_info->prev_seg_idx].dst_num; j++) {
|
|
if (strncmp(nnie_param->model->seg[forward_info->prev_seg_idx].dst_node[j].name,
|
|
nnie_param->model->seg[forward_info->proc_seg_idx].src_node[i].name, OT_SVP_NNIE_NODE_NAME_LEN) == 0) {
|
|
nnie_param->seg_data[forward_info->proc_seg_idx].src[i] =
|
|
nnie_param->seg_data[forward_info->prev_seg_idx].dst[j];
|
|
break;
|
|
}
|
|
}
|
|
sample_svp_check_exps_return(j == nnie_param->model->seg[forward_info->prev_seg_idx].dst_num,
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,can't find %u-th seg's %u-th src blob!\n",
|
|
forward_info->proc_seg_idx, i);
|
|
}
|
|
if (nnie_param->model->seg[forward_info->proc_seg_idx].net_type == OT_SVP_NNIE_NET_TYPE_ROI) {
|
|
sample_svp_check_exps_return(bbox == TD_NULL, OT_ERR_SVP_NNIE_NULL_PTR, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, bbox %p can't be TD_NULL!\n", bbox);
|
|
sample_svp_check_exps_return(bbox_num != 1, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, bbox_num %u should be 1!\n", bbox_num);
|
|
num = nnie_param->model->seg[forward_info->proc_seg_idx].src_num;
|
|
sample_svp_check_exps_return(num > OT_SVP_NNIE_MAX_IN_NUM - 1, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, src_num(%u) must be less than %u!\n", num, OT_SVP_NNIE_MAX_IN_NUM - 1);
|
|
ret = memcpy_s(&nnie_param->seg_data[forward_info->proc_seg_idx].src[num], sizeof(ot_svp_blob) * bbox_num,
|
|
bbox, sizeof(ot_svp_blob) * bbox_num);
|
|
sample_svp_check_exps_return(ret != EOK, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "memcpy_s failed!\n");
|
|
nnie_param->forward_ctrl[forward_info->proc_seg_idx].src_num =
|
|
nnie_param->model->seg[forward_info->proc_seg_idx].src_num + bbox_num;
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_fill_src_image(FILE *fp, td_u32 seg_idx, td_u32 src_blob_idx,
|
|
sample_svp_nnie_param *nnie_param)
|
|
{
|
|
td_u32 height = nnie_param->seg_data[seg_idx].src[src_blob_idx].shape.whc.height;
|
|
td_u32 width = nnie_param->seg_data[seg_idx].src[src_blob_idx].shape.whc.width;
|
|
td_u32 chn = nnie_param->seg_data[seg_idx].src[src_blob_idx].shape.whc.chn;
|
|
td_u32 stride = nnie_param->seg_data[seg_idx].src[src_blob_idx].stride;
|
|
td_u8 *pic_addr = sample_svp_convert_addr_to_ptr(td_u8, nnie_param->seg_data[seg_idx].src[src_blob_idx].virt_addr);
|
|
td_u32 i, n;
|
|
td_s32 ret;
|
|
td_u32 line_num;
|
|
|
|
switch (nnie_param->seg_data[seg_idx].src[src_blob_idx].type) {
|
|
case OT_SVP_BLOB_TYPE_U8:
|
|
line_num = chn * height;
|
|
break;
|
|
case OT_SVP_BLOB_TYPE_YVU420SP:
|
|
line_num = chn * height / SAMPLE_SVP_NNIE_DOUBLE;
|
|
break;
|
|
case OT_SVP_BLOB_TYPE_YVU422SP:
|
|
line_num = height * SAMPLE_SVP_NNIE_DOUBLE;
|
|
break;
|
|
default:
|
|
sample_svp_check_exps_return(1, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob type should be [%d, %d]!\n", OT_SVP_BLOB_TYPE_U8, OT_SVP_BLOB_TYPE_YVU422SP);
|
|
break;
|
|
}
|
|
for (n = 0; n < nnie_param->seg_data[seg_idx].src[src_blob_idx].num; n++) {
|
|
for (i = 0; i < line_num; i++) {
|
|
ret = fread(pic_addr, width, 1, fp);
|
|
sample_svp_check_exps_return(ret != 1, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,read image file failed!\n");
|
|
pic_addr += stride;
|
|
}
|
|
}
|
|
ret = sample_common_svp_flush_cache(nnie_param->seg_data[seg_idx].src[src_blob_idx].phys_addr,
|
|
sample_svp_convert_addr_to_ptr(td_void, nnie_param->seg_data[seg_idx].src[src_blob_idx].virt_addr),
|
|
nnie_param->seg_data[seg_idx].src[src_blob_idx].num * chn * height * stride);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_common_svp_flush_cache failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_fill_src_tensor_vector(FILE *fp, td_u32 seg_idx, td_u32 src_blob_idx,
|
|
sample_svp_nnie_param *nnie_param)
|
|
{
|
|
td_u32 height = nnie_param->seg_data[seg_idx].src[src_blob_idx].shape.whc.height;
|
|
td_u32 width = nnie_param->seg_data[seg_idx].src[src_blob_idx].shape.whc.width;
|
|
td_u32 chn = nnie_param->seg_data[seg_idx].src[src_blob_idx].shape.whc.chn;
|
|
td_u32 stride = nnie_param->seg_data[seg_idx].src[src_blob_idx].stride;
|
|
td_u8 *pic_addr = sample_svp_convert_addr_to_ptr(td_u8, nnie_param->seg_data[seg_idx].src[src_blob_idx].virt_addr);
|
|
td_u32 i, n;
|
|
td_s32 ret;
|
|
td_u32 line_num = chn * height;
|
|
|
|
for (n = 0; n < nnie_param->seg_data[seg_idx].src[src_blob_idx].num; n++) {
|
|
for (i = 0; i < line_num; i++) {
|
|
ret = fread(pic_addr, width * sizeof(td_u32), 1, fp);
|
|
sample_svp_check_exps_return(ret != 1, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,read image file failed!\n");
|
|
pic_addr += stride;
|
|
}
|
|
}
|
|
ret = sample_common_svp_flush_cache(nnie_param->seg_data[seg_idx].src[src_blob_idx].phys_addr,
|
|
sample_svp_convert_addr_to_ptr(td_void, nnie_param->seg_data[seg_idx].src[src_blob_idx].virt_addr),
|
|
nnie_param->seg_data[seg_idx].src[src_blob_idx].num * chn * height * stride);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_common_svp_flush_cache failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_fill_src_seq(FILE *fp, td_u32 seg_idx, td_u32 src_blob_idx,
|
|
sample_svp_nnie_param *nnie_param)
|
|
{
|
|
td_u32 i, n;
|
|
td_u32 dim = nnie_param->seg_data[seg_idx].src[src_blob_idx].shape.seq.dim;
|
|
td_u32 stride = nnie_param->seg_data[seg_idx].src[src_blob_idx].stride;
|
|
td_u32 *step_addr = sample_svp_convert_addr_to_ptr(td_u32,
|
|
nnie_param->seg_data[seg_idx].src[src_blob_idx].shape.seq.virt_addr_step);
|
|
td_u8 *pic_addr = sample_svp_convert_addr_to_ptr(td_u8, nnie_param->seg_data[seg_idx].src[src_blob_idx].virt_addr);
|
|
td_u32 total_step_num = 0;
|
|
td_s32 ret;
|
|
|
|
for (n = 0; n < nnie_param->seg_data[seg_idx].src[src_blob_idx].num; n++) {
|
|
for (i = 0; i < *(step_addr + n); i++) {
|
|
ret = fread(pic_addr, dim * sizeof(td_u32), 1, fp);
|
|
sample_svp_check_exps_return(ret != 1, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,read image file failed!\n");
|
|
pic_addr += stride;
|
|
}
|
|
total_step_num += *(step_addr + n);
|
|
}
|
|
ret = sample_common_svp_flush_cache(nnie_param->seg_data[seg_idx].src[src_blob_idx].phys_addr,
|
|
sample_svp_convert_addr_to_ptr(td_void, nnie_param->seg_data[seg_idx].src[src_blob_idx].virt_addr),
|
|
total_step_num * stride);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_common_svp_flush_cache failed!\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_print_report_blob(sample_svp_nnie_param *nnie_param,
|
|
td_u32 seg_idx, td_u32 node_idx, FILE *fp)
|
|
{
|
|
td_u32 i, j, n, stride, line_num, line_byte;
|
|
td_u32 *step_addr = TD_NULL;
|
|
td_s32 *result_addr = sample_svp_convert_addr_to_ptr(td_s32, nnie_param->seg_data[seg_idx].dst[node_idx].virt_addr);
|
|
td_s32 *num_addr = TD_NULL;
|
|
td_s32 ret;
|
|
|
|
if (nnie_param->seg_data[seg_idx].dst[node_idx].type == OT_SVP_BLOB_TYPE_SEQ_S20Q12) {
|
|
step_addr = sample_svp_convert_addr_to_ptr(td_u32,
|
|
nnie_param->seg_data[seg_idx].dst[node_idx].shape.seq.virt_addr_step);
|
|
line_num = *step_addr;
|
|
line_byte = nnie_param->seg_data[seg_idx].dst[node_idx].shape.seq.dim;
|
|
stride = nnie_param->seg_data[seg_idx].dst[node_idx].stride;
|
|
} else {
|
|
line_num = nnie_param->seg_data[seg_idx].dst[node_idx].shape.whc.chn *
|
|
nnie_param->seg_data[seg_idx].dst[node_idx].shape.whc.height;
|
|
line_byte = nnie_param->seg_data[seg_idx].dst[node_idx].shape.whc.width;
|
|
stride = nnie_param->seg_data[seg_idx].dst[node_idx].stride;
|
|
}
|
|
if (nnie_param->seg_data[seg_idx].dst[node_idx].type == OT_SVP_BLOB_TYPE_BSI_SQ32) {
|
|
num_addr = result_addr;
|
|
for (i = 0; i < nnie_param->seg_data[seg_idx].dst[node_idx].shape.whc.chn; i++) {
|
|
ret = fprintf(fp, "%08x\n", *(result_addr + i));
|
|
sample_svp_check_exps_return(ret < 0, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,write report result file failed!\n");
|
|
}
|
|
result_addr += sample_svp_nnie_align_32(nnie_param->seg_data[seg_idx].dst[node_idx].shape.whc.chn *
|
|
sizeof(td_u32)) / sizeof(td_u32);
|
|
}
|
|
for (n = 0; n < nnie_param->seg_data[seg_idx].dst[node_idx].num; n++) {
|
|
line_num = (nnie_param->seg_data[seg_idx].dst[node_idx].type == OT_SVP_BLOB_TYPE_SEQ_S20Q12) ?
|
|
(*(step_addr + n)) : line_num;
|
|
for (i = 0; i < line_num; i++) {
|
|
line_byte = (num_addr == TD_NULL) ? line_byte :
|
|
(td_u32)(*(num_addr + i / nnie_param->seg_data[seg_idx].dst[node_idx].shape.whc.height));
|
|
for (j = 0; j < line_byte; j++) {
|
|
ret = fprintf(fp, "%08x\n", *(result_addr + j));
|
|
sample_svp_check_exps_return(ret < 0, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,write report result file failed!\n");
|
|
}
|
|
result_addr += stride / sizeof(td_u32);
|
|
}
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_void sample_svp_nnie_print_hw_detect_each_class_result(sample_svp_nnie_hw_detect_out_result *result,
|
|
td_u32 offset, td_u32 class_id, td_u32 roi_num, td_float print_result_thresh)
|
|
{
|
|
td_u32 j;
|
|
td_float conf;
|
|
td_bool is_print = TD_FALSE;
|
|
for (j = 0; j < roi_num; j++) {
|
|
conf = (td_float)result->score[offset + j] / SAMPLE_SVP_NNIE_S12Q20_QUANT;
|
|
if (conf > print_result_thresh &&
|
|
(td_u32)(result->class_id[offset + j] / SAMPLE_SVP_NNIE_QUANT_BASE) == class_id) {
|
|
sample_svp_trace_info("==== the %u-th class box info ====\n", class_id);
|
|
is_print = TD_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (is_print == TD_TRUE) {
|
|
for (j = 0; j < roi_num; j++) {
|
|
conf = (td_float)result->score[offset + j] / SAMPLE_SVP_NNIE_S12Q20_QUANT;
|
|
if (conf < print_result_thresh) {
|
|
break;
|
|
}
|
|
if ((td_u32)(result->class_id[offset + j] / SAMPLE_SVP_NNIE_QUANT_BASE) == class_id) {
|
|
sample_svp_trace_info("%d %d %d %d %f\n",
|
|
result->x_min[offset + j] / SAMPLE_SVP_NNIE_QUANT_BASE,
|
|
result->y_min[offset + j] / SAMPLE_SVP_NNIE_QUANT_BASE,
|
|
result->x_max[offset + j] / SAMPLE_SVP_NNIE_QUANT_BASE,
|
|
result->y_max[offset + j] / SAMPLE_SVP_NNIE_QUANT_BASE,
|
|
conf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
td_s32 sample_common_svp_nnie_param_deinit(sample_svp_nnie_param *param)
|
|
{
|
|
sample_svp_check_exps_return(param == TD_NULL, OT_ERR_SVP_NNIE_NULL_PTR, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, param can't be TD_NULL!\n");
|
|
|
|
if ((param->task_buf.phys_addr != 0) && (param->task_buf.virt_addr != 0)) {
|
|
sample_svp_mmz_free(param->task_buf.phys_addr, param->task_buf.virt_addr);
|
|
param->task_buf.phys_addr = 0;
|
|
param->task_buf.virt_addr = 0;
|
|
}
|
|
|
|
if ((param->step_buf.phys_addr != 0) && (param->step_buf.virt_addr != 0)) {
|
|
sample_svp_mmz_free(param->step_buf.phys_addr, param->step_buf.virt_addr);
|
|
param->step_buf.phys_addr = 0;
|
|
param->step_buf.virt_addr = 0;
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 sample_common_svp_nnie_param_init(sample_svp_nnie_cfg *cfg, sample_svp_nnie_param *param)
|
|
{
|
|
td_s32 ret;
|
|
|
|
/* check */
|
|
sample_svp_check_exps_return((cfg == TD_NULL) || (param == TD_NULL), OT_ERR_SVP_NNIE_NULL_PTR,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,cfg and param can't be TD_NULL!\n");
|
|
sample_svp_check_exps_return(param->model == TD_NULL, OT_ERR_SVP_NNIE_NULL_PTR,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,param->model can't be TD_NULL!\n");
|
|
|
|
/* NNIE parameter initialization */
|
|
ret = sample_svp_nnie_param_init(cfg, param);
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, fail, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, sample_svp_nnie_param_init failed!\n");
|
|
|
|
return ret;
|
|
fail:
|
|
ret = sample_common_svp_nnie_param_deinit(param);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, sample_common_svp_nnie_param_deinit failed!\n");
|
|
return OT_ERR_SVP_NNIE_ILLEGAL_PARAM;
|
|
}
|
|
|
|
td_s32 sample_common_svp_nnie_unload_model(sample_svp_nnie_model *nnie_model)
|
|
{
|
|
sample_svp_check_exps_return(nnie_model == TD_NULL, OT_ERR_SVP_NNIE_NULL_PTR,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,nnie_model can't be TD_NULL!\n");
|
|
if ((nnie_model->model_buf.phys_addr != 0) && (nnie_model->model_buf.virt_addr != 0)) {
|
|
sample_svp_mmz_free(nnie_model->model_buf.phys_addr, nnie_model->model_buf.virt_addr);
|
|
nnie_model->model_buf.phys_addr = 0;
|
|
nnie_model->model_buf.virt_addr = 0;
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 sample_common_svp_nnie_load_model(const td_char *model_file, sample_svp_nnie_model *nnie_model)
|
|
{
|
|
td_s32 ret = OT_ERR_SVP_NNIE_ILLEGAL_PARAM;
|
|
td_phys_addr_t phys_addr;
|
|
td_u8 *virt_addr = TD_NULL;
|
|
td_slong file_size;
|
|
td_char path[PATH_MAX] = {0};
|
|
FILE *fp = TD_NULL;
|
|
|
|
sample_svp_check_exps_return(((model_file == TD_NULL) || (nnie_model == TD_NULL)), OT_ERR_SVP_NNIE_NULL_PTR,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, model_file or nnie_model is TD_NULL!\n");
|
|
|
|
sample_svp_check_exps_return((strlen(model_file) > PATH_MAX) ||
|
|
(realpath(model_file, path) == TD_NULL), ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, file_name is invalid!\n");
|
|
|
|
/* Get model file size */
|
|
fp = fopen(path, "rb");
|
|
sample_svp_check_exps_goto(fp == TD_NULL, fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, open model file failed!\n");
|
|
ret = fseek(fp, 0L, SEEK_END);
|
|
sample_svp_check_exps_goto(ret == -1, fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, fseek failed!\n");
|
|
file_size = ftell(fp);
|
|
sample_svp_check_exps_goto(file_size <= 0, fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, ftell failed!\n");
|
|
ret = fseek(fp, 0L, SEEK_SET);
|
|
sample_svp_check_exps_goto(ret == -1, fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, fseek failed!\n");
|
|
|
|
/* malloc model file mem */
|
|
ret = sample_common_svp_malloc_mem("sample_nnie_model", TD_NULL, &phys_addr, (void **)&virt_addr, file_size);
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error(%#x),Malloc memory failed!\n", ret);
|
|
|
|
nnie_model->model_buf.size = (td_u32)file_size;
|
|
nnie_model->model_buf.phys_addr = (td_u64)phys_addr;
|
|
nnie_model->model_buf.virt_addr = sample_svp_convert_ptr_to_addr(td_u64, virt_addr);
|
|
|
|
ret = fread(virt_addr, file_size, 1, fp);
|
|
sample_svp_check_exps_goto(ret != 1, fail_1, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,read model file failed!\n");
|
|
|
|
/* load model */
|
|
ret = ss_mpi_svp_nnie_load_model(&(nnie_model->model_buf), &(nnie_model->model));
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, fail_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,ss_mpi_svp_nnie_load_model failed!\n");
|
|
|
|
if (fp != TD_NULL) {
|
|
fclose(fp);
|
|
}
|
|
return TD_SUCCESS;
|
|
fail_1:
|
|
sample_svp_mmz_free(nnie_model->model_buf.phys_addr, nnie_model->model_buf.virt_addr);
|
|
nnie_model->model_buf.size = 0;
|
|
fail_0:
|
|
if (fp != TD_NULL) {
|
|
fclose(fp);
|
|
}
|
|
return OT_ERR_SVP_NNIE_ILLEGAL_PARAM;
|
|
}
|
|
|
|
/* function: NNIE forward */
|
|
td_s32 sample_common_svp_nnie_forward(sample_svp_nnie_forward_info *forward_info,
|
|
ot_svp_src_blob bbox[], td_u32 bbox_num, sample_svp_nnie_param *nnie_param)
|
|
{
|
|
td_s32 ret;
|
|
td_bool is_finish = TD_FALSE;
|
|
ot_svp_nnie_handle handle;
|
|
td_u32 seg_idx;
|
|
|
|
sample_svp_check_exps_return(((forward_info == TD_NULL) || (nnie_param == TD_NULL)),
|
|
OT_ERR_SVP_NNIE_NULL_PTR, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, some input params are TD_NULL!\n");
|
|
seg_idx = forward_info->proc_seg_idx;
|
|
sample_svp_check_exps_return(seg_idx >= OT_SVP_NNIE_MAX_NET_SEG_NUM, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, seg_idx(%u) must be less than %u!\n", seg_idx, OT_SVP_NNIE_MAX_NET_SEG_NUM);
|
|
|
|
ret = sample_common_svp_flush_cache(nnie_param->forward_ctrl[seg_idx].task_buf.phys_addr,
|
|
sample_svp_convert_addr_to_ptr(td_void, nnie_param->forward_ctrl[seg_idx].task_buf.virt_addr),
|
|
nnie_param->forward_ctrl[seg_idx].task_buf.size);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, sample_common_svp_flush_cache failed!\n");
|
|
|
|
ret = sample_svp_nnie_set_input_blob(forward_info, bbox, bbox_num, nnie_param);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, sample_svp_nnie_set_input_blob failed!\n");
|
|
|
|
/* nnie_forward */
|
|
ret = ss_mpi_svp_nnie_forward(&handle, nnie_param->seg_data[seg_idx].src,
|
|
nnie_param->model, nnie_param->seg_data[seg_idx].dst,
|
|
&nnie_param->forward_ctrl[seg_idx], forward_info->is_instant);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, ss_mpi_svp_nnie_forward failed!\n");
|
|
|
|
if (forward_info->is_instant) {
|
|
/* wait NNIE finish */
|
|
ret = ss_mpi_svp_nnie_query(nnie_param->forward_ctrl[seg_idx].nnie_id,
|
|
handle, &is_finish, TD_TRUE);
|
|
while (ret == OT_ERR_SVP_NNIE_QUERY_TIMEOUT) {
|
|
ret = ss_mpi_svp_nnie_query(nnie_param->forward_ctrl[seg_idx].nnie_id, handle, &is_finish, TD_TRUE);
|
|
usleep(SAMPLE_SVP_NNIE_QUERY_SLEEP_TIME);
|
|
sample_svp_trace_info("ss_mpi_svp_nnie_query query timeout!\n");
|
|
}
|
|
}
|
|
|
|
is_finish = TD_FALSE;
|
|
ret = sample_svp_nnie_flush_dst_blob(forward_info, nnie_param);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, sample_svp_nnie_flush_dst_blob failed!\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_check_hw_bsi_blob(ot_svp_blob *dst, td_u32 class_num)
|
|
{
|
|
td_s32 ret = OT_ERR_SVP_NNIE_ILLEGAL_PARAM;
|
|
td_u32 *roi_num = sample_svp_convert_addr_to_ptr(td_u32, dst->virt_addr);
|
|
td_u32 max_roi_num = 0;
|
|
td_u32 i;
|
|
|
|
sample_svp_check_exps_return(((class_num == 0) || (class_num > SAMPLE_SVP_NNIE_MAX_CLASS_NUM)), ret,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,class_num(%u) should be (0, %u]!\n",
|
|
class_num, SAMPLE_SVP_NNIE_MAX_CLASS_NUM);
|
|
|
|
sample_svp_check_exps_return(dst->type != OT_SVP_BLOB_TYPE_BSI_SQ32, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,dst->type(%d) must be %d!\n", dst->type,
|
|
OT_SVP_BLOB_TYPE_BSI_SQ32);
|
|
sample_svp_check_exps_return(dst->virt_addr == 0, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,dst->virt_addr(%llu) is 0!\n", dst->virt_addr);
|
|
sample_svp_check_exps_return(dst->num == 0, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,dst->num(%u) is 0!\n", dst->num);
|
|
sample_svp_check_exps_return(((dst->shape.whc.chn != 1) && (dst->shape.whc.chn != class_num)),
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,dst->shape.whc.chn(%u) must be 1 or %u!\n", dst->shape.whc.chn, class_num);
|
|
sample_svp_check_exps_return(dst->shape.whc.height != SAMPLE_SVP_NNIE_BSI_S20Q12_HEIGHT,
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,dst->shape.whc.height(%u) must be %u!\n",
|
|
dst->shape.whc.height, SAMPLE_SVP_NNIE_BSI_S20Q12_HEIGHT);
|
|
|
|
for (i = 0; i < dst->shape.whc.chn; i++) {
|
|
max_roi_num = (max_roi_num < *(roi_num + i)) ? (*(roi_num + i)) : max_roi_num;
|
|
}
|
|
sample_svp_check_exps_return(dst->shape.whc.width < max_roi_num, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,dst->shape.whc.width(%u) is less than %u!\n",
|
|
dst->shape.whc.width, max_roi_num);
|
|
sample_svp_check_exps_return(dst->stride < (td_u64)dst->shape.whc.width * sizeof(td_u32),
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,dst->stride(%u) is less than %u!\n",
|
|
dst->stride, (td_u32)(dst->shape.whc.width * sizeof(td_u32)));
|
|
sample_svp_check_exps_return(sample_svp_nnie_check_align_16(dst->stride) != 0,
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,dst->stride(%u) must be %u bytes align!\n", dst->stride, SAMPLE_SVP_NNIE_ALIGN_16);
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_check_hw_blob(ot_svp_blob *blob)
|
|
{
|
|
td_s32 ret = OT_ERR_SVP_NNIE_ILLEGAL_PARAM;
|
|
td_u32 byte_num = ((blob->type >= OT_SVP_BLOB_TYPE_U8) && (blob->type <= OT_SVP_BLOB_TYPE_YVU422SP)) ?
|
|
sizeof(td_u8) : sizeof(td_u32);
|
|
|
|
sample_svp_check_exps_return(blob->type > OT_SVP_BLOB_TYPE_VEC_S12Q20, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, blob->type(%d) is greater than %d!\n", blob->type, OT_SVP_BLOB_TYPE_VEC_S12Q20);
|
|
sample_svp_check_exps_return(blob->num == 0, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->num(%d) is 0!\n", blob->num);
|
|
sample_svp_check_exps_return(blob->virt_addr == 0, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->virt_addr is 0!\n");
|
|
if (blob->type == OT_SVP_BLOB_TYPE_SEQ_S20Q12) {
|
|
sample_svp_check_exps_return(blob->shape.seq.dim == 0, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.seq.dim(%u) is 0!\n", blob->shape.seq.dim);
|
|
sample_svp_check_exps_return((blob->stride < (td_u64)blob->shape.seq.dim * byte_num), ret,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,blob->stride(%u) is less than %llu!\n",
|
|
blob->stride, ((td_u64)blob->shape.seq.dim * byte_num));
|
|
sample_svp_check_exps_return(blob->shape.seq.virt_addr_step == 0, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.seq.virt_addr_step is 0!\n");
|
|
} else if (blob->type == OT_SVP_BLOB_TYPE_BSI_SQ32) {
|
|
ret = sample_svp_nnie_check_hw_bsi_blob(blob, blob->shape.whc.chn);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_svp_nnie_check_hw_bsi_blob failed!\n");
|
|
} else if ((blob->type == OT_SVP_BLOB_TYPE_VEC_S20Q12) || (blob->type == OT_SVP_BLOB_TYPE_VEC_S12Q20)) {
|
|
sample_svp_check_exps_return(blob->shape.whc.chn != 1, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.whc.chn(%u) should be 1!\n", blob->shape.whc.chn);
|
|
sample_svp_check_exps_return(blob->shape.whc.height != 1, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.whc.height(%u) should be 1!\n", blob->shape.whc.height);
|
|
sample_svp_check_exps_return(blob->shape.whc.width == 0, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.whc.width(%u) is 0!\n", blob->shape.whc.width);
|
|
sample_svp_check_exps_return((blob->stride < (td_u64)blob->shape.whc.width * byte_num), ret,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,blob->stride(%u) is less than %llu!\n",
|
|
blob->stride, ((td_u64)blob->shape.whc.width * byte_num));
|
|
} else {
|
|
sample_svp_check_exps_return(blob->shape.whc.chn == 0, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.whc.chn(%u) is 0!\n", blob->shape.whc.chn);
|
|
sample_svp_check_exps_return(blob->shape.whc.height == 0, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.whc.height(%u) is 0!\n", blob->shape.whc.height);
|
|
sample_svp_check_exps_return(blob->shape.whc.width == 0, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.whc.width(%u) is 0!\n", blob->shape.whc.width);
|
|
sample_svp_check_exps_return((blob->stride < (td_u64)blob->shape.whc.width * byte_num), ret,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,blob->stride(%u) is less than %llu!\n",
|
|
blob->stride, ((td_u64)blob->shape.whc.width * byte_num));
|
|
}
|
|
sample_svp_check_exps_return(sample_svp_nnie_check_align_16(blob->stride) != 0, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,blob->stride(%u) is not %u bytes align!\n",
|
|
blob->stride, SAMPLE_SVP_NNIE_ALIGN_16);
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
/* function: fill src data */
|
|
td_s32 sample_common_svp_nnie_fill_src_data(const char *file_name, td_u32 seg_idx, td_u32 src_blob_idx,
|
|
sample_svp_nnie_param *nnie_param)
|
|
{
|
|
FILE *fp = TD_NULL;
|
|
td_s32 ret = OT_ERR_SVP_NNIE_ILLEGAL_PARAM;
|
|
td_char path[PATH_MAX] = {0};
|
|
|
|
sample_svp_check_exps_return(((file_name == TD_NULL) || (nnie_param == TD_NULL)), OT_ERR_SVP_NNIE_NULL_PTR,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, file_name or nnie_param is TD_NULL!\n");
|
|
sample_svp_check_exps_return(((seg_idx >= OT_SVP_NNIE_MAX_NET_SEG_NUM) ||
|
|
(src_blob_idx >= OT_SVP_NNIE_MAX_IN_NUM)), OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, seg_idx(%u) should be less than %u and src_blob_idx(%u) should be less than %u!\n",
|
|
seg_idx, OT_SVP_NNIE_MAX_NET_SEG_NUM, src_blob_idx, OT_SVP_NNIE_MAX_IN_NUM);
|
|
sample_svp_check_exps_return((strlen(file_name) > PATH_MAX) ||
|
|
(realpath(file_name, path) == TD_NULL), ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, file_name is invalid!\n");
|
|
/* open file */
|
|
if (path != TD_NULL) {
|
|
fp = fopen(path, "rb");
|
|
sample_svp_check_exps_goto(fp == TD_NULL, fail, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, open %s file failed!\n", path);
|
|
}
|
|
sample_svp_check_exps_goto(nnie_param->seg_data[seg_idx].src[src_blob_idx].type == OT_SVP_BLOB_TYPE_BSI_SQ32,
|
|
fail, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error, do not support type(%d)!\n", OT_SVP_BLOB_TYPE_BSI_SQ32);
|
|
ret = sample_svp_nnie_check_hw_blob(&nnie_param->seg_data[seg_idx].src[src_blob_idx]);
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, fail, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, sample_svp_nnie_check_hw_blob failed!\n");
|
|
|
|
/* fill src data */
|
|
if (nnie_param->seg_data[seg_idx].src[src_blob_idx].type == OT_SVP_BLOB_TYPE_SEQ_S20Q12) {
|
|
ret = sample_svp_nnie_fill_src_seq(fp, seg_idx, src_blob_idx, nnie_param);
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, fail, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, sample_svp_nnie_fill_src_seq failed!\n");
|
|
} else if ((nnie_param->seg_data[seg_idx].src[src_blob_idx].type >= OT_SVP_BLOB_TYPE_U8) &&
|
|
(nnie_param->seg_data[seg_idx].src[src_blob_idx].type <= OT_SVP_BLOB_TYPE_YVU422SP)) {
|
|
ret = sample_svp_nnie_fill_src_image(fp, seg_idx, src_blob_idx, nnie_param);
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, fail, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, sample_common_svp_nnie_fill_src_image failed!\n");
|
|
} else {
|
|
ret = sample_svp_nnie_fill_src_tensor_vector(fp, seg_idx, src_blob_idx, nnie_param);
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, fail, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error, sample_svp_nnie_fill_src_tensor_vector failed!\n");
|
|
}
|
|
if (fp != TD_NULL) {
|
|
fclose(fp);
|
|
}
|
|
return TD_SUCCESS;
|
|
fail:
|
|
if (fp != TD_NULL) {
|
|
fclose(fp);
|
|
}
|
|
return OT_ERR_SVP_NNIE_ILLEGAL_PARAM;
|
|
}
|
|
|
|
/* function: print report result */
|
|
td_s32 sample_common_svp_nnie_print_report_result(sample_svp_nnie_param *nnie_param)
|
|
{
|
|
td_u32 seg_num;
|
|
td_u32 seg_idx, node_idx;
|
|
td_s32 ret;
|
|
td_char report_file_name[SAMPLE_SVP_NNIE_REPORT_NAME_LENGTH] = { '\0' };
|
|
FILE *fp = TD_NULL;
|
|
|
|
sample_svp_check_exps_return(nnie_param == TD_NULL, OT_ERR_SVP_NNIE_NULL_PTR, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,nnie_param is TD_NULL!\n");
|
|
sample_svp_check_exps_return(nnie_param->model == TD_NULL, OT_ERR_SVP_NNIE_NULL_PTR, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,nnie_param->model is TD_NULL!\n");
|
|
seg_num = nnie_param->model->net_seg_num;
|
|
sample_svp_check_exps_return(seg_num > OT_SVP_NNIE_MAX_NET_SEG_NUM, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,seg_num(%u) is greater than %u!\n", seg_num, OT_SVP_NNIE_MAX_NET_SEG_NUM);
|
|
for (seg_idx = 0; seg_idx < seg_num; seg_idx++) {
|
|
sample_svp_check_exps_return(nnie_param->model->seg[seg_idx].dst_num > OT_SVP_NNIE_MAX_OUT_NUM,
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,nnie_param->model->seg[%u].dst_num(%u) is greater than %u!\n", seg_idx,
|
|
nnie_param->model->seg[seg_idx].dst_num, OT_SVP_NNIE_MAX_OUT_NUM);
|
|
for (node_idx = 0; node_idx < nnie_param->model->seg[seg_idx].dst_num; node_idx++) {
|
|
ret = snprintf_s(report_file_name, SAMPLE_SVP_NNIE_REPORT_NAME_LENGTH - 1,
|
|
SAMPLE_SVP_NNIE_REPORT_NAME_LENGTH - 1, "seg%u_layer%u_output%u_inst.linear.hex", seg_idx,
|
|
nnie_param->model->seg[seg_idx].dst_node[node_idx].node_id, 0);
|
|
sample_svp_check_exps_return(ret < 0, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,create file name failed!\n");
|
|
|
|
fp = fopen(report_file_name, "w");
|
|
sample_svp_check_exps_return(fp == TD_NULL, OT_ERR_SVP_NNIE_NULL_PTR, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,open file failed!\n");
|
|
ret = sample_svp_nnie_check_hw_blob(&nnie_param->seg_data[seg_idx].dst[node_idx]);
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, print_fail, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_svp_nnie_check_hw_blob failed!\n");
|
|
|
|
ret = sample_svp_nnie_print_report_blob(nnie_param, seg_idx, node_idx, fp);
|
|
sample_svp_check_exps_goto(ret != TD_SUCCESS, print_fail, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_common_svp_nnie_print_report_blob failed!\n");
|
|
|
|
fclose(fp);
|
|
}
|
|
}
|
|
return TD_SUCCESS;
|
|
|
|
print_fail:
|
|
fclose(fp);
|
|
return OT_ERR_SVP_NNIE_ILLEGAL_PARAM;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_check_each_get_result_dst_blob(ot_svp_dst_blob *blob, td_u64 dst_width)
|
|
{
|
|
td_s32 ret = OT_ERR_SVP_NNIE_ILLEGAL_PARAM;
|
|
|
|
sample_svp_check_exps_return(blob->num == 0, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->num(%d) is 0!\n", blob->num);
|
|
sample_svp_check_exps_return(blob->shape.whc.chn != 1, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.whc.chn(%u) should be 1!\n", blob->shape.whc.chn);
|
|
sample_svp_check_exps_return(blob->shape.whc.height != 1, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.whc.height(%u) should be 1!\n", blob->shape.whc.height);
|
|
sample_svp_check_exps_return((blob->shape.whc.width < dst_width), ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->shape.whc.width(%u) is less than %llu!\n", blob->shape.whc.width, dst_width);
|
|
sample_svp_check_exps_return((blob->stride < blob->shape.whc.width * sizeof(td_u32)), ret,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,blob->stride(%u) is less than %u!\n",
|
|
blob->stride, (td_u32)(blob->shape.whc.width * sizeof(td_u32)));
|
|
sample_svp_check_exps_return(sample_svp_nnie_check_align_16(blob->stride) != 0, ret,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,blob->stride(%u) is not %u bytes align!\n",
|
|
blob->stride, SAMPLE_SVP_NNIE_ALIGN_16);
|
|
sample_svp_check_exps_return(blob->virt_addr == 0, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,blob->virt_addr is 0!\n");
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_svp_nnie_check_get_result_dst_blob(ot_svp_src_blob *bbox, ot_svp_src_blob *score,
|
|
ot_svp_src_blob *class_roi_num)
|
|
{
|
|
td_s32 ret = OT_ERR_SVP_NNIE_ILLEGAL_PARAM;
|
|
td_u64 max_roi_num = 0;
|
|
td_u32 i;
|
|
td_u32 class_num = class_roi_num->shape.whc.width;
|
|
td_u32 *roi_num = sample_svp_convert_addr_to_ptr(td_u32, class_roi_num->virt_addr);
|
|
|
|
sample_svp_check_exps_return(((class_num == 0) || (class_num > SAMPLE_SVP_NNIE_MAX_CLASS_NUM)), ret,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,class_num(%u) should be (0, %u]!\n",
|
|
class_num, SAMPLE_SVP_NNIE_MAX_CLASS_NUM);
|
|
|
|
sample_svp_check_exps_return(class_roi_num->type != OT_SVP_BLOB_TYPE_U32, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,class_roi_num->type(%d) should be %d!\n", class_roi_num->type, OT_SVP_BLOB_TYPE_U32);
|
|
ret = sample_svp_nnie_check_each_get_result_dst_blob(class_roi_num, class_num);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_svp_nnie_check_each_get_result_dst_blob failed!\n");
|
|
for (i = 0; i < class_roi_num->shape.whc.width; i++) {
|
|
max_roi_num += *(roi_num + i);
|
|
}
|
|
sample_svp_check_exps_return(max_roi_num > SAMPLE_SVP_NNIE_MAX_U32, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,max_roi_num(%llu) is greater than %u!\n", max_roi_num, SAMPLE_SVP_NNIE_MAX_U32);
|
|
|
|
sample_svp_check_exps_return(bbox->type != OT_SVP_BLOB_TYPE_S32, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,bbox->type(%d) should be %d!\n", bbox->type, OT_SVP_BLOB_TYPE_S32);
|
|
ret = sample_svp_nnie_check_each_get_result_dst_blob(bbox, class_num * max_roi_num * SAMPLE_SVP_NNIE_COORD_NUM);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_svp_nnie_check_each_get_result_dst_blob failed!\n");
|
|
|
|
sample_svp_check_exps_return(score->type != OT_SVP_BLOB_TYPE_S20Q12, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,score->type(%d) should be %d!\n", score->type, OT_SVP_BLOB_TYPE_S20Q12);
|
|
ret = sample_svp_nnie_check_each_get_result_dst_blob(score, class_num * max_roi_num);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_svp_nnie_check_each_get_result_dst_blob failed!\n");
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
/* function: print detection result */
|
|
td_s32 sample_common_svp_nnie_print_sw_detect_result(ot_svp_blob *dst_score,
|
|
ot_svp_blob *dst_roi, ot_svp_blob *class_roi_num, td_bool has_bg_class, td_float print_result_thresh)
|
|
{
|
|
td_u32 i, j;
|
|
td_u32 score_bias, bbox_bias, class_num, roi_num_bias, coord_offset;
|
|
td_float conf;
|
|
td_s32 *score = TD_NULL;
|
|
td_s32 *roi = TD_NULL;
|
|
td_s32 *roi_num = TD_NULL;
|
|
td_s32 x_min, y_min, x_max, y_max;
|
|
td_u32 start_class_idx = (has_bg_class == TD_TRUE) ? 1 : 0;
|
|
td_s32 ret;
|
|
|
|
sample_svp_check_exps_return(((dst_score == TD_NULL) || (dst_roi == TD_NULL) || (class_roi_num == TD_NULL)),
|
|
OT_ERR_SVP_NNIE_NULL_PTR, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,some input params are TD_NULL!\n");
|
|
ret = sample_svp_nnie_check_get_result_dst_blob(dst_roi, dst_score, class_roi_num);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_svp_nnie_check_get_result_dst_blob failed!\n");
|
|
score = sample_svp_convert_addr_to_ptr(td_s32, dst_score->virt_addr);
|
|
roi = sample_svp_convert_addr_to_ptr(td_s32, dst_roi->virt_addr);
|
|
roi_num = sample_svp_convert_addr_to_ptr(td_s32, class_roi_num->virt_addr);
|
|
class_num = class_roi_num->shape.whc.width;
|
|
roi_num_bias = (has_bg_class == TD_TRUE) ? roi_num[0] : 0;
|
|
for (i = start_class_idx; i < class_num; i++) {
|
|
score_bias = roi_num_bias;
|
|
bbox_bias = roi_num_bias * SAMPLE_SVP_NNIE_COORD_NUM;
|
|
/* if the confidence score greater than result threshold, the result will be printed */
|
|
if ((td_float)score[score_bias] / SAMPLE_SVP_NNIE_QUANT_BASE >= print_result_thresh &&
|
|
roi_num[i] != 0) {
|
|
sample_svp_trace_info("==== the %u-th class box info ====\n", i);
|
|
}
|
|
for (j = 0; j < (td_u32)roi_num[i]; j++) {
|
|
conf = (td_float)score[score_bias + j] / SAMPLE_SVP_NNIE_QUANT_BASE;
|
|
if (conf < print_result_thresh) {
|
|
break;
|
|
}
|
|
coord_offset = 0;
|
|
x_min = roi[bbox_bias + j * SAMPLE_SVP_NNIE_COORD_NUM + (coord_offset++)];
|
|
y_min = roi[bbox_bias + j * SAMPLE_SVP_NNIE_COORD_NUM + (coord_offset++)];
|
|
x_max = roi[bbox_bias + j * SAMPLE_SVP_NNIE_COORD_NUM + (coord_offset++)];
|
|
y_max = roi[bbox_bias + j * SAMPLE_SVP_NNIE_COORD_NUM + (coord_offset++)];
|
|
sample_svp_trace_info("%d %d %d %d %f\n", x_min, y_min, x_max, y_max, conf);
|
|
}
|
|
roi_num_bias += roi_num[i];
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 sample_common_svp_nnie_print_hw_detect_result(ot_svp_blob *dst, td_u32 class_num,
|
|
td_bool has_bg_class, td_float print_result_thresh)
|
|
{
|
|
td_u32 i;
|
|
td_s32 *num = TD_NULL;
|
|
sample_svp_nnie_hw_detect_out_result result;
|
|
td_u32 start_class_idx = (has_bg_class == TD_TRUE) ? 1 : 0;
|
|
td_u32 offset;
|
|
td_s32 ret;
|
|
|
|
sample_svp_check_exps_return(dst == TD_NULL, OT_ERR_SVP_NNIE_NULL_PTR, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,dst is TD_NULL!\n");
|
|
ret = sample_svp_nnie_check_hw_bsi_blob(dst, class_num);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,sample_svp_nnie_check_hw_bsi_blob failed!\n");
|
|
num = sample_svp_convert_addr_to_ptr(td_s32, dst->virt_addr);
|
|
result.x_min = num + sample_svp_nnie_align_32(dst->shape.whc.chn * sizeof(td_s32)) / sizeof(td_s32);
|
|
result.y_min = result.x_min + dst->stride / sizeof(td_s32);
|
|
result.x_max = result.y_min + dst->stride / sizeof(td_s32);
|
|
result.y_max = result.x_max + dst->stride / sizeof(td_s32);
|
|
result.score = result.y_max + dst->stride / sizeof(td_s32);
|
|
result.class_id = result.score + dst->stride / sizeof(td_s32);
|
|
if (dst->shape.whc.chn != 1) {
|
|
for (i = start_class_idx; i < class_num; i++) {
|
|
offset = i * dst->shape.whc.height * dst->stride / sizeof(td_s32);
|
|
sample_svp_nnie_print_hw_detect_each_class_result(&result, offset, i, *(num + i), print_result_thresh);
|
|
}
|
|
} else {
|
|
for (i = start_class_idx; i < class_num; i++) {
|
|
sample_svp_nnie_print_hw_detect_each_class_result(&result, 0, i, *num, print_result_thresh);
|
|
}
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_sample_common_svp_nnie_fill_rect_check_param(ot_video_frame_info *frame_info,
|
|
sample_svp_nnie_rect_info *rect_info)
|
|
{
|
|
td_u32 i;
|
|
|
|
sample_svp_check_exps_return(((frame_info == TD_NULL) || (rect_info == TD_NULL)), OT_ERR_SVP_NNIE_NULL_PTR,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,frame_info or rect_info is TD_NULL!\n");
|
|
sample_svp_check_exps_return(rect_info->class_num > SAMPLE_SVP_NNIE_MAX_CLASS_NUM, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,rect_info->class_num(%u) is greater than %u!\n",
|
|
rect_info->class_num, SAMPLE_SVP_NNIE_MAX_CLASS_NUM);
|
|
for (i = 0; i < rect_info->class_num; i++) {
|
|
sample_svp_check_exps_return(rect_info->roi_num[i] > SAMPLE_SVP_NNIE_MAX_ROI_NUM_OF_CLASS,
|
|
OT_ERR_SVP_NNIE_ILLEGAL_PARAM, SAMPLE_SVP_ERR_LEVEL_ERROR,
|
|
"Error,rect_info->roi_num[%u](%u) is greater than %u!\n",
|
|
i, rect_info->roi_num[i], SAMPLE_SVP_NNIE_MAX_ROI_NUM_OF_CLASS);
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
td_s32 sample_common_svp_nnie_fill_rect(ot_video_frame_info *frame_info,
|
|
sample_svp_nnie_rect_info *rect_info, td_u32 color)
|
|
{
|
|
ot_vgs_handle handle;
|
|
td_s32 ret;
|
|
td_u32 i, j;
|
|
ot_vgs_task_attr vgs_task;
|
|
ot_cover cover;
|
|
|
|
ret = sample_sample_common_svp_nnie_fill_rect_check_param(frame_info, rect_info);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,check param fail!\n");
|
|
|
|
if (rect_info->total_num == 0) {
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
ret = ss_mpi_vgs_begin_job(&handle);
|
|
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "Error,vgs begin job fail!\n");
|
|
|
|
ret = memcpy_s(&vgs_task.img_in, sizeof(ot_video_frame_info), frame_info, sizeof(ot_video_frame_info));
|
|
sample_svp_check_exps_return(ret != EOK, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "memcpy_s failed!\n");
|
|
ret = memcpy_s(&vgs_task.img_out, sizeof(ot_video_frame_info), frame_info, sizeof(ot_video_frame_info));
|
|
sample_svp_check_exps_return(ret != EOK, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "memcpy_s failed!\n");
|
|
|
|
cover.type = OT_COVER_QUAD;
|
|
cover.color = color;
|
|
cover.quad.is_solid = TD_FALSE;
|
|
cover.quad.thick = SAMPLE_SVP_NNIE_RECT_THICK;
|
|
|
|
for (i = 0; i < rect_info->class_num; i++) {
|
|
for (j = 0; j < rect_info->roi_num[i]; j++) {
|
|
ret = memcpy_s(cover.quad.point, sizeof(rect_info->rect[i][j].point),
|
|
rect_info->rect[i][j].point, sizeof(rect_info->rect[i][j].point));
|
|
sample_svp_check_exps_return(ret != EOK, OT_ERR_SVP_NNIE_ILLEGAL_PARAM,
|
|
SAMPLE_SVP_ERR_LEVEL_ERROR, "memcpy_s failed!\n");
|
|
ret = ss_mpi_vgs_add_cover_task(handle, &vgs_task, &cover, 1);
|
|
if (ret != TD_SUCCESS) {
|
|
ss_mpi_vgs_cancel_job(handle);
|
|
sample_svp_check_exps_return(1, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "ss_mpi_vgs_add_cover_task fail\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
ret = ss_mpi_vgs_end_job(handle);
|
|
if (ret != TD_SUCCESS) {
|
|
ss_mpi_vgs_cancel_job(handle);
|
|
sample_svp_check_exps_return(1, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "ss_mpi_vgs_end_job fail\n");
|
|
}
|
|
return ret;
|
|
}
|