/* Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd. */ #include "sample_common_nnie.h" #include #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; }