/* Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd. */ #include "sample_common_svp_npu_model.h" #include #include "svp_acl_rt.h" #include "svp_acl_ext.h" #include "libapi_common_svp.h" static struct_svp_npu_model_info g_svp_npu_model[MACRO_SVP_NPU_MAX_MODEL_NUM] = {0}; static td_s32 sample_svp_npu_get_model_base_info(td_u32 model_index) { svp_acl_error ret; g_svp_npu_model[model_index].input_num = svp_acl_mdl_get_num_inputs(g_svp_npu_model[model_index].model_desc); macro_svp_check_exps_return(g_svp_npu_model[model_index].input_num < MACRO_SVP_NPU_EXTRA_INPUT_NUM + 1, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get input num failed!\n"); g_svp_npu_model[model_index].output_num = svp_acl_mdl_get_num_outputs(g_svp_npu_model[model_index].model_desc); macro_svp_check_exps_return(g_svp_npu_model[model_index].output_num < 1, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get output num failed!\n"); ret = svp_acl_mdl_get_input_index_by_name(g_svp_npu_model[model_index].model_desc, SVP_ACL_DYNAMIC_TENSOR_NAME, &g_svp_npu_model[model_index].dynamic_batch_idx); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get dynamic batch idx failed, model id is %u, error code is %d!\n", model_index, ret); return TD_SUCCESS; } static td_s32 sample_svp_npu_get_line_num_and_line_byte_num(const struct_svp_npu_task_info *task, td_u32 idx, td_bool is_input, td_u32 *total_line_num, td_u32 *line_byte_num) { td_s32 ret; td_u32 i; svp_acl_mdl_io_dims dims; svp_acl_data_type data_type; size_t data_size; if (is_input == TD_TRUE) { ret = svp_acl_mdl_get_input_dims(g_svp_npu_model[task->cfg.model_idx].model_desc, idx, &dims); } else { ret = svp_acl_mdl_get_output_dims(g_svp_npu_model[task->cfg.model_idx].model_desc, idx, &dims); } macro_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th input/output dims failed!\n", idx); if (is_input == TD_TRUE) { data_type = svp_acl_mdl_get_input_data_type(g_svp_npu_model[task->cfg.model_idx].model_desc, idx); } else { data_type = svp_acl_mdl_get_output_data_type(g_svp_npu_model[task->cfg.model_idx].model_desc, idx); } macro_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th input/output data type failed!\n", idx); data_size = svp_acl_data_type_size(data_type); macro_svp_check_exps_return(data_size == 0, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get data size failed!\n"); *line_byte_num = dims.dims[dims.dim_count - 1] * ((data_size + MACRO_SVP_NPU_BYTE_BIT_NUM - 1) / MACRO_SVP_NPU_BYTE_BIT_NUM); *total_line_num = 1; for (i = 0; i < dims.dim_count - 1; i++) { *total_line_num *= dims.dims[i]; } /* lstm xt line num */ if ((task->cfg.total_t != 0) && (idx == 0)) { macro_svp_check_exps_return(task->cfg.total_t > dims.dims[0], TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "total t(%u) can't be greater than max total t(%ld)!\n", task->cfg.total_t, dims.dims[0]); *total_line_num /= dims.dims[0]; *total_line_num *= task->cfg.total_t; } return TD_SUCCESS; } static td_s32 sample_svp_check_task_cfg(const struct_svp_npu_task_info *task) { macro_svp_check_exps_return(task == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "task is NULL!\n"); macro_svp_check_exps_return(task->cfg.max_batch_num == 0, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "max_batch_num(%u) is 0!\n", task->cfg.max_batch_num); macro_svp_check_exps_return(task->cfg.dynamic_batch_num == 0, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "dynamic_batch_num(%u) is 0!\n", task->cfg.dynamic_batch_num); macro_svp_check_exps_return(task->cfg.total_t != 0 && task->cfg.dynamic_batch_num != 1, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "dynamic_batch_num(%u) should be 1 when total_t(%u) is not 0!\n", task->cfg.dynamic_batch_num, task->cfg.total_t); macro_svp_check_exps_return((task->cfg.is_cached != TD_TRUE && task->cfg.is_cached != TD_FALSE), TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "is_cached(%u) should be [%u, %u]!\n", task->cfg.is_cached, TD_FALSE, TD_TRUE); macro_svp_check_exps_return(task->cfg.model_idx >= MACRO_SVP_NPU_MAX_MODEL_NUM, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "model_idx(%u) should be less than %u!\n", task->cfg.model_idx, MACRO_SVP_NPU_MAX_MODEL_NUM); macro_svp_check_exps_return(g_svp_npu_model[task->cfg.model_idx].model_desc == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "%u-th model_desc is NULL!\n", task->cfg.model_idx); return TD_SUCCESS; } td_s32 sample_common_svp_npu_get_input_data(const td_char *src[], td_u32 file_num, const struct_svp_npu_task_info *task) { td_s32 ret; td_u32 i, line, total_line_num, line_byte_num; td_char path[PATH_MAX] = { 0 }; size_t stride, size, input_num; FILE *fp = TD_NULL; td_void *data = TD_NULL; svp_acl_data_buffer *data_buffer = TD_NULL; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } macro_svp_check_exps_return(src == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "src is NULL!\n"); input_num = g_svp_npu_model[task->cfg.model_idx].input_num - MACRO_SVP_NPU_EXTRA_INPUT_NUM; macro_svp_check_exps_return(input_num != file_num, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "input file num(%u) should be equal to %lu!\n", file_num, input_num); for (i = 0; i < file_num; i++) { macro_svp_check_exps_return(realpath(src[i], path) == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "Invalid file!\n"); fp = fopen(path, "rb"); macro_svp_check_exps_return(fp == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "open file failed!\n"); ret = sample_svp_npu_get_line_num_and_line_byte_num(task, i, TD_TRUE, &total_line_num, &line_byte_num); macro_svp_check_exps_goto(ret != TD_SUCCESS, end, ENUM_SVP_ERR_LEVEL_ERROR, "get line num failed!\n"); data_buffer = svp_acl_mdl_get_dataset_buffer(task->input_dataset, i); macro_svp_check_exps_goto(data_buffer == TD_NULL, end, ENUM_SVP_ERR_LEVEL_ERROR, "get data buffer NULL!\n"); data = svp_acl_get_data_buffer_addr(data_buffer); macro_svp_check_exps_goto(data == TD_NULL, end, ENUM_SVP_ERR_LEVEL_ERROR, "get data addr NULL!\n"); stride = svp_acl_get_data_buffer_stride(data_buffer); macro_svp_check_exps_goto(stride == 0, end, ENUM_SVP_ERR_LEVEL_ERROR, "get data stride failed!\n"); size = svp_acl_get_data_buffer_size(data_buffer); macro_svp_check_exps_goto(size < (td_u64)task->cfg.dynamic_batch_num * total_line_num * stride, end, ENUM_SVP_ERR_LEVEL_ERROR, "%u-th data buffer size(%lu) is less than needed(%llu)!\n", i, size, (td_u64)task->cfg.dynamic_batch_num * total_line_num * stride); for (line = 0; line < task->cfg.dynamic_batch_num * total_line_num; line++) { ret = fread(data + line * stride, line_byte_num, 1, fp); macro_svp_check_exps_goto(ret != 1, end, ENUM_SVP_ERR_LEVEL_ERROR, "Read file failed!\n"); } if (task->cfg.is_cached == TD_TRUE) { (td_void)svp_acl_rt_mem_flush(data, task->cfg.dynamic_batch_num * total_line_num * stride); } (td_void)fclose(fp); } return TD_SUCCESS; end: if (fp != TD_NULL) { (td_void)fclose(fp); } return TD_FAILURE; } static td_s32 sample_svp_npu_read_model(const td_char *model_path, td_u32 model_index, td_bool is_cached) { FILE *fp = TD_NULL; td_s32 ret; /* Get model file size */ fp = fopen(model_path, "rb"); macro_svp_check_exps_return(fp == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "open model file failed, model file is %s!\n", model_path); ret = fseek(fp, 0L, SEEK_END); macro_svp_check_exps_goto(ret == -1, end_0, ENUM_SVP_ERR_LEVEL_ERROR, "fseek failed!\n"); g_svp_npu_model[model_index].model_mem_size = ftell(fp); macro_svp_check_exps_goto(g_svp_npu_model[model_index].model_mem_size <= 0, end_0, ENUM_SVP_ERR_LEVEL_ERROR, "ftell failed!\n"); ret = fseek(fp, 0L, SEEK_SET); macro_svp_check_exps_goto(ret == -1, end_0, ENUM_SVP_ERR_LEVEL_ERROR, "fseek failed!\n"); /* malloc model file mem */ if (is_cached == TD_TRUE) { ret = svp_acl_rt_malloc_cached(&g_svp_npu_model[model_index].model_mem_ptr, g_svp_npu_model[model_index].model_mem_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY); } else { ret = svp_acl_rt_malloc(&g_svp_npu_model[model_index].model_mem_ptr, g_svp_npu_model[model_index].model_mem_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY); } macro_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_0, ENUM_SVP_ERR_LEVEL_ERROR, "malloc mem failed, erroe code %d!\n", ret); ret = fread(g_svp_npu_model[model_index].model_mem_ptr, g_svp_npu_model[model_index].model_mem_size, 1, fp); macro_svp_check_exps_goto(ret != 1, end_1, ENUM_SVP_ERR_LEVEL_ERROR, "read model file failed!\n"); if (is_cached == TD_TRUE) { ret = svp_acl_rt_mem_flush(g_svp_npu_model[model_index].model_mem_ptr, g_svp_npu_model[model_index].model_mem_size); macro_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_1, ENUM_SVP_ERR_LEVEL_ERROR, "flush mem failed!, error code is %d\n", ret); } (td_void)fclose(fp); return TD_SUCCESS; end_1: (td_void)svp_acl_rt_free(g_svp_npu_model[model_index].model_mem_ptr); end_0: (td_void)fclose(fp); return TD_FAILURE; } static td_s32 sample_svp_npu_create_desc(td_u32 model_index) { svp_acl_error ret; g_svp_npu_model[model_index].model_desc = svp_acl_mdl_create_desc(); macro_svp_check_exps_return(g_svp_npu_model[model_index].model_desc == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "create model description failed!\n"); ret = svp_acl_mdl_get_desc(g_svp_npu_model[model_index].model_desc, g_svp_npu_model[model_index].model_id); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get model description failed, error code is %d!\n", ret); macro_svp_trace_info("create model description success!\n"); return TD_SUCCESS; } td_s32 sample_common_svp_npu_load_model(const td_char *model_path, td_u32 model_index, td_bool is_cached) { td_s32 ret; macro_svp_check_exps_return(g_svp_npu_model[model_index].is_load_flag == TD_TRUE, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "%u-th node has already loaded a model!\n", model_index); ret = sample_svp_npu_read_model(model_path, model_index, is_cached); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "query model failed, model file is %s!\n", model_path); ret = svp_acl_mdl_load_from_mem(g_svp_npu_model[model_index].model_mem_ptr, g_svp_npu_model[model_index].model_mem_size, &g_svp_npu_model[model_index].model_id); macro_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_0, ENUM_SVP_ERR_LEVEL_ERROR, "load model from mem failed, error code is %d!\n", ret); ret = sample_svp_npu_create_desc(model_index); macro_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_0, ENUM_SVP_ERR_LEVEL_ERROR, "create desc failed, model file is %s!\n", model_path); ret = sample_svp_npu_get_model_base_info(model_index); macro_svp_check_exps_goto(ret != SVP_ACL_SUCCESS, end_1, ENUM_SVP_ERR_LEVEL_ERROR, "get model base info failed, model file is %s!\n", model_path); macro_svp_trace_info("load mem_size:%lu, id:%d!\n", g_svp_npu_model[model_index].model_mem_size, g_svp_npu_model[model_index].model_id); g_svp_npu_model[model_index].is_load_flag = TD_TRUE; macro_svp_trace_info("load model %s success!\n", model_path); return TD_SUCCESS; end_1: (td_void)svp_acl_mdl_destroy_desc(g_svp_npu_model[model_index].model_desc); g_svp_npu_model[model_index].model_desc = TD_NULL; end_0: (td_void)svp_acl_rt_free(g_svp_npu_model[model_index].model_mem_ptr); g_svp_npu_model[model_index].model_mem_ptr = TD_NULL; g_svp_npu_model[model_index].model_mem_size = 0; return TD_FAILURE; } td_void sample_common_svp_npu_unload_model(td_u32 model_index) { svp_acl_error ret; macro_svp_check_exps_return_void(g_svp_npu_model[model_index].is_load_flag != TD_TRUE, ENUM_SVP_ERR_LEVEL_ERROR, "%u-th node has not loaded a model!\n", model_index); ret = svp_acl_mdl_unload(g_svp_npu_model[model_index].model_id); if (ret != SVP_ACL_SUCCESS) { macro_svp_trace_err("unload model failed, model_id is %u, error code is %d!\n", g_svp_npu_model[model_index].model_id, ret); } if (g_svp_npu_model[model_index].model_desc != TD_NULL) { (td_void)svp_acl_mdl_destroy_desc(g_svp_npu_model[model_index].model_desc); g_svp_npu_model[model_index].model_desc = TD_NULL; } if (g_svp_npu_model[model_index].model_mem_ptr != TD_NULL) { (td_void)svp_acl_rt_free(g_svp_npu_model[model_index].model_mem_ptr); g_svp_npu_model[model_index].model_mem_ptr = TD_NULL; g_svp_npu_model[model_index].model_mem_size = 0; } g_svp_npu_model[model_index].is_load_flag = TD_FALSE; macro_svp_trace_info("unload model SUCCESS, model id is %u!\n", g_svp_npu_model[model_index].model_id); } static td_s32 sample_svp_npu_malloc_mem(td_void **buffer, td_u32 buffer_size, td_bool is_cached) { svp_acl_error ret; if (is_cached == TD_TRUE) { ret = svp_acl_rt_malloc_cached(buffer, buffer_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY); } else { ret = svp_acl_rt_malloc(buffer, buffer_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY); } macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "can't malloc buffer, size is %u, error code is %d!\n", buffer_size, ret); (td_void)memset_s(*buffer, buffer_size, 0, buffer_size); if (is_cached == TD_TRUE) { (td_void)svp_acl_rt_mem_flush(*buffer, buffer_size); } return ret; } static td_void sample_svp_npu_destroy_data_buffer(svp_acl_data_buffer *input_data) { td_void *data = svp_acl_get_data_buffer_addr(input_data); (td_void)svp_acl_rt_free(data); (td_void)svp_acl_destroy_data_buffer(input_data); } static svp_acl_data_buffer *sample_common_svp_npu_create_input_data_buffer(struct_svp_npu_task_info *task, td_u32 idx) { size_t buffer_size, stride; td_void *input_buffer = TD_NULL; svp_acl_data_buffer *input_data = TD_NULL; stride = svp_acl_mdl_get_input_default_stride(g_svp_npu_model[task->cfg.model_idx].model_desc, idx); macro_svp_check_exps_return(stride == 0, input_data, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th input stride failed!\n", idx); buffer_size = svp_acl_mdl_get_input_size_by_index(g_svp_npu_model[task->cfg.model_idx].model_desc, idx) * (td_u64)task->cfg.max_batch_num; macro_svp_check_exps_return((buffer_size == 0 || buffer_size > MACRO_SVP_NPU_MAX_MEM_SIZE), input_data, ENUM_SVP_ERR_LEVEL_ERROR, "buffer_size(%lu) can't be 0 and should be less than %u!\n", buffer_size, MACRO_SVP_NPU_MAX_MEM_SIZE); if (sample_svp_npu_malloc_mem(&input_buffer, (td_u32)buffer_size, task->cfg.is_cached) != TD_SUCCESS) { macro_svp_trace_err("%u-th input malloc mem failed!\n", idx); return input_data; } input_data = svp_acl_create_data_buffer(input_buffer, buffer_size, stride); if (input_data == TD_NULL) { macro_svp_trace_err("can't create %u-th input data buffer!\n", idx); (td_void)svp_acl_rt_free(input_buffer); return input_data; } if (idx == g_svp_npu_model[task->cfg.model_idx].input_num - MACRO_SVP_NPU_EXTRA_INPUT_NUM) { task->task_buf_ptr = input_buffer; task->task_buf_size = buffer_size; task->task_buf_stride = stride; } else if (idx == g_svp_npu_model[task->cfg.model_idx].input_num - 1) { task->work_buf_ptr = input_buffer; task->work_buf_size = buffer_size; task->work_buf_stride = stride; } return input_data; } static svp_acl_data_buffer *sample_common_svp_npu_create_output_data_buffer(const struct_svp_npu_task_info *task, td_u32 idx) { size_t buffer_size, stride; td_void *output_buffer = TD_NULL; svp_acl_data_buffer *output_data = TD_NULL; stride = svp_acl_mdl_get_output_default_stride(g_svp_npu_model[task->cfg.model_idx].model_desc, idx); macro_svp_check_exps_return(stride == 0, output_data, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th output stride failed!\n", idx); buffer_size = svp_acl_mdl_get_output_size_by_index(g_svp_npu_model[task->cfg.model_idx].model_desc, idx) * (td_u64)task->cfg.max_batch_num; macro_svp_check_exps_return((buffer_size == 0 || buffer_size > MACRO_SVP_NPU_MAX_MEM_SIZE), output_data, ENUM_SVP_ERR_LEVEL_ERROR, "buffer_size(%lu) can't be 0 and should be less than %u!\n", buffer_size, MACRO_SVP_NPU_MAX_MEM_SIZE); if (sample_svp_npu_malloc_mem(&output_buffer, buffer_size, task->cfg.is_cached) != TD_SUCCESS) { macro_svp_trace_err("%u-th output malloc mem failed!\n", idx); return output_data; } output_data = svp_acl_create_data_buffer(output_buffer, buffer_size, stride); if (output_data == TD_NULL) { macro_svp_trace_err("can't create %u-th output data buffer!\n", idx); (td_void)svp_acl_rt_free(output_buffer); return output_data; } return output_data; } td_s32 sample_common_svp_npu_create_input(struct_svp_npu_task_info *task) { svp_acl_error ret; td_u32 i; svp_acl_data_buffer *input_data = TD_NULL; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } task->input_dataset = svp_acl_mdl_create_dataset(); macro_svp_check_exps_return(task->input_dataset == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "create input dataset failed!\n"); for (i = 0; i < g_svp_npu_model[task->cfg.model_idx].input_num - MACRO_SVP_NPU_EXTRA_INPUT_NUM; i++) { input_data = sample_common_svp_npu_create_input_data_buffer(task, i); if (input_data == TD_NULL) { macro_svp_trace_err("create %u-th input data buffer failed!\n", i); (td_void)sample_common_svp_npu_destroy_input(task); return TD_FAILURE; } ret = svp_acl_mdl_add_dataset_buffer(task->input_dataset, input_data); if (ret != SVP_ACL_SUCCESS) { macro_svp_trace_err("add %u-th input data buffer failed!\n", i); (td_void)sample_svp_npu_destroy_data_buffer(input_data); (td_void)sample_common_svp_npu_destroy_input(task); return TD_FAILURE; } } return TD_SUCCESS; } td_s32 sample_common_svp_npu_create_output(struct_svp_npu_task_info *task) { svp_acl_error ret; td_u32 i; svp_acl_data_buffer *output_data = TD_NULL; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } task->output_dataset = svp_acl_mdl_create_dataset(); macro_svp_check_exps_return(task->input_dataset == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "create output dataset failed!\n"); for (i = 0; i < g_svp_npu_model[task->cfg.model_idx].output_num; i++) { output_data = sample_common_svp_npu_create_output_data_buffer(task, i); if (output_data == TD_NULL) { macro_svp_trace_err("create %u-th output data buffer failed!\n", i); (td_void)sample_common_svp_npu_destroy_input(task); return TD_FAILURE; } ret = svp_acl_mdl_add_dataset_buffer(task->output_dataset, output_data); if (ret != SVP_ACL_SUCCESS) { macro_svp_trace_err("add %u-th output data buffer failed!\n", i); (td_void)sample_svp_npu_destroy_data_buffer(output_data); (td_void)sample_common_svp_npu_destroy_output(task); return TD_FAILURE; } } return TD_SUCCESS; } td_void sample_common_svp_npu_destroy_input(struct_svp_npu_task_info *task) { td_u32 i; size_t input_num; svp_acl_data_buffer *data_buffer = TD_NULL; td_void *data = TD_NULL; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return; } if (task->input_dataset == TD_NULL) { return; } input_num = svp_acl_mdl_get_dataset_num_buffers(task->input_dataset); for (i = 0; i < input_num; i++) { data_buffer = svp_acl_mdl_get_dataset_buffer(task->input_dataset, i); if (i < g_svp_npu_model[task->cfg.model_idx].input_num - MACRO_SVP_NPU_EXTRA_INPUT_NUM) { data = svp_acl_get_data_buffer_addr(data_buffer); (td_void)svp_acl_rt_free(data); } (td_void)svp_acl_destroy_data_buffer(data_buffer); } (td_void)svp_acl_mdl_destroy_dataset(task->input_dataset); task->input_dataset = TD_NULL; } td_void sample_common_svp_npu_destroy_output(struct_svp_npu_task_info *task) { td_u32 i; size_t output_num; svp_acl_data_buffer *data_buffer = TD_NULL; td_void *data = TD_NULL; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return; } if (task->output_dataset == TD_NULL) { return; } output_num = svp_acl_mdl_get_dataset_num_buffers(task->output_dataset); for (i = 0; i < output_num; i++) { data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, i); data = svp_acl_get_data_buffer_addr(data_buffer); (td_void)svp_acl_rt_free(data); (td_void)svp_acl_destroy_data_buffer(data_buffer); } (td_void)svp_acl_mdl_destroy_dataset(task->output_dataset); task->output_dataset = TD_NULL; } td_void sample_common_svp_npu_destroy_task_buf(struct_svp_npu_task_info *task) { if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return; } if (task->task_buf_ptr == TD_NULL) { return; } (td_void)svp_acl_rt_free(task->task_buf_ptr); task->task_buf_ptr = TD_NULL; task->task_buf_stride = 0; task->task_buf_size = 0; } td_void sample_common_svp_npu_destroy_work_buf(struct_svp_npu_task_info *task) { if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return; } if (task->work_buf_ptr == TD_NULL) { return; } (td_void)svp_acl_rt_free(task->work_buf_ptr); task->work_buf_ptr = TD_NULL; task->work_buf_stride = 0; task->work_buf_size = 0; } td_s32 sample_common_svp_npu_create_task_buf(struct_svp_npu_task_info *task) { size_t num; svp_acl_data_buffer *task_buf = TD_NULL; svp_acl_error ret; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } macro_svp_check_exps_return(task->input_dataset == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "input_dataset is NULL!\n"); num = svp_acl_mdl_get_dataset_num_buffers(task->input_dataset); macro_svp_check_exps_return(num != g_svp_npu_model[task->cfg.model_idx].input_num - MACRO_SVP_NPU_EXTRA_INPUT_NUM, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "num of data buffer(%lu) should be %lu when create task buf!\n", num, g_svp_npu_model[task->cfg.model_idx].input_num - MACRO_SVP_NPU_EXTRA_INPUT_NUM); task_buf = sample_common_svp_npu_create_input_data_buffer(task, g_svp_npu_model[task->cfg.model_idx].input_num - MACRO_SVP_NPU_EXTRA_INPUT_NUM); macro_svp_check_exps_return(task_buf == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "create task buf failed!\n"); ret = svp_acl_mdl_add_dataset_buffer(task->input_dataset, task_buf); if (ret != SVP_ACL_SUCCESS) { macro_svp_trace_err("add task buf failed!\n"); (td_void)sample_svp_npu_destroy_data_buffer(task_buf); return TD_FAILURE; } return TD_SUCCESS; } td_s32 sample_common_svp_npu_create_work_buf(struct_svp_npu_task_info *task) { size_t num; svp_acl_data_buffer *work_buf = TD_NULL; svp_acl_error ret; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } macro_svp_check_exps_return(task->input_dataset == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "input_dataset is NULL!\n"); num = svp_acl_mdl_get_dataset_num_buffers(task->input_dataset); macro_svp_check_exps_return(num != g_svp_npu_model[task->cfg.model_idx].input_num - 1, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "num of data buffer(%lu) should be %lu when create work buf!\n", num, g_svp_npu_model[task->cfg.model_idx].input_num - 1); work_buf = sample_common_svp_npu_create_input_data_buffer(task, g_svp_npu_model[task->cfg.model_idx].input_num - 1); macro_svp_check_exps_return(work_buf == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "create work buf failed!\n"); ret = svp_acl_mdl_add_dataset_buffer(task->input_dataset, work_buf); if (ret != SVP_ACL_SUCCESS) { macro_svp_trace_err("add work buf failed!\n"); (td_void)sample_svp_npu_destroy_data_buffer(work_buf); return TD_FAILURE; } return TD_SUCCESS; } td_s32 sample_common_svp_npu_get_work_buf_info(const struct_svp_npu_task_info *task, td_u32 *work_buf_size, td_u32 *work_buf_stride) { if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } *work_buf_stride = (td_u32)svp_acl_mdl_get_input_default_stride(g_svp_npu_model[task->cfg.model_idx].model_desc, g_svp_npu_model[task->cfg.model_idx].input_num - 1); if (*work_buf_stride == 0) { macro_svp_trace_err("get work buf stride failed!\n"); return TD_FAILURE; } *work_buf_size = (td_u32)svp_acl_mdl_get_input_size_by_index(g_svp_npu_model[task->cfg.model_idx].model_desc, g_svp_npu_model[task->cfg.model_idx].input_num - 1); if (*work_buf_size == 0) { macro_svp_trace_err("get work buf size failed!\n"); return TD_FAILURE; } return TD_SUCCESS; } td_s32 sample_common_svp_npu_share_work_buf(const struct_svp_npu_shared_work_buf *shared_work_buf, const struct_svp_npu_task_info *task) { svp_acl_error ret; svp_acl_data_buffer *work_buf = TD_NULL; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } macro_svp_check_exps_return(shared_work_buf == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "shared_work_buf is NULL!\n"); macro_svp_check_exps_return(shared_work_buf->work_buf_ptr == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "work_buf_ptr is NULL!\n"); macro_svp_check_exps_return(task->work_buf_ptr != TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "task has created work buf!\n"); work_buf = svp_acl_create_data_buffer(shared_work_buf->work_buf_ptr, shared_work_buf->work_buf_size, shared_work_buf->work_buf_stride); macro_svp_check_exps_return(work_buf == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "create work buf failed!\n"); ret = svp_acl_mdl_add_dataset_buffer(task->input_dataset, work_buf); if (ret != SVP_ACL_SUCCESS) { macro_svp_trace_err("add work buf failed!\n"); (td_void)svp_acl_destroy_data_buffer(work_buf); return TD_FAILURE; } return TD_SUCCESS; } /* print the top n confidence values with indexes */ static td_void sample_svp_npu_sort_output_result(const td_float *src, td_u32 src_len, struct_svp_npu_top_n_result *dst, td_u32 dst_len) { td_u32 i, j, index; td_bool charge; for (i = 0; i < src_len; i++) { charge = TD_FALSE; for (j = 0; j < dst_len; j++) { if (src[i] > dst[j].score) { index = j; charge = TD_TRUE; break; } } if (charge == TD_TRUE) { for (j = dst_len - 1; j > index; j--) { dst[j].score = dst[j - 1].score; dst[j].class_id = dst[j - 1].class_id; } dst[index].score = src[i]; dst[index].class_id = i; } } } td_void sample_common_svp_npu_output_classification_result(const struct_svp_npu_task_info *task) { svp_acl_data_buffer *data_buffer = TD_NULL; td_void *data = TD_NULL; td_u32 i, j, n; svp_acl_error ret; size_t stride; svp_acl_mdl_io_dims dims; struct_svp_npu_top_n_result top[MACRO_SVP_NPU_SHOW_TOP_NUM] = { 0 }; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return; } macro_svp_check_exps_return_void(task->output_dataset == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "task->output_dataset is NULL!\n"); for (i = 0; i < svp_acl_mdl_get_dataset_num_buffers(task->output_dataset); i++) { data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, i); macro_svp_check_exps_return_void(data_buffer == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th data buffer is NULL!\n", i); data = svp_acl_get_data_buffer_addr(data_buffer); macro_svp_check_exps_return_void(data == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th data addr is NULL!\n", i); stride = svp_acl_get_data_buffer_stride(data_buffer); macro_svp_check_exps_return_void(data == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th data stride is 0!\n", i); ret = svp_acl_mdl_get_output_dims(g_svp_npu_model[task->cfg.model_idx].model_desc, i, &dims); macro_svp_check_exps_return_void(data == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th output dims failed, error code is %d!\n", i, ret); for (n = 0; n < task->cfg.dynamic_batch_num; n++) { (td_void)sample_svp_npu_sort_output_result(data, (td_u32)dims.dims[dims.dim_count - 1], top, MACRO_SVP_NPU_SHOW_TOP_NUM); macro_svp_trace_info("%u-th batch result:\n", n); for (j = 0; j < MACRO_SVP_NPU_SHOW_TOP_NUM; j++) { macro_svp_trace_info("top %d: value[%lf], class_id[%u]!\n", j, top[j].score, top[j].class_id); } data += stride; (td_void)memset_s(top, sizeof(top), 0, sizeof(top)); } } macro_svp_trace_info("output data success!\n"); } td_s32 sample_common_svp_npu_set_dynamic_batch(const struct_svp_npu_task_info *task) { svp_acl_error ret; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } ret = svp_acl_mdl_set_dynamic_batch_size(g_svp_npu_model[task->cfg.model_idx].model_id, task->input_dataset, g_svp_npu_model[task->cfg.model_idx].dynamic_batch_idx, task->cfg.dynamic_batch_num); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "set dynamic batch size failed, model id is %u, error code is %d!\n", g_svp_npu_model[task->cfg.model_idx].model_id, ret); if (task->cfg.total_t != 0) { ret = svp_acl_mdl_set_total_t(g_svp_npu_model[task->cfg.model_idx].model_id, task->input_dataset, task->cfg.total_t); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "set total_t failed, model id is %u, error code is %d!\n", g_svp_npu_model[task->cfg.model_idx].model_id, ret); } return TD_SUCCESS; } td_s32 sample_common_svp_npu_model_execute(const struct_svp_npu_task_info *task) { svp_acl_data_buffer *data_buffer = TD_NULL; td_void *data = TD_NULL; size_t size; td_u32 i; svp_acl_error ret; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } ret = svp_acl_mdl_execute(g_svp_npu_model[task->cfg.model_idx].model_id, task->input_dataset, task->output_dataset); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "svp_acl_mdl_execute failed, model_id is %u, error code is %d!\n", g_svp_npu_model[task->cfg.model_idx].model_id, ret); if (task->cfg.is_cached == TD_TRUE) { for (i = 0; i < g_svp_npu_model[task->cfg.model_idx].output_num; i++) { data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, i); macro_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th output data_buffer is NULL!\n", i); data = svp_acl_get_data_buffer_addr(data_buffer); macro_svp_check_exps_return(data == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th output data is NULL!\n", i); size = svp_acl_get_data_buffer_size(data_buffer) / task->cfg.max_batch_num * task->cfg.dynamic_batch_num; macro_svp_check_exps_return(size == 0, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th output data size is 0!\n", i); ret = svp_acl_rt_mem_flush(data, size); macro_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "flush %u-th output data failed, error code is %d!\n", i, ret); } } return ret; } static td_void sample_svp_npu_dump_dataset(const struct_svp_npu_task_info *task, const td_char *file_name, td_bool is_input) { td_u32 i, line, total_line_num, line_byte_num, data_num; svp_acl_error ret; size_t size, stride; svp_acl_data_buffer *data_buffer = TD_NULL; svp_acl_mdl_dataset *dataset = TD_NULL; td_void *data = TD_NULL; FILE *fp = TD_NULL; td_char name[MACRO_SVP_NPU_MAX_NAME_LEN] = {'\0'}; data_num = is_input == TD_TRUE ? g_svp_npu_model[task->cfg.model_idx].input_num - MACRO_SVP_NPU_EXTRA_INPUT_NUM : g_svp_npu_model[task->cfg.model_idx].output_num; dataset = is_input == TD_TRUE ? task->input_dataset : task->output_dataset; for (i = 0; i < data_num; i++) { ret = sample_svp_npu_get_line_num_and_line_byte_num(task, i, is_input, &total_line_num, &line_byte_num); macro_svp_check_exps_return_void(ret != TD_SUCCESS, ENUM_SVP_ERR_LEVEL_ERROR, "get line num and line byte num failed!\n"); data_buffer = svp_acl_mdl_get_dataset_buffer(dataset, i); macro_svp_check_exps_return_void(data_buffer == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th data_buffer failed!\n", i); data = svp_acl_get_data_buffer_addr(data_buffer); macro_svp_check_exps_return_void(data == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th data addr failed!\n", i); stride = svp_acl_get_data_buffer_stride(data_buffer); macro_svp_check_exps_return_void(stride == 0, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th data stride failed!\n", i); size = svp_acl_get_data_buffer_size(data_buffer); macro_svp_check_exps_return_void(size == 0, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th data size failed!\n", i); macro_svp_check_exps_return_void(size < (td_u64)task->cfg.dynamic_batch_num * total_line_num * stride, ENUM_SVP_ERR_LEVEL_ERROR, "%u-th data buffer size(%lu) is less than needed(%llu)!\n", i, size, (td_u64)task->cfg.dynamic_batch_num * total_line_num * stride); ret = snprintf_s(name, MACRO_SVP_NPU_MAX_NAME_LEN - 1, MACRO_SVP_NPU_MAX_NAME_LEN - 1, file_name, i); macro_svp_check_exps_return_void(ret < 0, ENUM_SVP_ERR_LEVEL_ERROR, "create file name failed!\n"); fp = fopen(name, "wb"); macro_svp_check_exps_return_void(fp == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "open file failed!\n"); for (line = 0; line < task->cfg.dynamic_batch_num * total_line_num; line++) { ret = fwrite(data, line_byte_num, 1, fp); if (ret != 1) { fclose(fp); macro_svp_check_exps_return_void(ret != 1, ENUM_SVP_ERR_LEVEL_ERROR, "write file failed!\n"); } data += stride; } (td_void)fclose(fp); } } td_void sample_common_svp_npu_dump_task_data(const struct_svp_npu_task_info *task) { if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return; } macro_svp_check_exps_return_void(task->input_dataset == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "task->input_dataset is NULL!\n"); macro_svp_check_exps_return_void(task->output_dataset == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "task->input_dataset is NULL!\n"); (td_void)sample_svp_npu_dump_dataset(task, "input_%u.bin", TD_TRUE); (td_void)sample_svp_npu_dump_dataset(task, "output_%u.bin", TD_FALSE); } td_s32 sample_common_svp_npu_update_input_data_buffer_info(td_u8 *virt_addr, td_u32 size, td_u32 stride, td_u32 idx, const struct_svp_npu_task_info *task) { svp_acl_data_buffer *data_buffer = TD_NULL; svp_acl_error ret; data_buffer = svp_acl_mdl_get_dataset_buffer(task->input_dataset, idx); macro_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get %u-th data_buffer failed!\n", idx); ret = svp_acl_update_data_buffer(data_buffer, (td_void *)virt_addr, size, stride); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "update data buffer failed!\n"); return TD_SUCCESS; } td_s32 sample_common_svp_npu_get_input_data_buffer_info(const struct_svp_npu_task_info *task, td_u32 idx, td_u8 **virt_addr, td_u32 *size, td_u32 *stride) { svp_acl_data_buffer *data_buffer = TD_NULL; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } macro_svp_check_exps_return(virt_addr == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "virt_addr is NULL!\n"); macro_svp_check_exps_return(size == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "size is NULL!\n"); macro_svp_check_exps_return(stride == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "size is NULL!\n"); data_buffer = svp_acl_mdl_get_dataset_buffer(task->input_dataset, idx); macro_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get 0-th data_buffer failed!\n"); *size = (td_u32)svp_acl_get_data_buffer_size(data_buffer); *stride = (td_u32)svp_acl_get_data_buffer_stride(data_buffer); *virt_addr = (td_u8 *)svp_acl_get_data_buffer_addr(data_buffer); return TD_SUCCESS; } static td_s32 sample_svp_npu_get_roi_num(const struct_svp_npu_task_info *task, struct_svp_npu_detection_info *info, ot_struct_svp_rect_info *rect_info) { svp_acl_error ret; size_t num_idx; svp_acl_mdl_io_dims dims; svp_acl_data_buffer *data_buffer = TD_NULL; td_float *data = TD_NULL; td_float total_num = 0.0; td_u32 start = 0; td_u32 i; ret = svp_acl_mdl_get_output_index_by_name(g_svp_npu_model[task->cfg.model_idx].model_desc, info->num_name, &num_idx); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get num idx failed!\n"); ret = svp_acl_mdl_get_output_dims(g_svp_npu_model[task->cfg.model_idx].model_desc, num_idx, &dims); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get num dims failed!\n"); data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, num_idx); macro_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get num data_buffer is NULL!\n"); data = (td_float *)svp_acl_get_data_buffer_addr(data_buffer); macro_svp_check_exps_return(data == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get num data is NULL!\n"); if (info->has_background == TD_TRUE) { info->roi_offset = (td_u32)(*data); start++; } for (i = start; i < dims.dims[dims.dim_count - 1]; i++) { total_num += *(data + i); } rect_info->num = (td_u32)total_num; return TD_SUCCESS; } static td_s32 sample_svp_npu_get_roi(const struct_svp_npu_task_info *task, const struct_svp_npu_detection_info *info, const ot_video_frame_info *proc_frame, const ot_video_frame_info *show_frame, ot_struct_svp_rect_info *rect_info) { svp_acl_error ret; size_t roi_idx, stride; svp_acl_data_buffer *data_buffer = TD_NULL; td_float *x_min = TD_NULL; td_float *y_min = TD_NULL; td_float *x_max = TD_NULL; td_float *y_max = TD_NULL; td_u32 roi_offset = info->roi_offset; td_u32 i; ret = svp_acl_mdl_get_output_index_by_name(g_svp_npu_model[task->cfg.model_idx].model_desc, info->roi_name, &roi_idx); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get roi idx failed!\n"); data_buffer = svp_acl_mdl_get_dataset_buffer(task->output_dataset, roi_idx); macro_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get roi data_buffer is NULL!\n"); stride = svp_acl_get_data_buffer_stride(data_buffer); macro_svp_check_exps_return(stride == 0, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get roi stride is 0!\n"); x_min = (td_float *)svp_acl_get_data_buffer_addr(data_buffer); macro_svp_check_exps_return(x_min == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get roi data is NULL!\n"); y_min = x_min + stride / sizeof(td_float); x_max = y_min + stride / sizeof(td_float); y_max = x_max + stride / sizeof(td_float); for (i = 0; i < rect_info->num; i++) { rect_info->rect[i].point[MACRO_SVP_NPU_RECT_LEFT_TOP].x = (td_u32)((td_float)x_min[roi_offset] / proc_frame->video_frame.width * show_frame->video_frame.width) & (~1); rect_info->rect[i].point[MACRO_SVP_NPU_RECT_LEFT_TOP].y = (td_u32)((td_float)y_min[roi_offset] / proc_frame->video_frame.height * show_frame->video_frame.height) & (~1); rect_info->rect[i].point[MACRO_SVP_NPU_RECT_RIGHT_TOP].x = (td_u32)((td_float)x_max[roi_offset] / proc_frame->video_frame.width * show_frame->video_frame.width) & (~1); rect_info->rect[i].point[MACRO_SVP_NPU_RECT_RIGHT_TOP].y = rect_info->rect[i].point[MACRO_SVP_NPU_RECT_LEFT_TOP].y; rect_info->rect[i].point[MACRO_SVP_NPU_RECT_RIGHT_BOTTOM].x = rect_info->rect[i].point[MACRO_SVP_NPU_RECT_RIGHT_TOP].x; rect_info->rect[i].point[MACRO_SVP_NPU_RECT_RIGHT_BOTTOM].y = (td_u32)((td_float)y_max[roi_offset] / proc_frame->video_frame.height * show_frame->video_frame.height) & (~1); rect_info->rect[i].point[MACRO_SVP_NPU_RECT_LEFT_BOTTOM].x = rect_info->rect[i].point[MACRO_SVP_NPU_RECT_LEFT_TOP].x; rect_info->rect[i].point[MACRO_SVP_NPU_RECT_LEFT_BOTTOM].y = rect_info->rect[i].point[MACRO_SVP_NPU_RECT_RIGHT_BOTTOM].y; roi_offset++; } return TD_SUCCESS; } td_s32 sample_common_svp_npu_roi_to_rect(const struct_svp_npu_task_info *task, struct_svp_npu_detection_info *detection_info, const ot_video_frame_info *proc_frame, const ot_video_frame_info *show_frame, ot_struct_svp_rect_info *rect_info) { td_s32 ret; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } macro_svp_check_exps_return(detection_info == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "detection_info is NULL!\n"); macro_svp_check_exps_return(proc_frame == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "proc_frame is NULL!\n"); macro_svp_check_exps_return(show_frame == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "show_frame is NULL!\n"); macro_svp_check_exps_return(rect_info == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "rect_info is NULL!\n"); detection_info->roi_offset = 0; ret = sample_svp_npu_get_roi_num(task, detection_info, rect_info); macro_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get roi num failed!\n"); ret = sample_svp_npu_get_roi(task, detection_info, proc_frame, show_frame, rect_info); macro_svp_check_exps_return(ret != TD_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get roi failed!\n"); return TD_SUCCESS; } td_s32 sample_common_svp_npu_set_threshold(struct_svp_npu_threshold threshold[], td_u32 threshold_num, const struct_svp_npu_task_info *task) { td_u32 i, n; svp_acl_error ret; svp_acl_data_buffer *data_buffer = TD_NULL; td_float *data = TD_NULL; size_t idx, size; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } macro_svp_check_exps_return(threshold == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "threshold is NULL!\n"); macro_svp_check_exps_return(threshold_num == 0, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "threshold_num is 0!\n"); for (i = 0; i < threshold_num; i++) { ret = svp_acl_mdl_get_input_index_by_name(g_svp_npu_model[task->cfg.model_idx].model_desc, threshold[i].name, &idx); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get roi idx failed!\n"); data_buffer = svp_acl_mdl_get_dataset_buffer(task->input_dataset, idx); macro_svp_check_exps_return(data_buffer == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get roi data_buffer is NULL!\n"); size = svp_acl_get_data_buffer_size(data_buffer); macro_svp_check_exps_return(size < MACRO_SVP_NPU_THRESHOLD_NUM * sizeof(td_float), TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get size(%lu) is less than %lu!\n", size, MACRO_SVP_NPU_THRESHOLD_NUM * sizeof(td_float)); data = (td_float *)svp_acl_get_data_buffer_addr(data_buffer); macro_svp_check_exps_return(data == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get roi data is NULL!\n"); n = 0; data[n++] = threshold[i].nms_threshold; data[n++] = threshold[i].score_threshold; data[n++] = threshold[i].min_height; data[n++] = threshold[i].min_width; } return TD_SUCCESS; } td_s32 sample_common_svp_npu_check_has_aicpu_task(const struct_svp_npu_task_info *task, td_bool *has_aicpu_task) { td_u32 aicpu_task_num; svp_acl_error ret; if (sample_svp_check_task_cfg(task) != TD_SUCCESS) { macro_svp_trace_err("check task cfg failed!\n"); return TD_FAILURE; } macro_svp_check_exps_return(has_aicpu_task == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "has_aicpu_task is NULL!\n"); ret = svp_acl_ext_get_mdl_aicpu_task_num(g_svp_npu_model[task->cfg.model_idx].model_id, &aicpu_task_num); macro_svp_check_exps_return(ret != SVP_ACL_SUCCESS, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR, "get aicpu task num failed, error code is %d!\n", ret); *has_aicpu_task = (aicpu_task_num == 0) ? TD_FALSE : TD_TRUE; return TD_SUCCESS; } struct_svp_npu_model_info* sample_common_svp_npu_get_model_info(td_u32 model_idx) { macro_svp_check_exps_return(model_idx >= MACRO_SVP_NPU_MAX_MODEL_NUM, NULL, ENUM_SVP_ERR_LEVEL_ERROR, "model_idx(%u) must be [0, %u)!\n", model_idx, MACRO_SVP_NPU_MAX_MODEL_NUM); return &g_svp_npu_model[model_idx]; }