Check failed: c‑>in_use() && (c‑>bin_num == kInvalidBinNum)

本文详细介绍了如何解决在使用TensorFlow时遇到的Checkfailed错误:c->in_use()&&(c->bin_num==kInvalidBinNum)。通过更新TensorFlow的non_max_suppression函数为non_max_suppression_v2,可以有效避免该问题的发生。

 

问题:Check failed: c‑>in_use() && (c‑>bin_num == kInvalidBinNum)

解决方案:


import tensorflow as tf

from tensorflow.python.ops import gen_image_ops

tf.image.non_max_suppression = gen_image_ops.non_max_suppression_v2
 

 

 

/****************************************************************************** Copyright © 2018-2018 TP-Link Systems Inc. Filename: httpd_utils.c Version: 1.0 Description: httpd 模块功能函数 Author: liyijieliyijie@tp-link.com.cn Date: 2018-9-10 ******************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <nvmp_common.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/time.h> #include <time.h> #ifdef MAKEROOM_BEFORE_UPGRADE #include <sys/reboot.h> #endif #include “http_utils.h” #include “http_parser.h” #include “http_special_request.h” #include “httpd.h” #define NONCE_LIFETIME 30 #define HEADER_SIZE 2 * 1024 #define HTTP_SEND_RETRY_INTERVAL 20000 #define HTTP_RECV_RETRY_INTERVAL 20000 #define HTTP_IMG_CATCH_TIME 120 #define HTTP_UPGRADE_TIMEOUT 30 #define HTTP_MAX_VIRTUAL_FILE 10 #define HTTP_UNAUTHORIZED 401 #define ERROR_CRYPTO_FAIL -1 #define ERROR_BUFFER_OVERFLOW -2 #define ESC_CHAR ‘%’ #define ESC_FIRST_CHAR ‘2’ #define ESC_SPACE ‘0’ #define ESC_PERCENT ‘5’ #define ESC_DOUBLE_QUOTE ‘2’ #define ESC_LEN 3 #define BEGIN_NUM ‘0’ #define END_NUM ‘9’ #define BEGIN_LOWERCASE ‘a’ #define END_LOWERCASE ‘z’ #define BEGIN_CAPITAL ‘A’ #define END_CAPITAL ‘Z’ #define END_LOWER_HEX ‘f’ #define END_UPPER_HEX ‘F’ #define TO_HEX_FIRST(x) ((x) / 16) > 9 ? (((x) / 16) + 55) : (((x) / 16) + 48); #define TO_HEX_SECOND(x) ((x) % 16) > 9 ? (((x) % 16) + 55) : (((x) % 16) + 48); LOCAL HTTP_ERROR_CODE g_http_err_code[] = { {HTTP_REQ_OK, “OK”}, {HTTP_MOVE_TEMPORARILY, “Moved Temporarily”}, {HTTP_NOT_MODIFIED, “Not Modified”}, {HTTP_BAD_REQUEST, “Bad Request”}, {HTTP_UNAUTHORIZED, “Unauthorized”}, {HTTP_FORBIDDEN, “Forbidden”}, {HTTP_NOT_FOUND, “Not Found”}, {HTTP_METHOD_NA, “Method Not Allowed”}, {HTTP_LENGTH_REQIRED, “Length Required”}, {HTTP_PRECOND_FAIL, “Precondition Failed”}, {HTTP_ENTITY_TOO_LARGE, “Request Entity Too Large”}, {HTTP_URI_TOO_LONG, “Request-URI Too Long”}, {HTTP_INTERNAL_ERROR, “Internal Server Error”}, {HTTP_NOT_IMPLEMENTED, “Not Implemented”}, {HTTP_SERV_UNAVAILABLE, “Service Unavailable”}, {HTTP_VERSION_NOT_SUPP, “HTTP Version not supported”}, {0, NULL} }; LOCAL char g_http_media_txt[HTTP_MEDIA_END][32] = { “text/html”, “x-bin/octet-stream”, “text/plain”, “text/html”, “text/html”, /* HTTP_MEDIA_LOG */ “text/html”, “text/xml”, “image/gif”, “image/jpeg”, “text/css”, “application/javascript”, “application/x-zip-compressed”, “application/json” }; extern UHTTPD_MAIN g_uhttp_main; char *http_get_err_str(U32 code) { U32 index = 0; while (NULL != g_http_err_code[index].value) { if (code == g_http_err_code[index].code) { return g_http_err_code[index].value; } index++; } return NULL; } LOCAL char *http_get_media_txt(CONTEXT *context) { if (NULL == context) { return NULL; } return g_http_media_txt[context->media_type]; } /* 发送数据在某些浏览器,如IE6.0~IE8.0中偶尔会出现发送不成功不成功的现象,在此处理 */ S32 http_send_block(void *ctx, const char *buffer, S32 send_len, S32 fail_max_time) { S32 length = 0; S32 fail_times = 0; S32 error = 0; CONTEXT *context = (CONTEXT *)ctx; while(fail_times < fail_max_time) { if (context->is_https == TRUE) { HTTPD_ERROR("Use HTTPS"); length = tpssl_writeSSL(context->ssl_ctx, buffer, send_len); if (length <= 0){ int err = tpssl_get_err(context->ssl_ctx, length); if ( err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE){ HTTPD_ERROR("tpssl_write error: %d\n", err); return -1; }else{ HTTPD_ERROR("no err, ret:%d\n", length); usleep(HTTP_SEND_RETRY_INTERVAL); fail_times++; continue; } } } else { HTTPD_ERROR("Use HTTP"); length = send(context->sock, buffer, send_len, 0); } if (length > 0) { break; } error = errno; if (error == EAGAIN || error == EINTR) { usleep(HTTP_SEND_RETRY_INTERVAL); fail_times++; } else { return HTTP_SEND_BLOCK_ERR; } } if (fail_times == fail_max_time) { HTTPD_ERROR("Http send timeout."); } return length; } /* 数据接收在某些浏览器,如IE6.0~IE8.0中偶尔会出现第一次接收不成功的现象,在此处理 */ S32 http_recv_block(void *ctx, char *buffer, int recv_len) { S32 length = 0; CONTEXT *context = (CONTEXT *)ctx; struct timeval last, now; /* 数据接收在IE6.0~IE8.0中偶尔会出现第一次接收不成功的现象,在此处理 */ if (context->is_https == TRUE) { if (context->is_upgrade == 1) { gettimeofday(&last, NULL); } readssl_again: length = tpssl_readSSL(context->ssl_ctx, buffer, recv_len); if (length <= 0) { int err = tpssl_get_err(context->ssl_ctx, length); if ( err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { HTTPD_ERROR(“tpssl_read error: %d\n”, err); return -1; } else { HTTPD_DEBUG(“no err, tpssl_get_err:%d, ret:%d\n”, err, length); #ifdef MAKEROOM_BEFORE_UPGRADE if (context->is_upgrade == 1) { gettimeofday(&now, NULL); if (now.tv_sec - last.tv_sec > HTTP_UPGRADE_TIMEOUT) { HTTPD_ERROR(“timeout! return error.”); return ERROR; } usleep(10); goto readssl_again; /* 固件升级保持阻塞方式读取 */ } else #endif { return RESERVE; } } } else { return length; } } else { length = recv(context->sock, buffer, recv_len, 0); } if (length == 0) { HTTPD_ERROR("recv length: %d\n", length); return ERROR; } if (length < 0) /* 接收数据失败。 */ { HTTPD_ERROR("recv length %d, errno %d\n", length, errno); if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) { return ERROR; } else { return RESERVE; } } return length; } /****************************************************************************** FUNCTION : DESCRIPTION : HTTP某个请求会话中负责发送响应数据的函数。 INPUT : OUTPUT : N/A RETURN : HISTORY : 把原发送缓存部分提出来单独成发送函数(即增加了一层发送处理函数), 以便异步发送时复用。 Create by luhan add 2015.12.23 *****************************************************************************/ S32 http_send_buffer(CONTEXT context, const char buffer, S32 send_len) { const char send_leave_buf = buffer; / 剩余要发送的缓存。/ S32 send_leave_buf_len = send_len; / 剩余要发送的缓存长度。/ S32 tmp_send_buf_len = 0; /S32 tmp_buf_len = NULL;/ BOOL is_need_asyn_send_flag = FALSE; S32 fail_max_time = HTTP_FAILED_MAXTIMES; if (NULL == context || NULL == buffer || send_len < 1) { return ERROR; } /* 是静态页面? 发送失败的话则使用异步发送机制。/ if ((HTTP_REQ_OK == context->code) && (context->media_type >= HTTP_MEDIA_INDEX && context->media_type <= HTTP_MEDIA_ZIP) && (strlen(context->path) > 0) / && (context->virt_file_index >= HTTP_MAX_VIRTUAL_FILE) /) { is_need_asyn_send_flag = TRUE; fail_max_time = HTTP_FAILED_MAXTIMES - 5; / 静态页面文件由于有了异步发送机制,则不用阻塞太久。*/ } /* 发送数据部分,如果有的话。 / while (send_leave_buf_len > 0) { / 计算一轮要发送的长度,最多4K。*/ tmp_send_buf_len = HTTP_SECTOR_SIZE; if (send_leave_buf_len < HTTP_SECTOR_SIZE) { tmp_send_buf_len = send_leave_buf_len; } tmp_send_buf_len = http_send_block(context, send_leave_buf, tmp_send_buf_len, fail_max_time); if (tmp_send_buf_len <= 0) { /* tcp reset 后将 timeout 设置为 0,在 context_check_timer 处释放 context */ if (tmp_send_buf_len == HTTP_SEND_BLOCK_ERR) { context->timeout = 0; return ERROR; } if (TRUE == is_need_asyn_send_flag) { if (context->async_buffer_len > send_leave_buf_len) { context->timeout = HTTP_CONTEXT_TIMEOUT; /* 有发送成功过,延长时间。*/ } /* 走到这里说明现在发送有失败了,存储未完成部分的静态文件的长度,稍后异步再继续发送。*/ context->async_buffer_len = send_leave_buf_len; return ERROR; } else { break; /* 非静态页面,发送失败的话直接不处理了。*/ } } send_leave_buf_len -= tmp_send_buf_len; send_leave_buf += tmp_send_buf_len; } context->async_buffer_len = 0; /* 发送完成,把需要发送的剩余文件长度置为0。*/ return OK; } /****************************************************************************** FUNCTION : DESCRIPTION : HTTP异步发送资源文件。 INPUT : OUTPUT : N/A RETURN : HISTORY : Create by luhan add 2015.12.28 ******************************************************************************/ S32 http_send_async_buffer(CONTEXT *context) { char *send_buffer = NULL; char *file_buffer = NULL; S32 fd = -1; S32 malloc_size = 0; S32 file_len = 0; if (context->async_buffer_len < 1) { return ERROR; } if ((context->rsp_file_stat.st_mode & S_IFREG) && ((fd = open(context->rsp_file_path, O_RDONLY)) > 0)) { file_len = context->rsp_file_stat.st_size; } /* 如果文件打不开,可能是找不到文件,也可能是文件解压失败,直接断开连接 */ else { return ERROR; } if (file_len < context->async_buffer_len) { return ERROR; } malloc_size = file_len + HTTP_CHUNK_BOU_LEN; /* 首先申请一段缓存。这里复用HTTP解析专用缓存。/ file_buffer = (char)NSD_MALLOC(malloc_size); if (NULL == file_buffer) { /* 一时申请不到内存,并不急于马上断开会话,先返回OK */ HTTPD_ERROR(“FAIL(async):alloc content error, no memory.”); return OK; } memset(file_buffer, 0, malloc_size); read(fd, file_buffer, malloc_size); /* 定位到要继续发送的位置。*/ send_buffer = file_buffer + (file_len - context->async_buffer_len); /* 继续发送出去。*/ http_send_buffer(context, send_buffer, context->async_buffer_len); /* 释放临时申请的内存块。*/ NSD_FREE(file_buffer); if (fd > 0) { close(fd); } return OK; } /****************************************************************************** fn nvmp_gen_rand_bytes brief Read a stream of bytes from /dev/urandom param[in] hex the address where the byte stream is saved param[in] len the number of bytes to be read return the actual number of bytes read ******************************************************************************/ int nvmp_gen_rand_bytes(unsigned char *hex, int len) { if (!hex || (len <= 0)) { return 0; } int total_bytes = 0; /* Number of bytes read */ struct stat b; static int nvmp_rand_fd = -2; /* init rand fd */ if (-2 == nvmp_rand_fd) { for (int i = 0; i < 5; i++) { if (!stat(“/dev/urandom”, &b) && (b.st_mode & S_IFCHR)) { nvmp_rand_fd = open(“/dev/urandom”, O_RDONLY); } if (nvmp_rand_fd >= 0) { break; } NVMP_PRINT(“/dev/urandom is NOT READY!\n”); sleep(1); } if (nvmp_rand_fd < 0) { nvmp_rand_fd = -1; } } /* read from /dev/urandom */ if (nvmp_rand_fd >= 0) { while (total_bytes < len) { int n = read(nvmp_rand_fd, hex + total_bytes, len - total_bytes); if (n <= 0) { break; } total_bytes += n; } if (total_bytes == len) { return len; } } /* use rand to pad when not fully read */ struct timeval tv = {0}; gettimeofday(&tv, NULL); srand(tv.tv_sec * tv.tv_usec + (unsigned int)(hex)); for (; total_bytes < len; ++total_bytes) { hex[total_bytes] = (char)(rand() & 0xFF); } return len; } S32 generate_digest_nonce(CONTEXT context) { / 数据源:时间戳+随机数 / struct { time_t timestamp; / 精确到秒的时间戳 / time_t expiration_time; / 过期时间 / unsigned char rand_bytes[16]; / 强随机数 */ } nonce_seed; /* 取当前时间戳 */ nonce_seed.timestamp = time(NULL); nonce_seed.expiration_time = nonce_seed.timestamp + NONCE_LIFETIME; /* 过期时间 */ /* 生成密码学强随机数 (使用RAND_bytes) */ if (0 == nvmp_gen_rand_bytes(nonce_seed.rand_bytes, sizeof(nonce_seed.rand_bytes))) { return ERROR_CRYPTO_FAIL; /* 随机数生成失败 */ } /* 转为十六进制字符串格式 */ char hex_buffer[2 * sizeof(nonce_seed) + 1]; const unsigned char *ptr = (const unsigned char *)&nonce_seed; for (size_t i = 0; i < sizeof(nonce_seed); i++) { snprintf(hex_buffer + 2*i, 3, "%02x", ptr[i]); } hex_buffer[2 * sizeof(nonce_seed)] = '\0'; /* 组合realm和hex_buffer生成nonce:realm:hex_buffer" */ int len = snprintf(context->digest_nonce, LEN_DIGEST_NONCE, "%s:%s", context->digest_realm, hex_buffer); if (len < 0 || len >= LEN_DIGEST_NONCE) { return ERROR_BUFFER_OVERFLOW; } return OK; } S32 http_send_rsp_header(CONTEXT *context) { S32 length = 0; S32 send_len = 0; char *file_name = NULL; char *http_err_str = NULL; U16 local_port = 0; NSD_ASSERT(NULL != context); /* 先封装头部。 */ http_err_str = http_get_err_str(context->code); if (NULL == http_err_str) { return ERROR; } char send_head_buf[HEADER_SIZE] = {0}; /*不能复用接受报文时的缓冲区*/ context->head_end = send_head_buf; context->head_buf_end = send_head_buf + sizeof(send_head_buf); /* Status-Line */ length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "HTTP/%s %03i %s\r\n", (context->version == HTTP_VERSION_1_0)?"1.0":"1.1", context->code, http_err_str); context->head_end+= length; context->header_len += length; /* ========== 新增Digest认证头 ========== */ if (HTTP_UNAUTHORIZED == context->code) { /* realm、opaque:自定义常量 */ strncpy(context->digest_realm, "TP-Link IP-Camera", sizeof(context->digest_realm) - 1); strncpy(context->digest_opaque, "64943214654649846565646421", sizeof(context->digest_opaque) - 1); /* 生成带时效的nonce */ if (generate_digest_nonce(context) != OK) { HTTPD_ERROR("generate_digest_nonce failed"); return ERROR; }else{ HTTPD_DEBUG("context->digest_nonce: %s", context->digest_nonce); } length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "WWW-Authenticate: Digest realm=\"%s\",algorithm=\"MD5\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"\r\n", context->digest_realm, context->digest_nonce, context->digest_opaque); /* 结束头部 */ context->head_end += length; context->header_len += length; } /* Connection */ #ifdef FAC_MODEL_ENABLE if(context->keepalive) { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), “Connection: %s\r\n”, “keep-alive”); } else #endif { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), “Connection: %s\r\n”, “close”); } context->head_end += length; context->header_len += length; /* ETag / if (context->etag[0] != ‘\0’) { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), “ETag: %s\r\n”, context->etag); context->head_end+= length; context->header_len += length; } / Last-Modified / if (context->last_modified[0] != ‘\0’) { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), “Last-Modified: %s\r\n”, context->last_modified); context->head_end += length; context->header_len += length; } / Cache-control / if ((HTTP_MEDIA_GIF == context->media_type) || (HTTP_MEDIA_JPEG == context->media_type)) { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), “Cache-control: max-age=%d\r\n”, HTTP_IMG_CATCH_TIME); context->head_end += length; context->header_len += length; } else { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), “Cache-Control: no-cache\r\n”); context->head_end += length; context->header_len += length; } #ifdef INCLUDE_UPNP_SERVER / UPnP扩展头部。 */ if (OK != http_make_extend_head(context)) { return ERROR; } #endif /* Location */ if (HTTP_MOVE_TEMPORARILY == context->code) { local_port = get_group_default_port(); length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Location: http://%s:%d\r\n", context->host, local_port); context->head_end += length; context->header_len += length; } /* Access-Control-Allow-Origin */ if (context->origin == TRUE) { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Access-Control-Allow-Origin: *\r\n"); context->head_end += length; context->header_len += length; } /* if have content */ if (context->content_len != 0) { /* Content-Type,filename 初始化为响应文件的路径 */ file_name = context->rsp_file_path; /* 修复在safari浏览器上保存的配置和日志都被保存为.html文件的问题 */ if ((TRUE == context->disposition) && (NULL != file_name) && /* (context->virt_file_index < HTTP_MAX_VIRTUAL_FILE) && */ ((0 == strcmp(file_name, CONFIG_FILE_PATH)) || (0 == strcmp(file_name, SYSLOG_FILE_PATH)) || (0 == strcmp(file_name, PLUGIN_DIR)))) { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Content-Type: application/octet-stream\r\n"); } else { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Content-Type: %s;charset=UTF-8\r\n", http_get_media_txt(context)); } context->head_end += length; context->header_len += length; /* Content-disposition */ //if ((TRUE == context->disposition) && // (context->virt_file_index < HTTP_MAX_VIRTUAL_FILE)) if (TRUE == context->disposition && NULL != file_name) { /* 去除文件的路径 */ file_name = strrchr(file_name, '/') + 1; length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Content-disposition: attachment;filename=\"%s\"\r\n", file_name); context->head_end += length; context->header_len += length; } /* 发送文件时,不使用chunked模块 */ if (TRUE == context->chunked && FALSE == context->rsp_file) { /* chunked */ length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Transfer-Encoding: chunked\r\n"); } else { /* Content-Length */ length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Content-Length: %d\r\n", context->content_len); } context->head_end += length; context->header_len += length; } /* close header */ length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "\r\n"); context->head_end += length; context->header_len += length; /* 发送头部。 */ send_len = http_send_block(context, send_head_buf, context->header_len, HTTP_FAILED_MAXTIMES); if (send_len <= 0) { /* tcp re set 后将 timeout 设置为 0,在 context_check_timer 处释放 context */ if (send_len == HTTP_SEND_BLOCK_ERR) { context->timeout = 0; } return ERROR; } return OK; } S32 http_send_rsp_content(CONTEXT *context) { U32 len = 0; U32 send_len = 0; char *ptr = NULL; NSD_ASSERT(NULL != context); if (NULL == context->content_buf || 0 == context->content_len) { return OK; } ptr = context->content_buf; while (context->content_len > 0) { send_len = min(context->content_len, HTTP_SECTOR_SIZE); len = http_send_block(context, ptr, send_len, HTTP_FAILED_MAXTIMES); if (len <= 0) { break; } context->content_len -= len; ptr += len; } return OK; } LOCAL BOOL is_num(char ch) { if (ch >= BEGIN_NUM && ch <= END_NUM) { return TRUE; } return FALSE; } LOCAL BOOL is_lowercase(char ch) { if (ch >= BEGIN_LOWERCASE && ch <= END_LOWERCASE) { return TRUE; } return FALSE; } LOCAL BOOL is_capital(char ch) { if (ch >= BEGIN_CAPITAL && ch <= END_CAPITAL) { return TRUE; } return FALSE; } LOCAL BOOL is_normal_char(char ch) { if (is_num(ch) == TRUE || is_lowercase(ch) == TRUE || is_capital(ch) == TRUE) { return TRUE; } return FALSE; } LOCAL BOOL is_hex_char(char ch) { if (is_num(ch) == TRUE || (ch >= BEGIN_CAPITAL && ch <= END_UPPER_HEX) || (ch >= BEGIN_LOWERCASE && ch <= END_LOWER_HEX)) { return TRUE; } return FALSE; } S32 model_encode_sc(const char* s_in, U32 s_in_len, char* s_out, U32 s_out_len) { U32 i = 0; U32 index = 0; if (NULL == s_in || NULL == s_out) { return ERROR; } for (i = 0; i < s_in_len; i++) { if(is_normal_char(s_in[i]) == TRUE && s_out_len > index + 1) { s_out[index++] = s_in[i]; } else if(s_out_len > index + ESC_LEN) { s_out[index++] = ESC_CHAR; s_out[index++] = TO_HEX_FIRST((U8)s_in[i]); s_out[index++] = TO_HEX_SECOND((U8)s_in[i]); } else { s_out[index] = '\0'; HTTPD_WARNING("output string don't have enough space!"); return ERROR; } } s_out[index] = '\0'; return OK; } S32 model_decode_sc(char *ptr_arg) { char *s_in = NULL; char *s_out = NULL; char tmp_buf[3] = {0}; if (NULL == ptr_arg) { return ERROR; } s_in = ptr_arg; s_out = ptr_arg; while (*s_in != '\0') { /*不是%的字符不需要进行转换*/ if(*s_in != '%') { *s_out++ = *s_in; s_in++; continue; } tmp_buf[0] = *(s_in + 1); if (!is_hex_char(tmp_buf[0])) { *s_out++ = *s_in; s_in++; continue; } tmp_buf[1] = *(s_in + 2); if (!is_hex_char(tmp_buf[1])) { *s_out++ = *s_in; *s_out++ = *(s_in + 1); s_in += 2; continue; } tmp_buf[2] = '\0'; *s_out++ = (char)strtol(tmp_buf, NULL, 16); s_in += 3; } *s_out = '\0'; return OK; } #ifdef MAKEROOM_BEFORE_UPGRADE /* 面向httpd的升级后延时重启 */ #define HTTPD_REBOOT_DELAY_SECOND 1 LOCAL void httpd_system_reboot_delay(S32 data) { int ret = reboot(RB_AUTOBOOT); if (ret) { ret = system(“reboot -f”); if (ret) { HTTPD_WARNING(“reboot -f fail!”); ret = system(“echo b 2>/dev/null > /proc/sysrq-trigger”); if (ret) { HTTPD_WARNING(“echo b 2>/dev/null > /proc/sysrq-trigger fail!”); } } } } S32 httpd_reboot_delay() { if (inet_add_timer(httpd_system_reboot_delay, 0, HTTPD_REBOOT_DELAY_SECOND, EXECUTE_SINGLE) == -1) { return ERROR; } return OK; } #endif
10-23
改写以下代码,将数据输入改为socket接收,模型推理输出改为socket发送:/** @brief Source file of vendor ai net sample code. @file ai_net_with_mblob.c @ingroup ai_net_sample @note Nothing. Copyright Novatek Microelectronics Corp. 2021. All rights reserved. */ /*-----------------------------------------------------------------------------*/ /* Including Files */ /*-----------------------------------------------------------------------------*/ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include "hdal.h" #include "hd_debug.h" #include "vendor_ai.h" #include "vendor_ai_cpu/vendor_ai_cpu.h" #include <sys/time.h> #if defined(_NVT_NVR_SDK_) #include <comm/nvtmem_if.h> #include <sys/ioctl.h> #endif #if defined(_BSP_NA51068_) || defined(_BSP_NA51090_) #include "vendor_common.h" #endif // platform dependent #if defined(__LINUX) #include <signal.h> #include <pthread.h> //for pthread API #define MAIN(argc, argv) int main(int argc, char** argv) #define GETCHAR() getchar() #else #include <FreeRTOS_POSIX.h> #include <FreeRTOS_POSIX/signal.h> #include <FreeRTOS_POSIX/pthread.h> //for pthread API #include <kwrap/util.h> //for sleep API #define sleep(x) vos_util_delay_ms(1000*(x)) #define msleep(x) vos_util_delay_ms(x) #define usleep(x) vos_util_delay_us(x) #include <kwrap/examsys.h> //for MAIN(), GETCHAR() API #define MAIN(argc, argv) EXAMFUNC_ENTRY(ai3_net_with_mblob, argc, argv) #define GETCHAR() NVT_EXAMSYS_GETCHAR() #endif #define DEBUG_MENU 1 #define DUMP_POSTPROC_INFO 1 #define DBG_OUT_DUMP 0 // debug mode, dump output iobuf #define FLOAT_IN 0 #define FLOAT_OUT 0 /////////////////////////////////////////////////////////////////////////////// #define NET_PATH_ID UINT32 #define VENDOR_AI_CFG 0x000f0000 //vendor ai config #define AI_RGB_BUFSIZE(w, h) (ALIGN_CEIL_4((w) * HD_VIDEO_PXLFMT_BPP(HD_VIDEO_PXLFMT_RGB888_PLANAR) / 8) * (h)) #define MULTI_BATCH_IN 0 #define CONFIG_INTERNAL_BUFFER 0 #define BATCH_SIZE 64 UINT32 g_proc_num=10; UINT32 dump_time_ut=0; UINT32 dump_time_proc=0; UINT32 dump_output=0; static UINT MPROCESS_FOR_AIISP =0; CHAR dump_path[256]; /////////////////////////////////////////////////////////////////////////////// /*-----------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------*/ typedef struct _MEM_PARM { UINTPTR pa; UINTPTR va; UINT32 size; UINTPTR blk; } MEM_PARM; /*-----------------------------------------------------------------------------*/ /* Global Functions */ /*-----------------------------------------------------------------------------*/ static HD_RESULT mem_alloc(MEM_PARM *mem_parm, CHAR* name, UINT32 size) { HD_RESULT ret = HD_OK; UINTPTR pa = 0; void *va = NULL; //alloc private pool ret = hd_common_mem_alloc(name, &pa, (void**)&va, size, DDR_ID0); if (ret!= HD_OK) { return ret; } mem_parm->pa = pa; mem_parm->va = (UINTPTR)va; mem_parm->size = size; mem_parm->blk = (UINTPTR)-1; return HD_OK; } static HD_RESULT mem_free(MEM_PARM *mem_parm) { HD_RESULT ret = HD_OK; //free private pool ret = hd_common_mem_free(mem_parm->pa, (void *)mem_parm->va); if (ret!= HD_OK) { return ret; } mem_parm->pa = 0; mem_parm->va = 0; mem_parm->size = 0; mem_parm->blk = (UINT32)-1; return HD_OK; } static INT32 mem_load(MEM_PARM *mem_parm, const CHAR *filename) { FILE *fd; INT32 size = 0; fd = fopen(filename, "rb"); if (!fd) { printf("cannot read %s\r\n", filename); size = -1; goto exit; } fseek(fd, 0, SEEK_END); size = ftell(fd); fseek(fd, 0, SEEK_SET); // check "ai_in_buf" enough or not if (mem_parm->size < (UINT32)size) { printf("ERROR: ai_in_buf(%u) is not enough, input file(%u)\r\n", mem_parm->size, (UINT32)size); size = -1; goto exit; } if (size < 0) { printf("getting %s size failed\r\n", filename); goto exit; } else if ((INT32)fread((VOID *)mem_parm->va, 1, size, fd) != size) { printf("read size < %d\r\n", size); size = -1; goto exit; } mem_parm->size = size; // we use cpu to read memory, which needs to deal cache flush. if(hd_common_mem_flush_cache((VOID *)mem_parm->va, mem_parm->size) != HD_OK) { printf("flush cache failed.\r\n"); } exit: if (fd) { fclose(fd); } return size; } /*-----------------------------------------------------------------------------*/ /* Input Functions */ /*-----------------------------------------------------------------------------*/ /////////////////////////////////////////////////////////////////////////////// typedef struct _NET_IN_CONFIG { CHAR input_filename[256]; UINT32 w; UINT32 h; UINT32 c; UINT32 b; UINT32 bitdepth; UINT32 loff; UINT32 fmt; UINT32 is_comb_img; // 1: image image (or feature-in) is a combination image (or feature-in). } NET_IN_CONFIG; typedef struct _NET_IN { NET_IN_CONFIG in_cfg; MEM_PARM input_mem; UINT32 in_id; VENDOR_AI3_BUF src_img; } NET_IN; static NET_IN *g_in = NULL; static UINT32 _calc_ai_buf_size(UINT32 loff, UINT32 h, UINT32 c, UINT32 b, UINT32 bitdepth, UINT32 fmt) { UINT size = 0; switch (fmt) { case HD_VIDEO_PXLFMT_YUV420: { size = loff * h * 3 / 2; } break; case HD_VIDEO_PXLFMT_RGB888_PLANAR: { size = AI_RGB_BUFSIZE(loff, h); } break; case HD_VIDEO_PXLFMT_BGR888_PLANAR: { size = AI_RGB_BUFSIZE(loff, h); } break; default: // feature-in { size = loff * h * c * bitdepth/8; } break; } if (!size) { printf("ERROR!! ai_buf size = 0\n"); } return size; } static HD_RESULT _load_buf(MEM_PARM *mem_parm, CHAR *filename, VENDOR_AI3_BUF *p_buf, UINT32 w, UINT32 h, UINT32 c, UINT32 b, UINT32 bitdepth, UINT32 loff, UINT32 fmt) { INT32 file_len; file_len = mem_load(mem_parm, filename); if (file_len < 0) { printf("load buf(%s) fail\r\n", filename); return HD_ERR_NG; } printf("load buf(%s) ok\r\n", filename); p_buf->width = w; p_buf->height = h; p_buf->channel = c; p_buf->batch_num = b; p_buf->line_ofs = loff; p_buf->fmt = fmt; p_buf->pa = mem_parm->pa; p_buf->va = mem_parm->va; p_buf->sign = MAKEFOURCC('A','B','U','F'); p_buf->size = _calc_ai_buf_size(loff, h, c, b, bitdepth, fmt); if (p_buf->size == 0) { printf("load buf(%s) fail, p_buf->size = 0\r\n", filename); return HD_ERR_NG; } return HD_OK; } static HD_RESULT input_init(void) { HD_RESULT ret = HD_OK; int i; for (i = 0; i < 16; i++) { NET_IN* p_net = g_in + i; p_net->in_id = i; } return ret; } static HD_RESULT input_uninit(void) { HD_RESULT ret = HD_OK; return ret; } static HD_RESULT input_set_config(NET_PATH_ID in_path, NET_IN_CONFIG* p_in_cfg) { HD_RESULT ret = HD_OK; NET_IN* p_net = g_in + in_path; UINT32 in_id = p_net->in_id; memcpy((void*)&p_net->in_cfg, (void*)p_in_cfg, sizeof(NET_IN_CONFIG)); printf("in_path(%u) in_id(%u) set in_cfg: file(%s), buf=(%u,%u,%u,%u,%u,%u,%08x)\r\n", in_path, in_id, p_net->in_cfg.input_filename, p_net->in_cfg.w, p_net->in_cfg.h, p_net->in_cfg.c, p_net->in_cfg.b, p_net->in_cfg.bitdepth, p_net->in_cfg.loff, p_net->in_cfg.fmt); return ret; } static HD_RESULT input_open(NET_PATH_ID in_path) { HD_RESULT ret = HD_OK; NET_IN* p_net = g_in + in_path; UINT32 in_id = p_net->in_id; UINT32 buf_size = 0; CHAR mem_name[23] ; snprintf(mem_name, 23, "ai_in_buf %u", in_id); // calculate in buf size buf_size = _calc_ai_buf_size(p_net->in_cfg.loff, p_net->in_cfg.h, p_net->in_cfg.c, p_net->in_cfg.b, p_net->in_cfg.bitdepth, p_net->in_cfg.fmt); if (buf_size == 0) { printf("in_path(%u) in_id(%u) size == 0 \r\n", in_path, in_id); return HD_ERR_FAIL; } // allocate in buf ret = mem_alloc(&p_net->input_mem, mem_name, buf_size * p_net->in_cfg.b); if (ret != HD_OK) { printf("in_path(%u) in_id(%u) alloc ai_in_buf fail\r\n", in_path, in_id); return HD_ERR_FAIL; } printf("alloc_in_buf: pa = 0x%lx, va = 0x%lx, size = %u\n", p_net->input_mem.pa, p_net->input_mem.va, p_net->input_mem.size); // load in buf ret = _load_buf(&p_net->input_mem, p_net->in_cfg.input_filename, &p_net->src_img, p_net->in_cfg.w, p_net->in_cfg.h, p_net->in_cfg.c, p_net->in_cfg.b, p_net->in_cfg.bitdepth, p_net->in_cfg.loff, p_net->in_cfg.fmt); if (ret != HD_OK) { printf("in_path(%u) in_id(%u) input_open fail=%d\n", in_path, in_id, ret); } return ret; } static HD_RESULT input_close(NET_PATH_ID in_path) { HD_RESULT ret = HD_OK; NET_IN* p_net = g_in + in_path; mem_free(&p_net->input_mem); return ret; } static HD_RESULT input_start(NET_PATH_ID in_path) { HD_RESULT ret = HD_OK; return ret; } static HD_RESULT input_stop(NET_PATH_ID in_path) { HD_RESULT ret = HD_OK; return ret; } static HD_RESULT input_pull_buf(NET_PATH_ID in_path, VENDOR_AI3_BUF *p_in, INT32 wait_ms) { HD_RESULT ret = HD_OK; NET_IN* p_net = g_in + in_path; memcpy((void*)p_in, (void*)&(p_net->src_img), sizeof(VENDOR_AI3_BUF)); return ret; } /////////////////////////////////////////////////////////////////////////////// /*-----------------------------------------------------------------------------*/ /* Network Functions */ /*-----------------------------------------------------------------------------*/ typedef struct _NET_PROC_CONFIG { CHAR model_filename[256]; INT32 binsize; void *p_share_model; CHAR label_filename[256]; } NET_PROC_CONFIG; typedef struct _NET_PROC { NET_PROC_CONFIG net_cfg; MEM_PARM proc_mem; UINT32 proc_id; //CHAR out_class_labels[MAX_CLASS_NUM * VENDOR_AIS_LBL_LEN]; MEM_PARM rslt_mem; MEM_PARM io_mem; MEM_PARM intl_mem; MEM_PARM *out_mem; VENDOR_AI3_NET_INFO net_info; } NET_PROC; static NET_PROC *g_net = NULL; static INT32 _getsize_model(char* filename) { FILE *bin_fd; UINT32 bin_size = 0; bin_fd = fopen(filename, "rb"); if (!bin_fd) { printf("get bin(%s) size fail\n", filename); return (-1); } fseek(bin_fd, 0, SEEK_END); bin_size = ftell(bin_fd); fseek(bin_fd, 0, SEEK_SET); fclose(bin_fd); return bin_size; } static UINT32 _load_model(CHAR *filename, UINTPTR va) { FILE *fd; UINT32 file_size = 0, read_size = 0; const UINTPTR model_addr = va; //DBG_DUMP("model addr = %#lx\r\n", model_addr); fd = fopen(filename, "rb"); if (!fd) { printf("load model(%s) fail\r\n", filename); return 0; } fseek ( fd, 0, SEEK_END ); file_size = ALIGN_CEIL_4( ftell(fd) ); fseek ( fd, 0, SEEK_SET ); read_size = fread ((void *)model_addr, 1, file_size, fd); if (read_size != file_size) { printf("size mismatch, real = %d, idea = %d\r\n", (int)read_size, (int)file_size); } fclose(fd); printf("load model(%s) ok\r\n", filename); return read_size; } /* static HD_RESULT _load_label(UINTPTR addr, UINT32 line_len, const CHAR *filename) { FILE *fd; CHAR *p_line = (CHAR *)addr; fd = fopen(filename, "r"); if (!fd) { printf("load label(%s) fail\r\n", filename); return HD_ERR_NG; } while (fgets(p_line, line_len, fd) != NULL) { p_line[strlen(p_line) - 1] = '\0'; // remove newline character p_line += line_len; } if (fd) { fclose(fd); } printf("load label(%s) ok\r\n", filename); return HD_OK; } */ static HD_RESULT network_init(void) { HD_RESULT ret = HD_OK; { VENDOR_AI3_DEV_CFG dev_cfg = {0}; ret = vendor_ai3_dev_init(&dev_cfg); if (ret != HD_OK) { printf("vendor_ai3_dev_init fail=%d\n", ret); return ret; } } // dump AI3 version { VENDOR_AI3_VER ai3_ver = {0}; ret = vendor_ai3_dev_get(VENDOR_AI3_CFG_VER, &ai3_ver); if (ret != HD_OK) { printf("vendor_ai3_dev_get(CFG_VER) fail=%d\n", ret); return ret; } printf("vendor_ai version = %s\r\n", ai3_ver.vendor_ai_impl_version); printf("kflow_ai version = %s\r\n", ai3_ver.kflow_ai_impl_version); printf("kdrv_ai version = %s\r\n", ai3_ver.kdrv_ai_impl_version); } return ret; } static HD_RESULT network_uninit(void) { HD_RESULT ret = HD_OK; ret = vendor_ai3_dev_uninit(); if (ret != HD_OK) { printf("vendor_ai3_dev_uninit fail=%d\n", ret); } return ret; } static INT32 network_mem_config(NET_PATH_ID net_path, HD_COMMON_MEM_INIT_CONFIG* p_mem_cfg, void* p_cfg) { NET_PROC* p_net = g_net + net_path; NET_PROC_CONFIG* p_proc_cfg = (NET_PROC_CONFIG*)p_cfg; #if defined(_NVT_NVR_SDK_) int sys_fd; struct nvtmem_hdal_base sys_hdal; uintptr_t hdal_start_addr0, hdal_start_addr1; sys_fd = open("/dev/nvtmem0", O_RDWR); if (sys_fd < 0) { printf("Error: cannot open /dev/nvtmem0 device.\n"); exit(0); } if (ioctl(sys_fd, NVTMEM_GET_DTS_HDAL_BASE, &sys_hdal) < 0) { printf("PCIE_SYS_IOC_HDALBASE! \n"); close(sys_fd); exit(0); } close(sys_fd); /* init ddr0 user_blk */ hdal_start_addr0 = sys_hdal.base[0]; p_mem_cfg->pool_info[0].start_addr = hdal_start_addr0; p_mem_cfg->pool_info[0].blk_cnt = 1; p_mem_cfg->pool_info[0].blk_size = 200 * 1024 * 1024; p_mem_cfg->pool_info[0].type = HD_COMMON_MEM_USER_BLK; p_mem_cfg->pool_info[0].ddr_id = sys_hdal.ddr_id[0]; printf("create ddr%d: hdal_memory(%#lx, %ldKB), usr_blk(%#lx, %dKB)\n", p_mem_cfg->pool_info[0].ddr_id, hdal_start_addr0, sys_hdal.size[0] / 1024, p_mem_cfg->pool_info[0].start_addr, p_mem_cfg->pool_info[0].blk_size * p_mem_cfg->pool_info[0].blk_cnt / 1024); /* init ddr1 user_blk, if ddr1 is exist */ if (sys_hdal.size[1] != 0) { hdal_start_addr1 = sys_hdal.base[1]; p_mem_cfg->pool_info[1].start_addr = hdal_start_addr1; p_mem_cfg->pool_info[1].blk_cnt = 1; p_mem_cfg->pool_info[1].blk_size = 200 * 1024 * 1024; p_mem_cfg->pool_info[1].type = HD_COMMON_MEM_USER_BLK; p_mem_cfg->pool_info[1].ddr_id = sys_hdal.ddr_id[1]; printf("create ddr%d: hdal_memory(%#lx, %ldKB) usr_blk(%#lx, %dKB)\n", p_mem_cfg->pool_info[1].ddr_id, hdal_start_addr1, sys_hdal.size[1] / 1024, p_mem_cfg->pool_info[1].start_addr, p_mem_cfg->pool_info[1].blk_size * p_mem_cfg->pool_info[1].blk_cnt / 1024); } else { printf("create ddr1: hdal_memory(%#lx, %ldKB) is not exist\n", sys_hdal.base[1], sys_hdal.size[1] / 1024); } usleep(30000); // wait for printf completely #endif memcpy((void*)&p_net->net_cfg, (void*)p_proc_cfg, sizeof(NET_PROC_CONFIG)); if (strlen(p_net->net_cfg.model_filename) == 0) { printf("net_path(%u) input model is null\r\n", net_path); return HD_ERR_NG; } p_net->net_cfg.binsize = _getsize_model(p_net->net_cfg.model_filename); if (p_net->net_cfg.binsize <= 0) { printf("net_path(%u) input model is not exist?\r\n", net_path); return HD_ERR_NG; } printf("net_path(%u) set net_mem_cfg: model-file(%s), binsize=%d\r\n", net_path, p_net->net_cfg.model_filename, p_net->net_cfg.binsize); printf("net_path(%u) set net_mem_cfg: label-file(%s)\r\n", net_path, p_net->net_cfg.label_filename); return HD_OK; } static HD_RESULT network_alloc_io_buf(NET_PATH_ID net_path, UINT32 req_size) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; CHAR mem_name[23] ; snprintf(mem_name, 23, "ai_io_buf %u", net_path); ret = mem_alloc(&p_net->io_mem, mem_name, req_size); if (ret != HD_OK) { printf("net_path(%u) alloc ai_io_buf fail\r\n", net_path); return HD_ERR_FAIL; } printf("alloc_io_buf: work buf, pa = %#lx, va = %#lx, size = %u\r\n", p_net->io_mem.pa, p_net->io_mem.va, p_net->io_mem.size); return ret; } static HD_RESULT network_free_io_buf(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; if (p_net->io_mem.pa && p_net->io_mem.va) { mem_free(&p_net->io_mem); } return ret; } static HD_RESULT network_alloc_intl_buf(NET_PATH_ID net_path, UINT32 req_size) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; CHAR mem_name[23] ; snprintf(mem_name, 23, "ai_ronly_buf %u", net_path); ret = mem_alloc(&p_net->intl_mem, mem_name, req_size); if (ret != HD_OK) { printf("net_path(%u) alloc ai_ronly_buf fail\r\n", net_path); return HD_ERR_FAIL; } printf("alloc_intl_buf: internal buf, pa = %#lx, va = %#lx, size = %u\r\n", p_net->intl_mem.pa, p_net->intl_mem.va, p_net->intl_mem.size); return ret; } static HD_RESULT network_free_intl_buf(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; if (p_net->intl_mem.pa && p_net->intl_mem.va) { mem_free(&p_net->intl_mem); } return ret; } static HD_RESULT network_open(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; UINT32 loadsize = 0; CHAR mem_name[23] ; snprintf(mem_name, 23, "model.bin %u", net_path); if (strlen(p_net->net_cfg.model_filename) == 0) { printf("net_path(%u) input model is null\r\n", net_path); return 0; } ret = mem_alloc(&p_net->proc_mem, mem_name, p_net->net_cfg.binsize); if (ret != HD_OK) { printf("net_path(%u) mem_alloc model.bin fail=%d\n", net_path, ret); return HD_ERR_FAIL; } //load file loadsize = _load_model(p_net->net_cfg.model_filename, p_net->proc_mem.va); if (loadsize <= 0) { printf("net_path(%u) input model load fail: %s\r\n", net_path, p_net->net_cfg.model_filename); return 0; } /* // load label ret = _load_label((UINTPTR)p_net->out_class_labels, VENDOR_AIS_LBL_LEN, p_net->net_cfg.label_filename); if (ret != HD_OK) { printf("proc_id(%u) load_label fail=%d\n", proc_id, ret); return HD_ERR_FAIL; } */ { VENDOR_AI3_MODEL_INFO model_info = {0}; model_info.model_buf.pa = p_net->proc_mem.pa; model_info.model_buf.va = p_net->proc_mem.va; model_info.model_buf.size = p_net->proc_mem.size; #if DBG_OUT_DUMP model_info.ctrl = CTRL_BUF_DEBUG | CTRL_JOB_DEBUG | CTRL_JOB_DUMPOUT; #endif #if FLOAT_IN model_info.ctrl = model_info.ctrl | CTRL_BUF_FLOATIN ; #endif #if FLOAT_OUT model_info.ctrl = model_info.ctrl | CTRL_BUF_FLOATOUT ; #endif printf("net_path(%u) vendor_ai3_dev_get(MODEL_INFO) \n", net_path); ret = vendor_ai3_dev_get(VENDOR_AI3_CFG_MODEL_INFO, &model_info); if (ret != HD_OK) { printf("net_path(%u) vendor_ai3_dev_get(MODEL_INFO) fail=%d\n", net_path, ret); return HD_ERR_FAIL; } printf("model_info get => workbuf size = %d, ronlybuf size = %d\r\n", model_info.proc_mem.buf[AI3_PROC_BUF_WORKBUF].size, model_info.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].size); // alloc WORKBUF/RONLYBUF ret = network_alloc_intl_buf(net_path, model_info.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].size); if (ret != HD_OK) { printf("net_path(%u) alloc ronlybuf fail=%d\n", net_path, ret); return HD_ERR_FAIL; } ret = network_alloc_io_buf(net_path, model_info.proc_mem.buf[AI3_PROC_BUF_WORKBUF].size); if (ret != HD_OK) { printf("net_path(%u) alloc workbuf fail=%d\n", net_path, ret); return HD_ERR_FAIL; } } // call open() { VENDOR_AI3_PROC_CFG proc_cfg = {0}; proc_cfg.model_buf.pa = p_net->proc_mem.pa; proc_cfg.model_buf.va = p_net->proc_mem.va; proc_cfg.model_buf.size = p_net->proc_mem.size; proc_cfg.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].pa = p_net->intl_mem.pa; proc_cfg.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].va = p_net->intl_mem.va; proc_cfg.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].size = p_net->intl_mem.size; proc_cfg.proc_mem.buf[AI3_PROC_BUF_WORKBUF].pa = p_net->io_mem.pa; proc_cfg.proc_mem.buf[AI3_PROC_BUF_WORKBUF].va = p_net->io_mem.va; proc_cfg.proc_mem.buf[AI3_PROC_BUF_WORKBUF].size = p_net->io_mem.size; proc_cfg.plugin[AI3_PLUGIN_CPU] = vendor_ai_cpu1_get_engine(); #if DBG_OUT_DUMP proc_cfg.ctrl = CTRL_BUF_DEBUG | CTRL_JOB_DEBUG | CTRL_JOB_DUMPOUT; #endif #if FLOAT_IN proc_cfg.ctrl = proc_cfg.ctrl | CTRL_BUF_FLOATIN ; #endif #if FLOAT_OUT proc_cfg.ctrl = proc_cfg.ctrl | CTRL_BUF_FLOATOUT ; #endif ret = vendor_ai3_net_open(&p_net->proc_id, &proc_cfg, &p_net->net_info); if (ret != HD_OK) { printf("net_path(%u) vendor_ai3_net_open() fail=%d\n", net_path, ret); return HD_ERR_FAIL; } else { printf("net_path(%u) open success => get proc_id(%u)\r\n", net_path, p_net->proc_id); } } return ret; } static HD_RESULT network_close(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; UINT32 proc_id = p_net->proc_id; UINT32 i ; // close ret = vendor_ai3_net_close(proc_id); if (ret != HD_OK) { printf("net_path(%u), proc_id(%u) vendor_ai3_net_close fail=%d\n", net_path, proc_id, ret); return HD_ERR_FAIL; } if ((ret = network_free_intl_buf(net_path)) != HD_OK) return ret; if ((ret = network_free_io_buf(net_path)) != HD_OK) return ret; mem_free(&p_net->proc_mem); for (i = 0 ; i < p_net->net_info.out_buf_cnt; i++){ if(p_net->out_mem && p_net->out_mem[i].va) mem_free(&p_net->out_mem[i]); } if(p_net->out_mem) free(p_net->out_mem) ; return ret; } #if DUMP_POSTPROC_INFO static HD_RESULT network_dump_ai_buf(VENDOR_AI3_BUF *p_outbuf) { HD_RESULT ret = HD_OK; printf(" sign(0x%x) pa(0x%lx) va(0x%lx) sz(%u) w(%u) h(%u) ch(%u) batch_num(%u)\n", p_outbuf->sign, p_outbuf->pa, p_outbuf->va, p_outbuf->size, p_outbuf->width, p_outbuf->height, p_outbuf->channel, p_outbuf->batch_num); printf(" l_ofs(%llu) c_ofs(%llu) b_ofs(%llu) t_ofs(%llu) layout(%s) name(%s) scale_ratio(%.6f)\n", p_outbuf->line_ofs, p_outbuf->channel_ofs, p_outbuf->batch_ofs, p_outbuf->time_ofs, p_outbuf->layout, p_outbuf->name, p_outbuf->scale_ratio); // parsing pixel format switch (AI_PXLFMT_TYPE(p_outbuf->fmt)) { case HD_VIDEO_PXLFMT_AI_UINT8: case HD_VIDEO_PXLFMT_AI_SINT8: case HD_VIDEO_PXLFMT_AI_UINT16: case HD_VIDEO_PXLFMT_AI_SINT16: case HD_VIDEO_PXLFMT_AI_UINT32: case HD_VIDEO_PXLFMT_AI_SINT32: case HD_VIDEO_PXLFMT_AI_FLOAT32: { INT8 bitdepth = HD_VIDEO_PXLFMT_BITS(p_outbuf->fmt); INT8 int_bits = HD_VIDEO_PXLFMT_INT(p_outbuf->fmt); INT8 frac_bits = HD_VIDEO_PXLFMT_FRAC(p_outbuf->fmt); printf(" fmt(0x%x) bits(%u) int(%u) frac(%u)\n", p_outbuf->fmt, bitdepth, int_bits, frac_bits); } break; default: switch ((UINT32)p_outbuf->fmt) { case HD_VIDEO_PXLFMT_BGR888_PLANAR: { printf(" fmt(0x%x), BGR888_PLANAR\n", p_outbuf->fmt); } break; case HD_VIDEO_PXLFMT_YUV420: { printf(" fmt(0x%x), YUV420\n", p_outbuf->fmt); } break; case HD_VIDEO_PXLFMT_Y8: { printf(" fmt(0x%x), Y8 only\n", p_outbuf->fmt); } break; case HD_VIDEO_PXLFMT_UV: { printf(" fmt(0x%x), UV only\n", p_outbuf->fmt); } break; case 0: { printf(" fmt(0x%x), AI BUF\n", p_outbuf->fmt); } break; default: printf("unknown pxlfmt(0x%x)\n", p_outbuf->fmt); break; } } printf("\n"); return ret; } /* static INT32 mem_save(MEM_PARM *mem_parm, const CHAR *filename) { FILE *fd; UINT32 size = 0; fd = fopen(filename, "wb"); if (!fd) { printf("ERR: cannot open %s for write!\r\n", filename); return -1; } size = (INT32)fwrite((VOID *)mem_parm->va, 1, mem_parm->size, fd); if (size != mem_parm->size) { printf("ERR: write %s with size %ld < wanted %ld?\r\n", filename, size, mem_parm->size); } else { printf("write %s with %ld bytes.\r\n", filename, mem_parm->size); } if (fd) { fclose(fd); } return size; } */ #endif /////////////////////////////////////////////////////////////////////////////// typedef struct _VIDEO_LIVEVIEW { // (1) input NET_IN_CONFIG net_in_cfg; NET_PATH_ID in_path; // (2) network NET_PROC_CONFIG net_proc_cfg; NET_PATH_ID net_path; pthread_t proc_thread_id; UINT32 proc_start; UINT32 proc_exit; UINT32 proc_oneshot; UINT32 input_blob_num; } VIDEO_LIVEVIEW; static HD_RESULT init_module(void) { HD_RESULT ret; if ((ret = input_init()) != HD_OK) return ret; if ((ret = network_init()) != HD_OK) return ret; return HD_OK; } static HD_RESULT open_module(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret; //if ((ret = input_open(p_stream->in_path)) != HD_OK) // return ret; if ((ret = network_open(p_stream->net_path)) != HD_OK) return ret; return HD_OK; } static HD_RESULT close_module(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret; //if ((ret = input_close(p_stream->in_path)) != HD_OK) // return ret; if ((ret = network_close(p_stream->net_path)) != HD_OK) return ret; return HD_OK; } static HD_RESULT exit_module(void) { HD_RESULT ret; if ((ret = input_uninit()) != HD_OK) return ret; if ((ret = network_uninit()) != HD_OK) return ret; return HD_OK; } static HD_RESULT perf_begin(void) { vendor_ai3_dev_perf_begin(VENDOR_AI3_PERF_ID_TIME_UT); return HD_OK; } static HD_RESULT perf_end(void) { UINT32 i; VENDOR_AI3_PERF_TIME_UT perf_time_ut = {0}; vendor_ai3_dev_perf_end(VENDOR_AI3_PERF_ID_TIME_UT, &perf_time_ut); printf("\r\n ************* util-per-proc() *************\r\n"); for (i=0; i<perf_time_ut.core_count; i++) { printf("%8s: time(us) = %6d, util(%%) = %6.2f\r\n", perf_time_ut.core[i].name, perf_time_ut.core[i].time, ((float)perf_time_ut.core[i].util)/100); } return HD_OK; } /////////////////////////////////////////////////////////////////////////////// static VOID *network_user_thread(VOID *arg); static HD_RESULT set_buf_by_in_path_list(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret = HD_OK; NET_PATH_ID net_path = p_stream->net_path; NET_PROC* p_net = g_net + net_path; VENDOR_AI3_NET_INFO net_info = p_net->net_info; VENDOR_AI3_BUF in_buf = {0}; VENDOR_AI3_BUF tmp_buf = {0}; UINT32 proc_id = p_net->proc_id; UINT32 i = 0, idx = 0, k = 0; UINT32 in_buf_cnt = 0; UINT32 *in_path_list = NULL; /* get in path list */ in_path_list = p_net->net_info.in_path_list; in_buf_cnt = net_info.in_buf_cnt; for (i = 0; i < in_buf_cnt; i++) { /* get in buf (by in path list) */ ret = vendor_ai3_net_get(proc_id, in_path_list[i], &tmp_buf); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) get in buf fail, i(%d), in_path(0x%x)\n",net_path, proc_id, i, in_path_list[i]); goto exit; } if (dump_output) { // dump in buf printf("dump_in_buf: path_id: 0x%x\n", in_path_list[i]); ret = network_dump_ai_buf(&tmp_buf); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) dump in buf fail !!\n", net_path, proc_id); goto exit; }} } for (i = 0; i < p_stream->input_blob_num; i++) { NET_IN* p_in = g_in + i; /* load input bin */ ret = input_pull_buf((p_stream->in_path + i), &in_buf, 0); if (HD_OK != ret) { printf("in_path(%u) pull input fail !!\n", (p_stream->in_path + i)); goto exit; } if (p_in->in_cfg.is_comb_img == 0) { for(k =1 ; k < in_buf.batch_num; k++) { UINTPTR dst_va = in_buf.va + (k * in_buf.size); memcpy((VOID*)dst_va , (VOID*)in_buf.va, in_buf.size); hd_common_mem_flush_cache((VOID *)dst_va, in_buf.size); } } //printf(" path_%d(0x%x) pa(0x%lx) va(0x%lx) size(%u)\n", idx, in_path_list[idx], in_buf.pa, in_buf.va, in_buf.size); ret = vendor_ai3_net_set(proc_id, in_path_list[idx], &in_buf); if (HD_OK != ret) { printf("proc_id(%u)push input fail !! i(%u)\n", proc_id, i); goto exit; } idx++; } exit: return ret; } static HD_RESULT set_buf_by_out_path_list(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; UINT32 proc_id = p_net->proc_id; UINT32 i; VENDOR_AI3_BUF ai_buf = {0}; /* get out buf */ for (i = 0; i < p_net->net_info.out_buf_cnt; i++) { // get out buf (by out path list) ret = vendor_ai3_net_get(proc_id, p_net->net_info.out_path_list[i], &ai_buf); if (HD_OK != ret) { printf("proc_id(%u) get out buf fail, i(%d), out_path(0x%x)\n", proc_id, i, p_net->net_info.out_path_list[i]); goto exit; } if (ai_buf.size > p_net->out_mem[i].size){ printf("output size %u < ai_buf.size %u\r\n", p_net->out_mem[i].size, ai_buf.size); goto exit; } ai_buf.va = p_net->out_mem[i].va ; ai_buf.pa = p_net->out_mem[i].pa ; ai_buf.size = p_net->out_mem[i].size ; #if FLOAT_OUT ai_buf.fmt = HD_VIDEO_PXLFMT_AI_FLOAT32; #endif ret = vendor_ai3_net_set(proc_id, p_net->net_info.out_path_list[i], &ai_buf); if (HD_OK != ret) { printf("proc_id(%u)set output buf fail !! (%u)\n", proc_id, i); goto exit; } } exit: return ret; } #if (1) static uintptr_t get_post_buf(uint32_t size) { uintptr_t buf = (uintptr_t)malloc(size); return buf; } static VOID release_post_buf(VOID *ptr) { if (ptr) { free(ptr); } return; } #endif #if(1) static HD_RESULT network_dump_out_buf(NET_PATH_ID net_path, VENDOR_AI3_BUF *p_outbuf, UINT32 id) { HD_RESULT ret = HD_OK; //NET_PROC *p_net = g_net + net_path; //INT32 i; //AI_NET_ACCURACY_PARM parm = {0}; //AI_NET_SHAPE shape = {p_outbuf->batch_num, p_outbuf->channel, 1, 1, 1}; //INT32 size = shape.num * shape.channels * shape.height * shape.width; UINT32 length = p_outbuf->batch_num * p_outbuf->channel * p_outbuf->height * p_outbuf->width; FLOAT *p_outbuf_float = (FLOAT *)get_post_buf(length * sizeof(FLOAT)); ret = vendor_ai_cpu_util_fixed2float((VOID *)p_outbuf->va, p_outbuf->fmt, p_outbuf_float, p_outbuf->scale_ratio, length, p_outbuf->zero_point); printf("id:%d size:%d name:%s\n", id, length, p_outbuf->name); #if (1) // save output float bin CHAR out_float_path[256] = {0}; sprintf(out_float_path, "%s/float_%s.bin", dump_path, p_outbuf->name); printf("out_float_path: %s\n", out_float_path); FILE* fp_out = NULL; if ((fp_out = fopen(out_float_path, "wb+")) == NULL) { printf("fopen fail\n"); } else { fwrite((VOID *)p_outbuf_float, sizeof(FLOAT), length, fp_out); //fwrite((VOID *)layer_buffer[i].va, sizeof(INT16), length, fp_out); } if(fp_out){ fclose(fp_out); } // save output fixed bin CHAR out_fixed_path[256] = {0}; sprintf(out_fixed_path, "%s/fixed_%s.bin", dump_path, p_outbuf->name); printf("out_fixed_path: %s\n", out_fixed_path); FILE* fp_out1 = NULL; if ((fp_out1 = fopen(out_fixed_path, "wb+")) == NULL) { printf("fopen fail\n"); } else { //fwrite((VOID *)p_outbuf_float, sizeof(FLOAT), length, fp_out1); fwrite((VOID *)p_outbuf->va, sizeof(INT16), length, fp_out1); } if(fp_out1){ fclose(fp_out1); } #endif /* INT32 *p_idx = (INT32 *)get_post_buf(p_outbuf->channel * sizeof(INT32)); AI_NET_OUTPUT_CLASSS *p_classes = (AI_NET_OUTPUT_CLASSS *)get_post_buf(p_outbuf->batch_num * TOP_N * sizeof(AI_NET_OUTPUT_CLASSS)); parm.in_addr = (uintptr_t)p_outbuf_float; parm.classes = p_classes; parm.shape = shape; parm.top_n = TOP_N; parm.class_idx = p_idx; ret = ai_net_accuracy_process(&parm); printf("Classification Results:\r\n"); for (i = 0; i < parm.top_n; i++) { printf("%d. no=%d, label=%s, score=%f\r\n", i + 1, parm.classes[i].no, &p_net->out_class_labels[parm.classes[i].no * LABEL_LEN], parm.classes[i].score); } */ release_post_buf(p_outbuf_float); //release_post_buf(p_idx); //release_post_buf(p_classes); return ret; } #endif static HD_RESULT get_buf_by_out_path_list(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; UINT32 proc_id = p_net->proc_id; UINT32 i; VENDOR_AI3_BUF ai_buf = {0}; printf("########### p_net->net_info.out_buf_cnt %d \r\n",p_net->net_info.out_buf_cnt); /* get out buf */ for (i = 0; i < p_net->net_info.out_buf_cnt; i++) { // get out buf (by out path list) ret = vendor_ai3_net_get(proc_id, p_net->net_info.out_path_list[i], &ai_buf); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) get out buf fail, i(%d), out_path(0x%x)\n", net_path, proc_id, i, p_net->net_info.out_path_list[i]); goto exit; } #if DUMP_POSTPROC_INFO { //CHAR dump_path[23]; // dump out buf if (hd_common_mem_flush_cache((VOID *)ai_buf.va, ai_buf.size) != HD_OK) { printf("flush cache failed.\r\n"); } printf("dump_out_buf: path_id: 0x%x\n", p_net->net_info.out_path_list[i]); ret = network_dump_ai_buf(&ai_buf); if (HD_OK != ret) { printf("net_path(%u) dump out buf fail !!\n", net_path); goto exit; } //snprintf(dump_path, 23, "%s.bin", ai_buf.name); //printf(" DUMP out_buf (%u): %s va = %lx\n", i, dump_path,(ULONG)p_net->out_mem[i].va); //mem_save(&p_net->out_mem[i], dump_path); ret = network_dump_out_buf(net_path, &ai_buf, i); } #endif } exit: return ret; } static HD_RESULT allocate_buf_by_out_path_list(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; UINT32 proc_id = p_net->proc_id; UINT32 i; VENDOR_AI3_BUF ai_buf = {0}; CHAR mem_name[23] ; /* get out path list */ p_net->out_mem = (MEM_PARM *)malloc(sizeof(MEM_PARM) * p_net->net_info.out_buf_cnt); memset(p_net->out_mem, 0, sizeof(MEM_PARM) * p_net->net_info.out_buf_cnt); /* get out buf */ for (i = 0; i < p_net->net_info.out_buf_cnt; i++) { // get out buf (by out path list) ret = vendor_ai3_net_get(proc_id, p_net->net_info.out_path_list[i], &ai_buf); if (HD_OK != ret) { printf("proc_id(%u) get out buf fail, i(%d), out_path(0x%x)\n", proc_id, i, p_net->net_info.out_path_list[i]); goto exit; } // // allocate in buf #if FLOAT_OUT ai_buf.size = ai_buf.width * ai_buf.height * ai_buf.channel * ai_buf.batch_num *sizeof(float) ; #endif snprintf(mem_name, 23, "output_buf %u", i); ret = mem_alloc(&p_net->out_mem[i], mem_name, ai_buf.size); if (ret != HD_OK) { printf("proc_id(%u) alloc ai_in_buf fail\r\n", proc_id); goto exit; } printf("alloc_outbuf: pa = 0x%lx, va = 0x%lx, size = %u\n", p_net->out_mem[i].pa, p_net->out_mem[i].va, p_net->out_mem[i].size); } return ret; exit: for (i = 0 ; i < p_net->net_info.out_buf_cnt; i++){ if(p_net->out_mem && p_net->out_mem[i].va) mem_free(&p_net->out_mem[i]); } if(p_net->out_mem) free(p_net->out_mem) ; return ret; } static HD_RESULT network_user_start(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + p_stream->net_path; UINT32 proc_id = p_net->proc_id; p_stream->proc_start = 0; p_stream->proc_exit = 0; p_stream->proc_oneshot = 0; ret = vendor_ai3_net_start(proc_id); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) vendor_ai3_net_start fail !!\n", p_stream->net_path, proc_id); } ret = pthread_create(&p_stream->proc_thread_id, NULL, network_user_thread, (VOID*)(p_stream)); if (ret < 0) { return HD_ERR_FAIL; } p_stream->proc_start = 1; p_stream->proc_exit = 0; p_stream->proc_oneshot = 0; return ret; } static HD_RESULT network_user_oneshot(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret = HD_OK; p_stream->proc_oneshot = 1; return ret; } static HD_RESULT network_user_stop(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + p_stream->net_path; UINT32 proc_id = p_net->proc_id; p_stream->proc_exit = 1; if (p_stream->proc_thread_id) { pthread_join(p_stream->proc_thread_id, NULL); } //stop: should be call after last time proc ret = vendor_ai3_net_stop(proc_id); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) vendor_ai3_net_stop fail !!\n", p_stream->net_path, proc_id); } return ret; } static VOID *network_user_thread(VOID *arg) { HD_RESULT ret = HD_OK; VIDEO_LIVEVIEW *p_stream = (VIDEO_LIVEVIEW*)arg; NET_PROC* p_net = g_net + p_stream->net_path; UINT32 proc_id = p_net->proc_id; static struct timeval tstart, tend; static UINT64 cur_time = 0; static UINT64 all_time = 0; static float mean_time = 0; UINT32 count=0; printf("\r\n"); while (p_stream->proc_start == 0) sleep(1); printf("\r\n"); while (p_stream->proc_exit == 0) { if (p_stream->proc_oneshot) { p_stream->proc_oneshot = 0; for (count=0;count<g_proc_num;count++) { // set buf by in_path_list ret = set_buf_by_in_path_list(p_stream); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) set in_buf fail(%d) !!\n", p_stream->net_path, proc_id, ret); goto skip; } ret = set_buf_by_out_path_list(p_stream->net_path); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) set in_buf fail(%d) !!\n", p_stream->net_path, proc_id, ret); goto skip; } // do net proc gettimeofday(&tstart, NULL); if(dump_time_ut){ perf_begin(); } ret = vendor_ai3_net_proc(proc_id); if(dump_time_ut){ perf_end(); } gettimeofday(&tend, NULL); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) proc fail !!\n", p_stream->net_path, proc_id); goto skip; } //count++; cur_time = (UINT64)(tend.tv_sec - tstart.tv_sec) * 1000000 + (tend.tv_usec - tstart.tv_usec); if(count>0){ all_time+=cur_time; mean_time=all_time/(float)(count); if (dump_time_proc){ printf("count %d cur time(us): %lld all time(us): %lld mean time(us): %f \r\n",count,cur_time,all_time,mean_time); } } // printf("net_path(%u), proc_id(%u) oneshot done!\n", p_stream->net_path, proc_id); // get buf by out_path_list if (dump_output) { /* code */ ret = get_buf_by_out_path_list(p_stream->net_path); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) get out_buf fail(%d) !!\n", p_stream->net_path, proc_id, ret); goto skip; } } } printf("count %d cur time(us): %lld all time(us): %lld mean time(us): %f \r\n",count,cur_time,all_time,mean_time); } usleep(100); } skip: return 0; } /*-----------------------------------------------------------------------------*/ /* Interface Functions */ /*-----------------------------------------------------------------------------*/ MAIN(argc, argv) { VIDEO_LIVEVIEW stream[1] = {0}; HD_COMMON_MEM_INIT_CONFIG mem_cfg = {0}; HD_RESULT ret; INT key; UINT32 j; INT32 idx; #if FLOAT_IN stream[0].input_blob_num = 1; //net_in NET_IN_CONFIG in_cfg = { .input_filename = "/mnt/sd/jpg/float32.bin", .w = 74, .h = 1, .c = 40, .b = 1, .bitdepth = 32, .loff = 296, .fmt = HD_VIDEO_PXLFMT_AI_FLOAT32, .is_comb_img = 1, }; NET_IN_CONFIG in_cfg2 = { .input_filename = "NULL", .w = 0, .h = 0, .c = 0, .b = 0, .bitdepth = 0, .loff = 0, .fmt = 0, .is_comb_img = 0, }; //net proc NET_PROC_CONFIG net_cfg = { .model_filename = "/mnt/sd/para/nvt_model_float32.bin", .label_filename = "/mnt/sd/accuracy/labels.txt" }; #elif MULTI_BATCH_IN /* multi-blob with multi-batch */ stream[0].input_blob_num = 2; //net_in NET_IN_CONFIG in_cfg = { .input_filename = "/mnt/sd/jpg/mblob_mbatch_0.yuv", .w = 12, .h = 12, .c = 2, .b = 8, .bitdepth = 8, .loff = 12, .fmt = HD_VIDEO_PXLFMT_YUV420, .is_comb_img = 1, }; NET_IN_CONFIG in_cfg2 = { .input_filename = "/mnt/sd/jpg/mblob_mbatch_1.bin", .w = 1, .h = 1, .c = 5, .b = 8, .bitdepth = 16, .loff = 2, .fmt = 0xA2101000, .is_comb_img = 1, }; //net proc NET_PROC_CONFIG net_cfg = { .model_filename = "/mnt/sd/para/nvt_model_mblob_mbatch.bin", .label_filename = "/mnt/sd/accuracy/labels.txt" }; #else stream[0].input_blob_num = 3; //net_in NET_IN_CONFIG in_cfg1 = { .input_filename = "/mnt/sd/jpg/mblob.bin", .w = 224, .h = 224, .c = 2, .b = 1, .bitdepth = 8, .loff = 224, .fmt = HD_VIDEO_PXLFMT_YUV420, .is_comb_img = 0, }; NET_IN_CONFIG in_cfg2 = { .input_filename = "/mnt/sd/jpg/mblob.bin", .w = 224, .h = 224, .c = 2, .b = 1, .bitdepth = 8, .loff = 224, .fmt = HD_VIDEO_PXLFMT_YUV420, .is_comb_img = 0, }; NET_IN_CONFIG in_cfg3 = { .input_filename = "/mnt/sd/jpg/mblob.bin", .w = 224, .h = 224, .c = 2, .b = 1, .bitdepth = 8, .loff = 224, .fmt = HD_VIDEO_PXLFMT_YUV420, .is_comb_img = 0, }; //net proc NET_PROC_CONFIG net_cfg = { .model_filename = "/mnt/sd/para/nvt_model_mblob.bin", .label_filename = "/mnt/sd/accuracy/labels.txt" }; #endif // End of #if MULTI_BATCH_IN if(argc < 4){ printf("usage : ai3_net_with_mblob (proc_num) (model_path) (input_blob_num)\n"); printf("usage : (MPROCESS_FOR_AIISP)\n"); printf("usage : (dump_time_UT)\n"); printf("usage : (dump_time_proc)\n"); printf("usage : (dump_output)\n"); printf("usage : (dump_path)\n"); printf("usage : (input_data_path1) (input_w) (input_h) (input_c) (input_b) (input_bitdepth) (input_loff) (input_fmt_10) (input_is_comb_img)\n"); printf("usage : (input_data_path2) (input_w) (input_h) (input_c) (input_b) (input_bitdepth) (input_loff) (input_fmt_10) (input_is_comb_img)\n"); printf("usage : (input_data_path2) (input_w) (input_h) (input_c) (input_b) (input_bitdepth) (input_loff) (input_fmt_10) (input_is_comb_img)\n"); return -1; } printf("\r\n\r\n"); idx = 1; UINT32 proc_num = 0; UINT32 input_blob_num = 0; { if (argc > idx) { sscanf(argv[idx++], "%d", &proc_num); printf("proc_num: %d\n", proc_num); g_proc_num=proc_num; } if (argc > idx) { sscanf(argv[idx++], "%s", net_cfg.model_filename); printf("net_cfg.model_filename: %s\n", net_cfg.model_filename); } if (argc > idx) { sscanf(argv[idx++], "%d", &input_blob_num); printf("input_blob_num: %d\n", input_blob_num); stream[0].input_blob_num=input_blob_num; } if (argc > idx) { sscanf(argv[idx++], "%d", &MPROCESS_FOR_AIISP); printf("MPROCESS_FOR_AIISP : %d\n", MPROCESS_FOR_AIISP); } if (argc > idx) { sscanf(argv[idx++], "%d", &dump_time_ut); printf("dump_time_ut: %d\n", dump_time_ut); } if (argc > idx) { sscanf(argv[idx++], "%d", &dump_time_proc); printf("dump_time_proc: %d\n", dump_time_proc); } if (argc > idx) { sscanf(argv[idx++], "%d", &dump_output); printf("dump_output: %d\n", dump_output); } if (argc > idx) { sscanf(argv[idx++], "%s", dump_path); printf("dump_path: %s\n", dump_path); } if (argc > idx) { sscanf(argv[idx++], "%s", in_cfg1.input_filename); printf("in_cfg1.input_filename: %s\n", in_cfg1.input_filename); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.w)); printf("(in_cfg1.w): %d\n", (in_cfg1.w)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.h)); printf("(in_cfg1.h): %d\n", (in_cfg1.h)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.c)); printf("(in_cfg1.c): %d\n", (in_cfg1.c)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.b)); printf("(in_cfg1.b): %d\n", (in_cfg1.b)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.bitdepth)); printf("(in_cfg1.bitdepth): %d\n", (in_cfg1.bitdepth)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.loff)); printf("(in_cfg1.loff): %d\n", (in_cfg1.loff)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.fmt)); printf("(in_cfg1.fmt): %d\n", (in_cfg1.fmt)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.is_comb_img)); printf("(in_cfg1.is_comb_img): %d\n", (in_cfg1.is_comb_img)); } if (argc > idx) { sscanf(argv[idx++], "%s", in_cfg2.input_filename); printf("in_cfg2.input_filename: %s\n", in_cfg2.input_filename); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.w)); printf("(in_cfg2.w): %d\n", (in_cfg2.w)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.h)); printf("(in_cfg2.h): %d\n", (in_cfg2.h)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.c)); printf("(in_cfg2.c): %d\n", (in_cfg2.c)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.b)); printf("(in_cfg2.b): %d\n", (in_cfg2.b)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.bitdepth)); printf("(in_cfg2.bitdepth): %d\n", (in_cfg2.bitdepth)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.loff)); printf("(in_cfg2.loff): %d\n", (in_cfg2.loff)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.fmt)); printf("(in_cfg2.fmt): %d\n", (in_cfg2.fmt)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.is_comb_img)); printf("(in_cfg2.is_comb_img): %d\n", (in_cfg2.is_comb_img)); } // cfg3 if (argc > idx) { sscanf(argv[idx++], "%s", in_cfg3.input_filename); printf("in_cfg3.input_filename: %s\n", in_cfg3.input_filename); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.w)); printf("(in_cfg3.w): %d\n", (in_cfg3.w)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.h)); printf("(in_cfg3.h): %d\n", (in_cfg3.h)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.c)); printf("(in_cfg3.c): %d\n", (in_cfg3.c)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.b)); printf("(in_cfg3.b): %d\n", (in_cfg3.b)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.bitdepth)); printf("(in_cfg3.bitdepth): %d\n", (in_cfg3.bitdepth)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.loff)); printf("(in_cfg3.loff): %d\n", (in_cfg3.loff)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.fmt)); printf("(in_cfg3.fmt): %d\n", (in_cfg3.fmt)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.is_comb_img)); printf("(in_cfg3.is_comb_img): %d\n", (in_cfg3.is_comb_img)); } } // malloc for g_in & g_net g_in = (NET_IN *)malloc(sizeof(NET_IN)*16); g_net = (NET_PROC *)malloc(sizeof(NET_PROC)*16); if ((g_in == NULL) || (g_net == NULL)) { printf("fail to malloc g_in/g_net\n"); goto exit; } stream[0].in_path = 0; stream[0].net_path = 0; // init hdal if(MPROCESS_FOR_AIISP){ ret = hd_common_init(1); // multi-process for aiisp }else{ ret = hd_common_init(0); } //this is no longer need in 690 /* #if defined(_BSP_NS02201_) || defined(_BSP_NS02302_) // set project config for AI hd_common_sysconfig(0, (1<<16), 0, VENDOR_AI_CFG); //enable AI engine #endif */ // init mem { // config common pool network_mem_config(stream[0].net_path, &mem_cfg, &net_cfg); } #if defined(_BSP_NS02201_) || defined(_BSP_NS02302_) if(MPROCESS_FOR_AIISP){ ret = hd_common_mem_init(NULL); // multi-process for aiisp }else{ ret = hd_common_mem_init(&mem_cfg); } if (HD_OK != ret) { printf("hd_common_mem_init err: %d\r\n", ret); goto exit; } #endif // init all modules ret = init_module(); if (ret != HD_OK) { printf("init fail=%d\n", ret); goto exit; } // set open config for (j=0; j < stream[0].input_blob_num; j++) { if (j == 0) { ret = input_set_config((stream[0].in_path + j), &in_cfg1); } else if (j == 1) { ret = input_set_config((stream[0].in_path + j), &in_cfg2); } else if (j == 2) { ret = input_set_config((stream[0].in_path + j), &in_cfg3); } if (HD_OK != ret) { printf("in_path(%u) input_set_config fail=%d\n", (stream[0].in_path + j), ret); goto exit; } } // open video_liveview modules for(j=0; j < stream[0].input_blob_num; j++) { ret = input_open((stream[0].in_path + j)); if (ret != HD_OK) { printf("in_path(%u) input open fail=%d\n", (stream[0].in_path + j), ret); goto exit; } } ret = open_module(&stream[0]); if (ret != HD_OK) { printf("open fail=%d\n", ret); goto exit; } // start input_start(stream[0].in_path); network_user_start(&stream[0]); allocate_buf_by_out_path_list(stream[0].net_path); do { printf("Enter q to exit, r to run once\n"); key = GETCHAR(); if (key == 'r') { // run once network_user_oneshot(&stream[0]); continue; } if (key == 'q' || key == 0x3) { break; } } while(1); // stop input_stop(stream[0].in_path); network_user_stop(&stream[0]); exit: // close video_liveview modules ret = close_module(&stream[0]); if (ret != HD_OK) { printf("close fail=%d\n", ret); } for(j=0; j < stream[0].input_blob_num; j++) { ret = input_close((stream[0].in_path + j)); if (ret != HD_OK) { printf("in_path(%u) input close fail=%d\n", (stream[0].in_path + j), ret); goto exit; } } // uninit all modules ret = exit_module(); if (ret != HD_OK) { printf("exit fail=%d\n", ret); } #if defined(_BSP_NS02201_) || defined(_BSP_NS02302_) // uninit memory ret = hd_common_mem_uninit(); if (ret != HD_OK) { printf("mem fail=%d\n", ret); } #endif // uninit hdal ret = hd_common_uninit(); if (ret != HD_OK) { printf("common fail=%d\n", ret); } // free g_in & g_net if (g_in) free(g_in); if (g_net) free(g_net); return ret; }
最新发布
11-04
/****************************************************************************** * Copyright (c) 2018-2018 TP-Link Systems Inc. * * Filename: httpd_utils.c * Version: 1.0 * Description: httpd 模块功能函数 * Author: liyijie<liyijie@tp-link.com.cn> * Date: 2018-9-10 ******************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <nvmp_common.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/time.h> #include <time.h> #ifdef MAKEROOM_BEFORE_UPGRADE #include <sys/reboot.h> #endif #include "http_utils.h" #include "http_parser.h" #include "http_special_request.h" #include "httpd.h" #define NONCE_LIFETIME 30 #define HEADER_SIZE 2 * 1024 #define HTTP_SEND_RETRY_INTERVAL 20000 #define HTTP_RECV_RETRY_INTERVAL 20000 #define HTTP_IMG_CATCH_TIME 120 #define HTTP_UPGRADE_TIMEOUT 30 #define HTTP_MAX_VIRTUAL_FILE 10 #define HTTP_UNAUTHORIZED 401 #define ERROR_CRYPTO_FAIL -1 #define ERROR_BUFFER_OVERFLOW -2 #define ESC_CHAR '%' #define ESC_FIRST_CHAR '2' #define ESC_SPACE '0' #define ESC_PERCENT '5' #define ESC_DOUBLE_QUOTE '2' #define ESC_LEN 3 #define BEGIN_NUM '0' #define END_NUM '9' #define BEGIN_LOWERCASE 'a' #define END_LOWERCASE 'z' #define BEGIN_CAPITAL 'A' #define END_CAPITAL 'Z' #define END_LOWER_HEX 'f' #define END_UPPER_HEX 'F' #define TO_HEX_FIRST(x) ((x) / 16) > 9 ? (((x) / 16) + 55) : (((x) / 16) + 48); #define TO_HEX_SECOND(x) ((x) % 16) > 9 ? (((x) % 16) + 55) : (((x) % 16) + 48); LOCAL HTTP_ERROR_CODE g_http_err_code[] = { {HTTP_REQ_OK, "OK"}, {HTTP_MOVE_TEMPORARILY, "Moved Temporarily"}, {HTTP_NOT_MODIFIED, "Not Modified"}, {HTTP_BAD_REQUEST, "Bad Request"}, {HTTP_UNAUTHORIZED, "Unauthorized"}, {HTTP_FORBIDDEN, "Forbidden"}, {HTTP_NOT_FOUND, "Not Found"}, {HTTP_METHOD_NA, "Method Not Allowed"}, {HTTP_LENGTH_REQIRED, "Length Required"}, {HTTP_PRECOND_FAIL, "Precondition Failed"}, {HTTP_ENTITY_TOO_LARGE, "Request Entity Too Large"}, {HTTP_URI_TOO_LONG, "Request-URI Too Long"}, {HTTP_INTERNAL_ERROR, "Internal Server Error"}, {HTTP_NOT_IMPLEMENTED, "Not Implemented"}, {HTTP_SERV_UNAVAILABLE, "Service Unavailable"}, {HTTP_VERSION_NOT_SUPP, "HTTP Version not supported"}, {0, NULL} }; LOCAL char g_http_media_txt[HTTP_MEDIA_END][32] = { "text/html", "x-bin/octet-stream", "text/plain", "text/html", "text/html", /* HTTP_MEDIA_LOG */ "text/html", "text/xml", "image/gif", "image/jpeg", "text/css", "application/javascript", "application/x-zip-compressed", "application/json" }; extern UHTTPD_MAIN g_uhttp_main; char *http_get_err_str(U32 code) { U32 index = 0; while (NULL != g_http_err_code[index].value) { if (code == g_http_err_code[index].code) { return g_http_err_code[index].value; } index++; } return NULL; } LOCAL char *http_get_media_txt(CONTEXT *context) { if (NULL == context) { return NULL; } return g_http_media_txt[context->media_type]; } /* 发送数据在某些浏览器,如IE6.0~IE8.0中偶尔会出现发送不成功不成功的现象,在此处理 */ S32 http_send_block(void *ctx, const char *buffer, S32 send_len, S32 fail_max_time) { S32 length = 0; S32 fail_times = 0; S32 error = 0; CONTEXT *context = (CONTEXT *)ctx; while(fail_times < fail_max_time) { if (context->is_https == TRUE) { HTTPD_ERROR("Use HTTPS"); length = tpssl_writeSSL(context->ssl_ctx, buffer, send_len); if (length <= 0){ int err = tpssl_get_err(context->ssl_ctx, length); if ( err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE){ HTTPD_ERROR("tpssl_write error: %d\n", err); return -1; }else{ HTTPD_ERROR("no err, ret:%d\n", length); usleep(HTTP_SEND_RETRY_INTERVAL); fail_times++; continue; } } } else { HTTPD_ERROR("Use HTTP"); length = send(context->sock, buffer, send_len, 0); } if (length > 0) { break; } error = errno; if (error == EAGAIN || error == EINTR) { usleep(HTTP_SEND_RETRY_INTERVAL); fail_times++; } else { return HTTP_SEND_BLOCK_ERR; } } if (fail_times == fail_max_time) { HTTPD_ERROR("Http send timeout."); } return length; } /* 数据接收在某些浏览器,如IE6.0~IE8.0中偶尔会出现第一次接收不成功的现象,在此处理 */ S32 http_recv_block(void *ctx, char *buffer, int recv_len) { S32 length = 0; CONTEXT *context = (CONTEXT *)ctx; struct timeval last, now; /* 数据接收在IE6.0~IE8.0中偶尔会出现第一次接收不成功的现象,在此处理 */ if (context->is_https == TRUE) { if (context->is_upgrade == 1) { gettimeofday(&last, NULL); } readssl_again: length = tpssl_readSSL(context->ssl_ctx, buffer, recv_len); if (length <= 0) { int err = tpssl_get_err(context->ssl_ctx, length); if ( err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { HTTPD_ERROR("tpssl_read error: %d\n", err); return -1; } else { HTTPD_DEBUG("no err, tpssl_get_err:%d, ret:%d\n", err, length); #ifdef MAKEROOM_BEFORE_UPGRADE if (context->is_upgrade == 1) { gettimeofday(&now, NULL); if (now.tv_sec - last.tv_sec > HTTP_UPGRADE_TIMEOUT) { HTTPD_ERROR("timeout! return error."); return ERROR; } usleep(10); goto readssl_again; /* 固件升级保持阻塞方式读取 */ } else #endif { return RESERVE; } } } else { return length; } } else { length = recv(context->sock, buffer, recv_len, 0); } if (length == 0) { HTTPD_ERROR("recv length: %d\n", length); return ERROR; } if (length < 0) /* 接收数据失败。 */ { HTTPD_ERROR("recv length %d, errno %d\n", length, errno); if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) { return ERROR; } else { return RESERVE; } } return length; } /****************************************************************************** * FUNCTION : * DESCRIPTION : HTTP某个请求会话中负责发送响应数据的函数。 * INPUT : * OUTPUT : N/A * RETURN : * HISTORY : * 把原发送缓存部分提出来单独成发送函数(即增加了一层发送处理函数), * 以便异步发送时复用。 * Create by luhan add 2015.12.23 ******************************************************************************/ S32 http_send_buffer(CONTEXT *context, const char *buffer, S32 send_len) { const char *send_leave_buf = buffer; /* 剩余要发送的缓存。*/ S32 send_leave_buf_len = send_len; /* 剩余要发送的缓存长度。*/ S32 tmp_send_buf_len = 0; /*S32 tmp_buf_len = NULL;*/ BOOL is_need_asyn_send_flag = FALSE; S32 fail_max_time = HTTP_FAILED_MAXTIMES; if (NULL == context || NULL == buffer || send_len < 1) { return ERROR; } /* 是静态页面? 发送失败的话则使用异步发送机制。*/ if ((HTTP_REQ_OK == context->code) && (context->media_type >= HTTP_MEDIA_INDEX && context->media_type <= HTTP_MEDIA_ZIP) && (strlen(context->path) > 0) /* && (context->virt_file_index >= HTTP_MAX_VIRTUAL_FILE) */) { is_need_asyn_send_flag = TRUE; fail_max_time = HTTP_FAILED_MAXTIMES - 5; /* 静态页面文件由于有了异步发送机制,则不用阻塞太久。*/ } /* 发送数据部分,如果有的话。 */ while (send_leave_buf_len > 0) { /* 计算一轮要发送的长度,最多4K。*/ tmp_send_buf_len = HTTP_SECTOR_SIZE; if (send_leave_buf_len < HTTP_SECTOR_SIZE) { tmp_send_buf_len = send_leave_buf_len; } tmp_send_buf_len = http_send_block(context, send_leave_buf, tmp_send_buf_len, fail_max_time); if (tmp_send_buf_len <= 0) { /* tcp reset 后将 timeout 设置为 0,在 context_check_timer 处释放 context */ if (tmp_send_buf_len == HTTP_SEND_BLOCK_ERR) { context->timeout = 0; return ERROR; } if (TRUE == is_need_asyn_send_flag) { if (context->async_buffer_len > send_leave_buf_len) { context->timeout = HTTP_CONTEXT_TIMEOUT; /* 有发送成功过,延长时间。*/ } /* 走到这里说明现在发送有失败了,存储未完成部分的静态文件的长度,稍后异步再继续发送。*/ context->async_buffer_len = send_leave_buf_len; return ERROR; } else { break; /* 非静态页面,发送失败的话直接不处理了。*/ } } send_leave_buf_len -= tmp_send_buf_len; send_leave_buf += tmp_send_buf_len; } context->async_buffer_len = 0; /* 发送完成,把需要发送的剩余文件长度置为0。*/ return OK; } /****************************************************************************** * FUNCTION : * DESCRIPTION : HTTP异步发送资源文件。 * INPUT : * OUTPUT : N/A * RETURN : * HISTORY : * Create by luhan add 2015.12.28 ******************************************************************************/ S32 http_send_async_buffer(CONTEXT *context) { char *send_buffer = NULL; char *file_buffer = NULL; S32 fd = -1; S32 malloc_size = 0; S32 file_len = 0; if (context->async_buffer_len < 1) { return ERROR; } if ((context->rsp_file_stat.st_mode & S_IFREG) && ((fd = open(context->rsp_file_path, O_RDONLY)) > 0)) { file_len = context->rsp_file_stat.st_size; } /* 如果文件打不开,可能是找不到文件,也可能是文件解压失败,直接断开连接 */ else { return ERROR; } if (file_len < context->async_buffer_len) { return ERROR; } malloc_size = file_len + HTTP_CHUNK_BOU_LEN; /* 首先申请一段缓存。这里复用HTTP解析专用缓存。*/ file_buffer = (char*)NSD_MALLOC(malloc_size); if (NULL == file_buffer) { /* 一时申请不到内存,并不急于马上断开会话,先返回OK */ HTTPD_ERROR("FAIL(async):alloc content error, no memory."); return OK; } memset(file_buffer, 0, malloc_size); read(fd, file_buffer, malloc_size); /* 定位到要继续发送的位置。*/ send_buffer = file_buffer + (file_len - context->async_buffer_len); /* 继续发送出去。*/ http_send_buffer(context, send_buffer, context->async_buffer_len); /* 释放临时申请的内存块。*/ NSD_FREE(file_buffer); if (fd > 0) { close(fd); } return OK; } /****************************************************************************** * fn nvmp_gen_rand_bytes * brief Read a stream of bytes from /dev/urandom * param[in] hex the address where the byte stream is saved * param[in] len the number of bytes to be read * return the actual number of bytes read ******************************************************************************/ int nvmp_gen_rand_bytes(unsigned char *hex, int len) { if (!hex || (len <= 0)) { return 0; } int total_bytes = 0; /* Number of bytes read */ struct stat b; static int nvmp_rand_fd = -2; /* init rand fd */ if (-2 == nvmp_rand_fd) { for (int i = 0; i < 5; i++) { if (!stat("/dev/urandom", &b) && (b.st_mode & S_IFCHR)) { nvmp_rand_fd = open("/dev/urandom", O_RDONLY); } if (nvmp_rand_fd >= 0) { break; } NVMP_PRINT("/dev/urandom is NOT READY!\n"); sleep(1); } if (nvmp_rand_fd < 0) { nvmp_rand_fd = -1; } } /* read from /dev/urandom */ if (nvmp_rand_fd >= 0) { while (total_bytes < len) { int n = read(nvmp_rand_fd, hex + total_bytes, len - total_bytes); if (n <= 0) { break; } total_bytes += n; } if (total_bytes == len) { return len; } } /* use rand to pad when not fully read */ struct timeval tv = {0}; gettimeofday(&tv, NULL); srand(tv.tv_sec * tv.tv_usec + (unsigned int)(hex)); for (; total_bytes < len; ++total_bytes) { hex[total_bytes] = (char)(rand() & 0xFF); } return len; } S32 generate_digest_nonce(CONTEXT *context) { /* 数据源:时间戳+随机数 */ struct { time_t timestamp; /* 精确到秒的时间戳 */ time_t expiration_time; /* 过期时间 */ unsigned char rand_bytes[16]; /* 强随机数 */ } nonce_seed; /* 取当前时间戳 */ nonce_seed.timestamp = time(NULL); nonce_seed.expiration_time = nonce_seed.timestamp + NONCE_LIFETIME; /* 过期时间 */ /* 生成密码学强随机数 (使用RAND_bytes) */ if (0 == nvmp_gen_rand_bytes(nonce_seed.rand_bytes, sizeof(nonce_seed.rand_bytes))) { return ERROR_CRYPTO_FAIL; /* 随机数生成失败 */ } /* 转为十六进制字符串格式 */ char hex_buffer[2 * sizeof(nonce_seed) + 1]; const unsigned char *ptr = (const unsigned char *)&nonce_seed; for (size_t i = 0; i < sizeof(nonce_seed); i++) { snprintf(hex_buffer + 2*i, 3, "%02x", ptr[i]); } hex_buffer[2 * sizeof(nonce_seed)] = '\0'; /* 组合realm和hex_buffer生成nonce:realm:hex_buffer" */ int len = snprintf(context->digest_nonce, LEN_DIGEST_NONCE, "%s:%s", context->digest_realm, hex_buffer); if (len < 0 || len >= LEN_DIGEST_NONCE) { return ERROR_BUFFER_OVERFLOW; } return OK; } S32 http_send_rsp_header(CONTEXT *context) { S32 length = 0; S32 send_len = 0; char *file_name = NULL; char *http_err_str = NULL; U16 local_port = 0; NSD_ASSERT(NULL != context); /* 先封装头部。 */ http_err_str = http_get_err_str(context->code); if (NULL == http_err_str) { return ERROR; } char send_head_buf[HEADER_SIZE] = {0}; /*不能复用接受报文时的缓冲区*/ context->head_end = send_head_buf; context->head_buf_end = send_head_buf + sizeof(send_head_buf); /* Status-Line */ length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "HTTP/%s %03i %s\r\n", (context->version == HTTP_VERSION_1_0)?"1.0":"1.1", context->code, http_err_str); context->head_end+= length; context->header_len += length; /* ========== 新增Digest认证头 ========== */ if (HTTP_UNAUTHORIZED == context->code) { /* realm、opaque:自定义常量 */ strncpy(context->digest_realm, "TP-Link IP-Camera", sizeof(context->digest_realm) - 1); strncpy(context->digest_opaque, "64943214654649846565646421", sizeof(context->digest_opaque) - 1); /* 生成带时效的nonce */ if (generate_digest_nonce(context) != OK) { HTTPD_ERROR("generate_digest_nonce failed"); return ERROR; }else{ HTTPD_DEBUG("context->digest_nonce: %s", context->digest_nonce); } length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "WWW-Authenticate: Digest realm=\"%s\",algorithm=\"MD5\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"\r\n", context->digest_realm, context->digest_nonce, context->digest_opaque); /* 结束头部 */ context->head_end += length; context->header_len += length; } /* Connection */ #ifdef FAC_MODEL_ENABLE if(context->keepalive) { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Connection: %s\r\n", "keep-alive"); } else #endif { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Connection: %s\r\n", "close"); } context->head_end += length; context->header_len += length; /* ETag */ if (context->etag[0] != '\0') { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "ETag: %s\r\n", context->etag); context->head_end+= length; context->header_len += length; } /* Last-Modified */ if (context->last_modified[0] != '\0') { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Last-Modified: %s\r\n", context->last_modified); context->head_end += length; context->header_len += length; } /* Cache-control */ if ((HTTP_MEDIA_GIF == context->media_type) || (HTTP_MEDIA_JPEG == context->media_type)) { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Cache-control: max-age=%d\r\n", HTTP_IMG_CATCH_TIME); context->head_end += length; context->header_len += length; } else { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Cache-Control: no-cache\r\n"); context->head_end += length; context->header_len += length; } #ifdef INCLUDE_UPNP_SERVER /* UPnP扩展头部。 */ if (OK != http_make_extend_head(context)) { return ERROR; } #endif /* Location */ if (HTTP_MOVE_TEMPORARILY == context->code) { local_port = get_group_default_port(); length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Location: http://%s:%d\r\n", context->host, local_port); context->head_end += length; context->header_len += length; } /* Access-Control-Allow-Origin */ if (context->origin == TRUE) { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Access-Control-Allow-Origin: *\r\n"); context->head_end += length; context->header_len += length; } /* if have content */ if (context->content_len != 0) { /* Content-Type,filename 初始化为响应文件的路径 */ file_name = context->rsp_file_path; /* 修复在safari浏览器上保存的配置和日志都被保存为.html文件的问题 */ if ((TRUE == context->disposition) && (NULL != file_name) && /* (context->virt_file_index < HTTP_MAX_VIRTUAL_FILE) && */ ((0 == strcmp(file_name, CONFIG_FILE_PATH)) || (0 == strcmp(file_name, SYSLOG_FILE_PATH)) || (0 == strcmp(file_name, PLUGIN_DIR)))) { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Content-Type: application/octet-stream\r\n"); } else { length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Content-Type: %s;charset=UTF-8\r\n", http_get_media_txt(context)); } context->head_end += length; context->header_len += length; /* Content-disposition */ //if ((TRUE == context->disposition) && // (context->virt_file_index < HTTP_MAX_VIRTUAL_FILE)) if (TRUE == context->disposition && NULL != file_name) { /* 去除文件的路径 */ file_name = strrchr(file_name, '/') + 1; length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Content-disposition: attachment;filename=\"%s\"\r\n", file_name); context->head_end += length; context->header_len += length; } /* 发送文件时,不使用chunked模块 */ if (TRUE == context->chunked && FALSE == context->rsp_file) { /* chunked */ length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Transfer-Encoding: chunked\r\n"); } else { /* Content-Length */ length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "Content-Length: %d\r\n", context->content_len); } context->head_end += length; context->header_len += length; } /* close header */ length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "\r\n"); context->head_end += length; context->header_len += length; /* 发送头部。 */ send_len = http_send_block(context, send_head_buf, context->header_len, HTTP_FAILED_MAXTIMES); if (send_len <= 0) { /* tcp re set 后将 timeout 设置为 0,在 context_check_timer 处释放 context */ if (send_len == HTTP_SEND_BLOCK_ERR) { context->timeout = 0; } return ERROR; } return OK; } S32 http_send_rsp_content(CONTEXT *context) { U32 len = 0; U32 send_len = 0; char *ptr = NULL; NSD_ASSERT(NULL != context); if (NULL == context->content_buf || 0 == context->content_len) { return OK; } ptr = context->content_buf; while (context->content_len > 0) { send_len = min(context->content_len, HTTP_SECTOR_SIZE); len = http_send_block(context, ptr, send_len, HTTP_FAILED_MAXTIMES); if (len <= 0) { break; } context->content_len -= len; ptr += len; } return OK; } LOCAL BOOL is_num(char ch) { if (ch >= BEGIN_NUM && ch <= END_NUM) { return TRUE; } return FALSE; } LOCAL BOOL is_lowercase(char ch) { if (ch >= BEGIN_LOWERCASE && ch <= END_LOWERCASE) { return TRUE; } return FALSE; } LOCAL BOOL is_capital(char ch) { if (ch >= BEGIN_CAPITAL && ch <= END_CAPITAL) { return TRUE; } return FALSE; } LOCAL BOOL is_normal_char(char ch) { if (is_num(ch) == TRUE || is_lowercase(ch) == TRUE || is_capital(ch) == TRUE) { return TRUE; } return FALSE; } LOCAL BOOL is_hex_char(char ch) { if (is_num(ch) == TRUE || (ch >= BEGIN_CAPITAL && ch <= END_UPPER_HEX) || (ch >= BEGIN_LOWERCASE && ch <= END_LOWER_HEX)) { return TRUE; } return FALSE; } S32 model_encode_sc(const char* s_in, U32 s_in_len, char* s_out, U32 s_out_len) { U32 i = 0; U32 index = 0; if (NULL == s_in || NULL == s_out) { return ERROR; } for (i = 0; i < s_in_len; i++) { if(is_normal_char(s_in[i]) == TRUE && s_out_len > index + 1) { s_out[index++] = s_in[i]; } else if(s_out_len > index + ESC_LEN) { s_out[index++] = ESC_CHAR; s_out[index++] = TO_HEX_FIRST((U8)s_in[i]); s_out[index++] = TO_HEX_SECOND((U8)s_in[i]); } else { s_out[index] = '\0'; HTTPD_WARNING("output string don't have enough space!"); return ERROR; } } s_out[index] = '\0'; return OK; } S32 model_decode_sc(char *ptr_arg) { char *s_in = NULL; char *s_out = NULL; char tmp_buf[3] = {0}; if (NULL == ptr_arg) { return ERROR; } s_in = ptr_arg; s_out = ptr_arg; while (*s_in != '\0') { /*不是%的字符不需要进行转换*/ if(*s_in != '%') { *s_out++ = *s_in; s_in++; continue; } tmp_buf[0] = *(s_in + 1); if (!is_hex_char(tmp_buf[0])) { *s_out++ = *s_in; s_in++; continue; } tmp_buf[1] = *(s_in + 2); if (!is_hex_char(tmp_buf[1])) { *s_out++ = *s_in; *s_out++ = *(s_in + 1); s_in += 2; continue; } tmp_buf[2] = '\0'; *s_out++ = (char)strtol(tmp_buf, NULL, 16); s_in += 3; } *s_out = '\0'; return OK; } #ifdef MAKEROOM_BEFORE_UPGRADE /* 面向httpd的升级后延时重启 */ #define HTTPD_REBOOT_DELAY_SECOND 1 LOCAL void httpd_system_reboot_delay(S32 data) { int ret = reboot(RB_AUTOBOOT); if (ret) { ret = system("reboot -f"); if (ret) { HTTPD_WARNING("reboot -f fail!"); ret = system("echo b 2>/dev/null > /proc/sysrq-trigger"); if (ret) { HTTPD_WARNING("echo b 2>/dev/null > /proc/sysrq-trigger fail!"); } } } } S32 httpd_reboot_delay() { if (inet_add_timer(httpd_system_reboot_delay, 0, HTTPD_REBOOT_DELAY_SECOND, EXECUTE_SINGLE) == -1) { return ERROR; } return OK; } #endif
10-23
将代码中的输入改为通过socket接收(参考代码中的receive_data_via_socket()函数),输出改为通过socket发送(参考代码中的send_data_via_socket()函数)。将只执行一次的逻辑(proc_oneshot)改成持续执行接收来自socket的数据:/** @brief Source file of vendor ai net sample code. @file ai_net_with_mblob.c @ingroup ai_net_sample @note Nothing. Copyright Novatek Microelectronics Corp. 2021. All rights reserved. */ /*-----------------------------------------------------------------------------*/ /* Including Files */ /*-----------------------------------------------------------------------------*/ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include "hdal.h" #include "hd_debug.h" #include "vendor_ai.h" #include "vendor_ai_cpu/vendor_ai_cpu.h" #include <sys/time.h> #if defined(_NVT_NVR_SDK_) #include <comm/nvtmem_if.h> #include <sys/ioctl.h> #endif #if defined(_BSP_NA51068_) || defined(_BSP_NA51090_) #include "vendor_common.h" #endif // platform dependent #if defined(__LINUX) #include <signal.h> #include <pthread.h> //for pthread API #define MAIN(argc, argv) int main(int argc, char** argv) #define GETCHAR() getchar() #else #include <FreeRTOS_POSIX.h> #include <FreeRTOS_POSIX/signal.h> #include <FreeRTOS_POSIX/pthread.h> //for pthread API #include <kwrap/util.h> //for sleep API #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #define sleep(x) vos_util_delay_ms(1000*(x)) #define msleep(x) vos_util_delay_ms(x) #define usleep(x) vos_util_delay_us(x) #include <kwrap/examsys.h> //for MAIN(), GETCHAR() API #define MAIN(argc, argv) EXAMFUNC_ENTRY(ai3_net_with_mblob, argc, argv) #define GETCHAR() NVT_EXAMSYS_GETCHAR() #endif #define DEBUG_MENU 1 #define DUMP_POSTPROC_INFO 1 #define DBG_OUT_DUMP 0 // debug mode, dump output iobuf #define FLOAT_IN 0 #define FLOAT_OUT 0 /////////////////////////////////////////////////////////////////////////////// #define NET_PATH_ID UINT32 #define VENDOR_AI_CFG 0x000f0000 //vendor ai config #define AI_RGB_BUFSIZE(w, h) (ALIGN_CEIL_4((w) * HD_VIDEO_PXLFMT_BPP(HD_VIDEO_PXLFMT_RGB888_PLANAR) / 8) * (h)) #define MULTI_BATCH_IN 0 #define CONFIG_INTERNAL_BUFFER 0 #define OUTPUT 1 // 是否输出,debug用 #define BATCH_SIZE 64 UINT32 g_proc_num=10; UINT32 dump_time_ut=0; UINT32 dump_time_proc=0; UINT32 dump_output=0; static UINT MPROCESS_FOR_AIISP =0; CHAR dump_path[256]; /////////////////////////////////////////////////////////////////////////////// /*-----------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------*/ typedef struct _MEM_PARM { UINTPTR pa; UINTPTR va; UINT32 size; UINTPTR blk; } MEM_PARM; /*-----------------------------------------------------------------------------*/ /* Global Functions */ /*-----------------------------------------------------------------------------*/ static HD_RESULT receive_data_via_socket(NET_PROC *p_net, int sockfd, UINT32 input_cnt) { HD_RESULT ret = HD_OK; UINT32 i; for (i = 0; i < p_net->net_info.in_buf_cnt; i++) { // 接收输入数据长度 UINT32 data_size = p_net -> in_buf[i].size; // 预期输入数据大小 size_t total_recevied = 0; size_t remaining = data_size; // 剩余需要接收的 //char *data_buffer = (char *)p_net->in_buf[i].va; uintptr_t data_buffer = p_net -> in_buf[i].va; // MEM_PARM mem_parm; // mem_parm.va = p_net->in_buf[i].va; // 超时退出设置 struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv)); while (remaining > 0) { ssize_t bytes_received = recv(sockfd, (void *)(data_buffer + total_recevied), remaining, 0); if (bytes_received <= 0){ if (bytes_received == 0) { printf("Client closed connection during data transfer\n"); return HD_ERR_USER; } else if (errno == EAGAIN || errno == EWOULDBLOCK) { printf("Socket receive timeout\n"); return HD_ERR_TIMEDOUT; } else { perror("recv error during data transfer \n"); return HD_ERR_USER; } } total_recevied += bytes_received; remaining -= bytes_received; } if (input_cnt == 0) // 只在第一次打印此信息 { printf("\n Received input %d data via socket, size: %u bytes\n", i, data_size); } } return ret; } #if OUTPUT==1 /** * @brief 通过Socket发送输出结果 * @param p_net 网络处理结构体指针 * @param sockfd Socket文件描述符 * @return HD_RESULT 操作结果 */ static HD_RESULT send_data_via_socket(NET_PROC *p_net, int sockfd, UINT32 input_cnt, char* out_print) { HD_RESULT ret = HD_OK; UINT32 outlay_num = p_net->net_info.out_buf_cnt; LONG total_size = 0; VENDOR_AI3_BUF ai_buf = {0}; if (out_print == NULL) { printf("out_print malloc size fail \n"); return HD_ERR_FAIL; } // total_size += sprintf(out_print + total_size, "input index %u\n", input_cnt); /* 格式化输出结果 */ for (UINT32 i=0; i < outlay_num; i++) { ret = vendor_ai3_net_get(p_net->proc_id, p_net->net_info.out_path_list[i], &ai_buf); UINT32 out_length = ai_buf.time * ai_buf.batch_num * ai_buf.channel * ai_buf.height * ai_buf.width; // 输出数据量 // /* 新增文件写入部分 */ FILE *fp = fopen("output.bin", "wb+"); // 以二进制写入模式打开文件 if (fp == NULL) { perror("Error opening file"); // 输出错误信息 return HD_ERR_FAIL; // 返回错误码 } size_t written = fwrite((void *)p_net->out_mem_float[i].va, sizeof(FLOAT), out_length, fp); // 写入文件 printf("output ai buf size:%d, out length:%d \n", ai_buf.size, out_length); if (written != out_length) { perror("Error writing to file"); // 输出写入错误 fclose(fp); return HD_ERR_FAIL; } fclose(fp); // 关闭文件 if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) get out buf fail, i(%d), out_path(0x%x)\n", p_net->net_id, p_net->proc_id, i, p_net->net_info.out_path_list[i]); return ret; } if (input_cnt == 1 && i % dump_mean_time_freq == 0) { printf("#######output_size:%u\n", out_length); } FLOAT *curr_layer_float_ptr =(FLOAT *)p_net->out_mem_float[i].va; for (UINT32 k = 0; k < out_length-1; k++) { // 2025.10.21新增:多batch时需要每行只输出一个样本的结果 if ((k+1) % (ai_buf.time * ai_buf.channel * ai_buf.height * ai_buf.width) == 0 && ai_buf.batch_num != 1) { total_size += sprintf(out_print + total_size, "%f\n", *(curr_layer_float_ptr+k)); } else { total_size += sprintf(out_print + total_size, "%f ", *(curr_layer_float_ptr+k)); } //total_size += sprintf(out_print + total_size, "%f ", *(curr_layer_float_ptr+k)); } total_size += sprintf(out_print + total_size, "%f\n", *(curr_layer_float_ptr+(out_length-1))); } write(sockfd, out_print, total_size); // 释放内存 // for (UINT32 i = 0; i < outlay_num; i++) // { // free(outlayer_float[i]); // outlayer_float[i] = NULL; // } // free(outlayer_float); // outlayer_float = NULL; return ret; } #endif /** * @brief 设置Socket服务器 * @return int 监听Socket的文件描述符 */ static int setup_socket_server(void) { int server_fd; struct sockaddr_in address; int opt = 1; // 创建Socket文件描述符 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 设置Socket选项 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt failed"); close(server_fd); exit(EXIT_FAILURE); } // 绑定地址和端口 address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(SOCKET_PORT); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); close(server_fd); exit(EXIT_FAILURE); } // 开始监听 if (listen(server_fd, MAX_CLIENTS) < 0) { perror("listen failed"); close(server_fd); exit(EXIT_FAILURE); } printf("Socket server listening on port %d\n", SOCKET_PORT); return server_fd; } static HD_RESULT mem_alloc(MEM_PARM *mem_parm, CHAR* name, UINT32 size) { HD_RESULT ret = HD_OK; UINTPTR pa = 0; void *va = NULL; //alloc private pool ret = hd_common_mem_alloc(name, &pa, (void**)&va, size, DDR_ID0); if (ret!= HD_OK) { return ret; } mem_parm->pa = pa; mem_parm->va = (UINTPTR)va; mem_parm->size = size; mem_parm->blk = (UINTPTR)-1; return HD_OK; } static HD_RESULT mem_free(MEM_PARM *mem_parm) { HD_RESULT ret = HD_OK; //free private pool ret = hd_common_mem_free(mem_parm->pa, (void *)mem_parm->va); if (ret!= HD_OK) { return ret; } mem_parm->pa = 0; mem_parm->va = 0; mem_parm->size = 0; mem_parm->blk = (UINT32)-1; return HD_OK; } static INT32 mem_load(MEM_PARM *mem_parm, const CHAR *filename) { FILE *fd; INT32 size = 0; fd = fopen(filename, "rb"); if (!fd) { printf("cannot read %s\r\n", filename); size = -1; goto exit; } fseek(fd, 0, SEEK_END); size = ftell(fd); fseek(fd, 0, SEEK_SET); // check "ai_in_buf" enough or not if (mem_parm->size < (UINT32)size) { printf("ERROR: ai_in_buf(%u) is not enough, input file(%u)\r\n", mem_parm->size, (UINT32)size); size = -1; goto exit; } if (size < 0) { printf("getting %s size failed\r\n", filename); goto exit; } else if ((INT32)fread((VOID *)mem_parm->va, 1, size, fd) != size) { printf("read size < %d\r\n", size); size = -1; goto exit; } mem_parm->size = size; // we use cpu to read memory, which needs to deal cache flush. if(hd_common_mem_flush_cache((VOID *)mem_parm->va, mem_parm->size) != HD_OK) { printf("flush cache failed.\r\n"); } exit: if (fd) { fclose(fd); } return size; } /*-----------------------------------------------------------------------------*/ /* Input Functions */ /*-----------------------------------------------------------------------------*/ /////////////////////////////////////////////////////////////////////////////// typedef struct _NET_IN_CONFIG { CHAR input_filename[256]; UINT32 w; UINT32 h; UINT32 c; UINT32 b; UINT32 bitdepth; UINT32 loff; UINT32 fmt; UINT32 is_comb_img; // 1: image image (or feature-in) is a combination image (or feature-in). } NET_IN_CONFIG; typedef struct _NET_IN { NET_IN_CONFIG in_cfg; MEM_PARM input_mem; UINT32 in_id; VENDOR_AI3_BUF src_img; } NET_IN; static NET_IN *g_in = NULL; static UINT32 _calc_ai_buf_size(UINT32 loff, UINT32 h, UINT32 c, UINT32 b, UINT32 bitdepth, UINT32 fmt) { UINT size = 0; switch (fmt) { case HD_VIDEO_PXLFMT_YUV420: { size = loff * h * 3 / 2; } break; case HD_VIDEO_PXLFMT_RGB888_PLANAR: { size = AI_RGB_BUFSIZE(loff, h); } break; case HD_VIDEO_PXLFMT_BGR888_PLANAR: { size = AI_RGB_BUFSIZE(loff, h); } break; default: // feature-in { size = loff * h * c * bitdepth/8; } break; } if (!size) { printf("ERROR!! ai_buf size = 0\n"); } return size; } static HD_RESULT _load_buf(MEM_PARM *mem_parm, CHAR *filename, VENDOR_AI3_BUF *p_buf, UINT32 w, UINT32 h, UINT32 c, UINT32 b, UINT32 bitdepth, UINT32 loff, UINT32 fmt) { INT32 file_len; file_len = mem_load(mem_parm, filename); if (file_len < 0) { printf("load buf(%s) fail\r\n", filename); return HD_ERR_NG; } printf("load buf(%s) ok\r\n", filename); p_buf->width = w; p_buf->height = h; p_buf->channel = c; p_buf->batch_num = b; p_buf->line_ofs = loff; p_buf->fmt = fmt; p_buf->pa = mem_parm->pa; p_buf->va = mem_parm->va; p_buf->sign = MAKEFOURCC('A','B','U','F'); p_buf->size = _calc_ai_buf_size(loff, h, c, b, bitdepth, fmt); if (p_buf->size == 0) { printf("load buf(%s) fail, p_buf->size = 0\r\n", filename); return HD_ERR_NG; } return HD_OK; } static HD_RESULT input_init(void) { HD_RESULT ret = HD_OK; int i; for (i = 0; i < 16; i++) { NET_IN* p_net = g_in + i; p_net->in_id = i; } return ret; } static HD_RESULT input_uninit(void) { HD_RESULT ret = HD_OK; return ret; } static HD_RESULT input_set_config(NET_PATH_ID in_path, NET_IN_CONFIG* p_in_cfg) { HD_RESULT ret = HD_OK; NET_IN* p_net = g_in + in_path; UINT32 in_id = p_net->in_id; memcpy((void*)&p_net->in_cfg, (void*)p_in_cfg, sizeof(NET_IN_CONFIG)); printf("in_path(%u) in_id(%u) set in_cfg: file(%s), buf=(%u,%u,%u,%u,%u,%u,%08x)\r\n", in_path, in_id, p_net->in_cfg.input_filename, p_net->in_cfg.w, p_net->in_cfg.h, p_net->in_cfg.c, p_net->in_cfg.b, p_net->in_cfg.bitdepth, p_net->in_cfg.loff, p_net->in_cfg.fmt); return ret; } static HD_RESULT input_open(NET_PATH_ID in_path) { HD_RESULT ret = HD_OK; NET_IN* p_net = g_in + in_path; UINT32 in_id = p_net->in_id; UINT32 buf_size = 0; CHAR mem_name[23] ; snprintf(mem_name, 23, "ai_in_buf %u", in_id); // calculate in buf size buf_size = _calc_ai_buf_size(p_net->in_cfg.loff, p_net->in_cfg.h, p_net->in_cfg.c, p_net->in_cfg.b, p_net->in_cfg.bitdepth, p_net->in_cfg.fmt); if (buf_size == 0) { printf("in_path(%u) in_id(%u) size == 0 \r\n", in_path, in_id); return HD_ERR_FAIL; } // allocate in buf ret = mem_alloc(&p_net->input_mem, mem_name, buf_size * p_net->in_cfg.b); if (ret != HD_OK) { printf("in_path(%u) in_id(%u) alloc ai_in_buf fail\r\n", in_path, in_id); return HD_ERR_FAIL; } printf("alloc_in_buf: pa = 0x%lx, va = 0x%lx, size = %u\n", p_net->input_mem.pa, p_net->input_mem.va, p_net->input_mem.size); // load in buf ret = _load_buf(&p_net->input_mem, p_net->in_cfg.input_filename, &p_net->src_img, p_net->in_cfg.w, p_net->in_cfg.h, p_net->in_cfg.c, p_net->in_cfg.b, p_net->in_cfg.bitdepth, p_net->in_cfg.loff, p_net->in_cfg.fmt); if (ret != HD_OK) { printf("in_path(%u) in_id(%u) input_open fail=%d\n", in_path, in_id, ret); } return ret; } static HD_RESULT input_close(NET_PATH_ID in_path) { HD_RESULT ret = HD_OK; NET_IN* p_net = g_in + in_path; mem_free(&p_net->input_mem); return ret; } static HD_RESULT input_start(NET_PATH_ID in_path) { HD_RESULT ret = HD_OK; return ret; } static HD_RESULT input_stop(NET_PATH_ID in_path) { HD_RESULT ret = HD_OK; return ret; } static HD_RESULT input_pull_buf(NET_PATH_ID in_path, VENDOR_AI3_BUF *p_in, INT32 wait_ms) { HD_RESULT ret = HD_OK; NET_IN* p_net = g_in + in_path; memcpy((void*)p_in, (void*)&(p_net->src_img), sizeof(VENDOR_AI3_BUF)); return ret; } /////////////////////////////////////////////////////////////////////////////// /*-----------------------------------------------------------------------------*/ /* Network Functions */ /*-----------------------------------------------------------------------------*/ typedef struct _NET_PROC_CONFIG { CHAR model_filename[256]; INT32 binsize; void *p_share_model; CHAR label_filename[256]; } NET_PROC_CONFIG; typedef struct _NET_PROC { NET_PROC_CONFIG net_cfg; MEM_PARM proc_mem; UINT32 proc_id; //CHAR out_class_labels[MAX_CLASS_NUM * VENDOR_AIS_LBL_LEN]; MEM_PARM rslt_mem; MEM_PARM io_mem; MEM_PARM intl_mem; MEM_PARM *out_mem; VENDOR_AI3_NET_INFO net_info; } NET_PROC; static NET_PROC *g_net = NULL; static INT32 _getsize_model(char* filename) { FILE *bin_fd; UINT32 bin_size = 0; bin_fd = fopen(filename, "rb"); if (!bin_fd) { printf("get bin(%s) size fail\n", filename); return (-1); } fseek(bin_fd, 0, SEEK_END); bin_size = ftell(bin_fd); fseek(bin_fd, 0, SEEK_SET); fclose(bin_fd); return bin_size; } static UINT32 _load_model(CHAR *filename, UINTPTR va) { FILE *fd; UINT32 file_size = 0, read_size = 0; const UINTPTR model_addr = va; //DBG_DUMP("model addr = %#lx\r\n", model_addr); fd = fopen(filename, "rb"); if (!fd) { printf("load model(%s) fail\r\n", filename); return 0; } fseek ( fd, 0, SEEK_END ); file_size = ALIGN_CEIL_4( ftell(fd) ); fseek ( fd, 0, SEEK_SET ); read_size = fread ((void *)model_addr, 1, file_size, fd); if (read_size != file_size) { printf("size mismatch, real = %d, idea = %d\r\n", (int)read_size, (int)file_size); } fclose(fd); printf("load model(%s) ok\r\n", filename); return read_size; } /* static HD_RESULT _load_label(UINTPTR addr, UINT32 line_len, const CHAR *filename) { FILE *fd; CHAR *p_line = (CHAR *)addr; fd = fopen(filename, "r"); if (!fd) { printf("load label(%s) fail\r\n", filename); return HD_ERR_NG; } while (fgets(p_line, line_len, fd) != NULL) { p_line[strlen(p_line) - 1] = '\0'; // remove newline character p_line += line_len; } if (fd) { fclose(fd); } printf("load label(%s) ok\r\n", filename); return HD_OK; } */ static HD_RESULT network_init(void) { HD_RESULT ret = HD_OK; { VENDOR_AI3_DEV_CFG dev_cfg = {0}; ret = vendor_ai3_dev_init(&dev_cfg); if (ret != HD_OK) { printf("vendor_ai3_dev_init fail=%d\n", ret); return ret; } } // dump AI3 version { VENDOR_AI3_VER ai3_ver = {0}; ret = vendor_ai3_dev_get(VENDOR_AI3_CFG_VER, &ai3_ver); if (ret != HD_OK) { printf("vendor_ai3_dev_get(CFG_VER) fail=%d\n", ret); return ret; } printf("vendor_ai version = %s\r\n", ai3_ver.vendor_ai_impl_version); printf("kflow_ai version = %s\r\n", ai3_ver.kflow_ai_impl_version); printf("kdrv_ai version = %s\r\n", ai3_ver.kdrv_ai_impl_version); } return ret; } static HD_RESULT network_uninit(void) { HD_RESULT ret = HD_OK; ret = vendor_ai3_dev_uninit(); if (ret != HD_OK) { printf("vendor_ai3_dev_uninit fail=%d\n", ret); } return ret; } static INT32 network_mem_config(NET_PATH_ID net_path, HD_COMMON_MEM_INIT_CONFIG* p_mem_cfg, void* p_cfg) { NET_PROC* p_net = g_net + net_path; NET_PROC_CONFIG* p_proc_cfg = (NET_PROC_CONFIG*)p_cfg; #if defined(_NVT_NVR_SDK_) int sys_fd; struct nvtmem_hdal_base sys_hdal; uintptr_t hdal_start_addr0, hdal_start_addr1; sys_fd = open("/dev/nvtmem0", O_RDWR); if (sys_fd < 0) { printf("Error: cannot open /dev/nvtmem0 device.\n"); exit(0); } if (ioctl(sys_fd, NVTMEM_GET_DTS_HDAL_BASE, &sys_hdal) < 0) { printf("PCIE_SYS_IOC_HDALBASE! \n"); close(sys_fd); exit(0); } close(sys_fd); /* init ddr0 user_blk */ hdal_start_addr0 = sys_hdal.base[0]; p_mem_cfg->pool_info[0].start_addr = hdal_start_addr0; p_mem_cfg->pool_info[0].blk_cnt = 1; p_mem_cfg->pool_info[0].blk_size = 200 * 1024 * 1024; p_mem_cfg->pool_info[0].type = HD_COMMON_MEM_USER_BLK; p_mem_cfg->pool_info[0].ddr_id = sys_hdal.ddr_id[0]; printf("create ddr%d: hdal_memory(%#lx, %ldKB), usr_blk(%#lx, %dKB)\n", p_mem_cfg->pool_info[0].ddr_id, hdal_start_addr0, sys_hdal.size[0] / 1024, p_mem_cfg->pool_info[0].start_addr, p_mem_cfg->pool_info[0].blk_size * p_mem_cfg->pool_info[0].blk_cnt / 1024); /* init ddr1 user_blk, if ddr1 is exist */ if (sys_hdal.size[1] != 0) { hdal_start_addr1 = sys_hdal.base[1]; p_mem_cfg->pool_info[1].start_addr = hdal_start_addr1; p_mem_cfg->pool_info[1].blk_cnt = 1; p_mem_cfg->pool_info[1].blk_size = 200 * 1024 * 1024; p_mem_cfg->pool_info[1].type = HD_COMMON_MEM_USER_BLK; p_mem_cfg->pool_info[1].ddr_id = sys_hdal.ddr_id[1]; printf("create ddr%d: hdal_memory(%#lx, %ldKB) usr_blk(%#lx, %dKB)\n", p_mem_cfg->pool_info[1].ddr_id, hdal_start_addr1, sys_hdal.size[1] / 1024, p_mem_cfg->pool_info[1].start_addr, p_mem_cfg->pool_info[1].blk_size * p_mem_cfg->pool_info[1].blk_cnt / 1024); } else { printf("create ddr1: hdal_memory(%#lx, %ldKB) is not exist\n", sys_hdal.base[1], sys_hdal.size[1] / 1024); } usleep(30000); // wait for printf completely #endif memcpy((void*)&p_net->net_cfg, (void*)p_proc_cfg, sizeof(NET_PROC_CONFIG)); if (strlen(p_net->net_cfg.model_filename) == 0) { printf("net_path(%u) input model is null\r\n", net_path); return HD_ERR_NG; } p_net->net_cfg.binsize = _getsize_model(p_net->net_cfg.model_filename); if (p_net->net_cfg.binsize <= 0) { printf("net_path(%u) input model is not exist?\r\n", net_path); return HD_ERR_NG; } printf("net_path(%u) set net_mem_cfg: model-file(%s), binsize=%d\r\n", net_path, p_net->net_cfg.model_filename, p_net->net_cfg.binsize); printf("net_path(%u) set net_mem_cfg: label-file(%s)\r\n", net_path, p_net->net_cfg.label_filename); return HD_OK; } static HD_RESULT network_alloc_io_buf(NET_PATH_ID net_path, UINT32 req_size) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; CHAR mem_name[23] ; snprintf(mem_name, 23, "ai_io_buf %u", net_path); ret = mem_alloc(&p_net->io_mem, mem_name, req_size); if (ret != HD_OK) { printf("net_path(%u) alloc ai_io_buf fail\r\n", net_path); return HD_ERR_FAIL; } printf("alloc_io_buf: work buf, pa = %#lx, va = %#lx, size = %u\r\n", p_net->io_mem.pa, p_net->io_mem.va, p_net->io_mem.size); return ret; } static HD_RESULT network_free_io_buf(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; if (p_net->io_mem.pa && p_net->io_mem.va) { mem_free(&p_net->io_mem); } return ret; } static HD_RESULT network_alloc_intl_buf(NET_PATH_ID net_path, UINT32 req_size) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; CHAR mem_name[23] ; snprintf(mem_name, 23, "ai_ronly_buf %u", net_path); ret = mem_alloc(&p_net->intl_mem, mem_name, req_size); if (ret != HD_OK) { printf("net_path(%u) alloc ai_ronly_buf fail\r\n", net_path); return HD_ERR_FAIL; } printf("alloc_intl_buf: internal buf, pa = %#lx, va = %#lx, size = %u\r\n", p_net->intl_mem.pa, p_net->intl_mem.va, p_net->intl_mem.size); return ret; } static HD_RESULT network_free_intl_buf(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; if (p_net->intl_mem.pa && p_net->intl_mem.va) { mem_free(&p_net->intl_mem); } return ret; } static HD_RESULT network_open(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; UINT32 loadsize = 0; CHAR mem_name[23] ; snprintf(mem_name, 23, "model.bin %u", net_path); if (strlen(p_net->net_cfg.model_filename) == 0) { printf("net_path(%u) input model is null\r\n", net_path); return 0; } ret = mem_alloc(&p_net->proc_mem, mem_name, p_net->net_cfg.binsize); if (ret != HD_OK) { printf("net_path(%u) mem_alloc model.bin fail=%d\n", net_path, ret); return HD_ERR_FAIL; } //load file loadsize = _load_model(p_net->net_cfg.model_filename, p_net->proc_mem.va); if (loadsize <= 0) { printf("net_path(%u) input model load fail: %s\r\n", net_path, p_net->net_cfg.model_filename); return 0; } /* // load label ret = _load_label((UINTPTR)p_net->out_class_labels, VENDOR_AIS_LBL_LEN, p_net->net_cfg.label_filename); if (ret != HD_OK) { printf("proc_id(%u) load_label fail=%d\n", proc_id, ret); return HD_ERR_FAIL; } */ { VENDOR_AI3_MODEL_INFO model_info = {0}; model_info.model_buf.pa = p_net->proc_mem.pa; model_info.model_buf.va = p_net->proc_mem.va; model_info.model_buf.size = p_net->proc_mem.size; #if DBG_OUT_DUMP model_info.ctrl = CTRL_BUF_DEBUG | CTRL_JOB_DEBUG | CTRL_JOB_DUMPOUT; #endif #if FLOAT_IN model_info.ctrl = model_info.ctrl | CTRL_BUF_FLOATIN ; #endif #if FLOAT_OUT model_info.ctrl = model_info.ctrl | CTRL_BUF_FLOATOUT ; #endif printf("net_path(%u) vendor_ai3_dev_get(MODEL_INFO) \n", net_path); ret = vendor_ai3_dev_get(VENDOR_AI3_CFG_MODEL_INFO, &model_info); if (ret != HD_OK) { printf("net_path(%u) vendor_ai3_dev_get(MODEL_INFO) fail=%d\n", net_path, ret); return HD_ERR_FAIL; } printf("model_info get => workbuf size = %d, ronlybuf size = %d\r\n", model_info.proc_mem.buf[AI3_PROC_BUF_WORKBUF].size, model_info.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].size); // alloc WORKBUF/RONLYBUF ret = network_alloc_intl_buf(net_path, model_info.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].size); if (ret != HD_OK) { printf("net_path(%u) alloc ronlybuf fail=%d\n", net_path, ret); return HD_ERR_FAIL; } ret = network_alloc_io_buf(net_path, model_info.proc_mem.buf[AI3_PROC_BUF_WORKBUF].size); if (ret != HD_OK) { printf("net_path(%u) alloc workbuf fail=%d\n", net_path, ret); return HD_ERR_FAIL; } } // call open() { VENDOR_AI3_PROC_CFG proc_cfg = {0}; proc_cfg.model_buf.pa = p_net->proc_mem.pa; proc_cfg.model_buf.va = p_net->proc_mem.va; proc_cfg.model_buf.size = p_net->proc_mem.size; proc_cfg.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].pa = p_net->intl_mem.pa; proc_cfg.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].va = p_net->intl_mem.va; proc_cfg.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].size = p_net->intl_mem.size; proc_cfg.proc_mem.buf[AI3_PROC_BUF_WORKBUF].pa = p_net->io_mem.pa; proc_cfg.proc_mem.buf[AI3_PROC_BUF_WORKBUF].va = p_net->io_mem.va; proc_cfg.proc_mem.buf[AI3_PROC_BUF_WORKBUF].size = p_net->io_mem.size; proc_cfg.plugin[AI3_PLUGIN_CPU] = vendor_ai_cpu1_get_engine(); #if DBG_OUT_DUMP proc_cfg.ctrl = CTRL_BUF_DEBUG | CTRL_JOB_DEBUG | CTRL_JOB_DUMPOUT; #endif #if FLOAT_IN proc_cfg.ctrl = proc_cfg.ctrl | CTRL_BUF_FLOATIN ; #endif #if FLOAT_OUT proc_cfg.ctrl = proc_cfg.ctrl | CTRL_BUF_FLOATOUT ; #endif ret = vendor_ai3_net_open(&p_net->proc_id, &proc_cfg, &p_net->net_info); if (ret != HD_OK) { printf("net_path(%u) vendor_ai3_net_open() fail=%d\n", net_path, ret); return HD_ERR_FAIL; } else { printf("net_path(%u) open success => get proc_id(%u)\r\n", net_path, p_net->proc_id); } } return ret; } static HD_RESULT network_close(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; UINT32 proc_id = p_net->proc_id; UINT32 i ; // close ret = vendor_ai3_net_close(proc_id); if (ret != HD_OK) { printf("net_path(%u), proc_id(%u) vendor_ai3_net_close fail=%d\n", net_path, proc_id, ret); return HD_ERR_FAIL; } if ((ret = network_free_intl_buf(net_path)) != HD_OK) return ret; if ((ret = network_free_io_buf(net_path)) != HD_OK) return ret; mem_free(&p_net->proc_mem); for (i = 0 ; i < p_net->net_info.out_buf_cnt; i++){ if(p_net->out_mem && p_net->out_mem[i].va) mem_free(&p_net->out_mem[i]); } if(p_net->out_mem) free(p_net->out_mem) ; return ret; } #if DUMP_POSTPROC_INFO static HD_RESULT network_dump_ai_buf(VENDOR_AI3_BUF *p_outbuf) { HD_RESULT ret = HD_OK; printf(" sign(0x%x) pa(0x%lx) va(0x%lx) sz(%u) w(%u) h(%u) ch(%u) batch_num(%u)\n", p_outbuf->sign, p_outbuf->pa, p_outbuf->va, p_outbuf->size, p_outbuf->width, p_outbuf->height, p_outbuf->channel, p_outbuf->batch_num); printf(" l_ofs(%llu) c_ofs(%llu) b_ofs(%llu) t_ofs(%llu) layout(%s) name(%s) scale_ratio(%.6f)\n", p_outbuf->line_ofs, p_outbuf->channel_ofs, p_outbuf->batch_ofs, p_outbuf->time_ofs, p_outbuf->layout, p_outbuf->name, p_outbuf->scale_ratio); // parsing pixel format switch (AI_PXLFMT_TYPE(p_outbuf->fmt)) { case HD_VIDEO_PXLFMT_AI_UINT8: case HD_VIDEO_PXLFMT_AI_SINT8: case HD_VIDEO_PXLFMT_AI_UINT16: case HD_VIDEO_PXLFMT_AI_SINT16: case HD_VIDEO_PXLFMT_AI_UINT32: case HD_VIDEO_PXLFMT_AI_SINT32: case HD_VIDEO_PXLFMT_AI_FLOAT32: { INT8 bitdepth = HD_VIDEO_PXLFMT_BITS(p_outbuf->fmt); INT8 int_bits = HD_VIDEO_PXLFMT_INT(p_outbuf->fmt); INT8 frac_bits = HD_VIDEO_PXLFMT_FRAC(p_outbuf->fmt); printf(" fmt(0x%x) bits(%u) int(%u) frac(%u)\n", p_outbuf->fmt, bitdepth, int_bits, frac_bits); } break; default: switch ((UINT32)p_outbuf->fmt) { case HD_VIDEO_PXLFMT_BGR888_PLANAR: { printf(" fmt(0x%x), BGR888_PLANAR\n", p_outbuf->fmt); } break; case HD_VIDEO_PXLFMT_YUV420: { printf(" fmt(0x%x), YUV420\n", p_outbuf->fmt); } break; case HD_VIDEO_PXLFMT_Y8: { printf(" fmt(0x%x), Y8 only\n", p_outbuf->fmt); } break; case HD_VIDEO_PXLFMT_UV: { printf(" fmt(0x%x), UV only\n", p_outbuf->fmt); } break; case 0: { printf(" fmt(0x%x), AI BUF\n", p_outbuf->fmt); } break; default: printf("unknown pxlfmt(0x%x)\n", p_outbuf->fmt); break; } } printf("\n"); return ret; } /* static INT32 mem_save(MEM_PARM *mem_parm, const CHAR *filename) { FILE *fd; UINT32 size = 0; fd = fopen(filename, "wb"); if (!fd) { printf("ERR: cannot open %s for write!\r\n", filename); return -1; } size = (INT32)fwrite((VOID *)mem_parm->va, 1, mem_parm->size, fd); if (size != mem_parm->size) { printf("ERR: write %s with size %ld < wanted %ld?\r\n", filename, size, mem_parm->size); } else { printf("write %s with %ld bytes.\r\n", filename, mem_parm->size); } if (fd) { fclose(fd); } return size; } */ #endif /////////////////////////////////////////////////////////////////////////////// typedef struct _VIDEO_LIVEVIEW { // (1) input NET_IN_CONFIG net_in_cfg; NET_PATH_ID in_path; // (2) network NET_PROC_CONFIG net_proc_cfg; NET_PATH_ID net_path; pthread_t proc_thread_id; UINT32 proc_start; UINT32 proc_exit; UINT32 proc_oneshot; UINT32 input_blob_num; } VIDEO_LIVEVIEW; static HD_RESULT init_module(void) { HD_RESULT ret; if ((ret = input_init()) != HD_OK) return ret; if ((ret = network_init()) != HD_OK) return ret; return HD_OK; } static HD_RESULT open_module(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret; //if ((ret = input_open(p_stream->in_path)) != HD_OK) // return ret; if ((ret = network_open(p_stream->net_path)) != HD_OK) return ret; return HD_OK; } static HD_RESULT close_module(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret; //if ((ret = input_close(p_stream->in_path)) != HD_OK) // return ret; if ((ret = network_close(p_stream->net_path)) != HD_OK) return ret; return HD_OK; } static HD_RESULT exit_module(void) { HD_RESULT ret; if ((ret = input_uninit()) != HD_OK) return ret; if ((ret = network_uninit()) != HD_OK) return ret; return HD_OK; } static HD_RESULT perf_begin(void) { vendor_ai3_dev_perf_begin(VENDOR_AI3_PERF_ID_TIME_UT); return HD_OK; } static HD_RESULT perf_end(void) { UINT32 i; VENDOR_AI3_PERF_TIME_UT perf_time_ut = {0}; vendor_ai3_dev_perf_end(VENDOR_AI3_PERF_ID_TIME_UT, &perf_time_ut); printf("\r\n ************* util-per-proc() *************\r\n"); for (i=0; i<perf_time_ut.core_count; i++) { printf("%8s: time(us) = %6d, util(%%) = %6.2f\r\n", perf_time_ut.core[i].name, perf_time_ut.core[i].time, ((float)perf_time_ut.core[i].util)/100); } return HD_OK; } /////////////////////////////////////////////////////////////////////////////// static VOID *network_user_thread(VOID *arg); static HD_RESULT set_buf_by_in_path_list(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret = HD_OK; NET_PATH_ID net_path = p_stream->net_path; NET_PROC* p_net = g_net + net_path; VENDOR_AI3_NET_INFO net_info = p_net->net_info; VENDOR_AI3_BUF in_buf = {0}; VENDOR_AI3_BUF tmp_buf = {0}; UINT32 proc_id = p_net->proc_id; UINT32 i = 0, idx = 0, k = 0; UINT32 in_buf_cnt = 0; UINT32 *in_path_list = NULL; /* get in path list */ in_path_list = p_net->net_info.in_path_list; in_buf_cnt = net_info.in_buf_cnt; for (i = 0; i < in_buf_cnt; i++) { /* get in buf (by in path list) */ ret = vendor_ai3_net_get(proc_id, in_path_list[i], &tmp_buf); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) get in buf fail, i(%d), in_path(0x%x)\n",net_path, proc_id, i, in_path_list[i]); goto exit; } if (dump_output) { // dump in buf printf("dump_in_buf: path_id: 0x%x\n", in_path_list[i]); ret = network_dump_ai_buf(&tmp_buf); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) dump in buf fail !!\n", net_path, proc_id); goto exit; }} } for (i = 0; i < p_stream->input_blob_num; i++) { NET_IN* p_in = g_in + i; /* load input bin */ ret = input_pull_buf((p_stream->in_path + i), &in_buf, 0); if (HD_OK != ret) { printf("in_path(%u) pull input fail !!\n", (p_stream->in_path + i)); goto exit; } if (p_in->in_cfg.is_comb_img == 0) { for(k =1 ; k < in_buf.batch_num; k++) { UINTPTR dst_va = in_buf.va + (k * in_buf.size); memcpy((VOID*)dst_va , (VOID*)in_buf.va, in_buf.size); hd_common_mem_flush_cache((VOID *)dst_va, in_buf.size); } } //printf(" path_%d(0x%x) pa(0x%lx) va(0x%lx) size(%u)\n", idx, in_path_list[idx], in_buf.pa, in_buf.va, in_buf.size); ret = vendor_ai3_net_set(proc_id, in_path_list[idx], &in_buf); if (HD_OK != ret) { printf("proc_id(%u)push input fail !! i(%u)\n", proc_id, i); goto exit; } idx++; } exit: return ret; } static HD_RESULT set_buf_by_out_path_list(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; UINT32 proc_id = p_net->proc_id; UINT32 i; VENDOR_AI3_BUF ai_buf = {0}; /* get out buf */ for (i = 0; i < p_net->net_info.out_buf_cnt; i++) { // get out buf (by out path list) ret = vendor_ai3_net_get(proc_id, p_net->net_info.out_path_list[i], &ai_buf); if (HD_OK != ret) { printf("proc_id(%u) get out buf fail, i(%d), out_path(0x%x)\n", proc_id, i, p_net->net_info.out_path_list[i]); goto exit; } if (ai_buf.size > p_net->out_mem[i].size){ printf("output size %u < ai_buf.size %u\r\n", p_net->out_mem[i].size, ai_buf.size); goto exit; } ai_buf.va = p_net->out_mem[i].va ; ai_buf.pa = p_net->out_mem[i].pa ; ai_buf.size = p_net->out_mem[i].size ; #if FLOAT_OUT ai_buf.fmt = HD_VIDEO_PXLFMT_AI_FLOAT32; #endif ret = vendor_ai3_net_set(proc_id, p_net->net_info.out_path_list[i], &ai_buf); if (HD_OK != ret) { printf("proc_id(%u)set output buf fail !! (%u)\n", proc_id, i); goto exit; } } exit: return ret; } #if (1) static uintptr_t get_post_buf(uint32_t size) { uintptr_t buf = (uintptr_t)malloc(size); return buf; } static VOID release_post_buf(VOID *ptr) { if (ptr) { free(ptr); } return; } #endif #if(1) static HD_RESULT network_dump_out_buf(NET_PATH_ID net_path, VENDOR_AI3_BUF *p_outbuf, UINT32 id) { HD_RESULT ret = HD_OK; //NET_PROC *p_net = g_net + net_path; //INT32 i; //AI_NET_ACCURACY_PARM parm = {0}; //AI_NET_SHAPE shape = {p_outbuf->batch_num, p_outbuf->channel, 1, 1, 1}; //INT32 size = shape.num * shape.channels * shape.height * shape.width; UINT32 length = p_outbuf->batch_num * p_outbuf->channel * p_outbuf->height * p_outbuf->width; FLOAT *p_outbuf_float = (FLOAT *)get_post_buf(length * sizeof(FLOAT)); ret = vendor_ai_cpu_util_fixed2float((VOID *)p_outbuf->va, p_outbuf->fmt, p_outbuf_float, p_outbuf->scale_ratio, length, p_outbuf->zero_point); printf("id:%d size:%d name:%s\n", id, length, p_outbuf->name); #if (1) // save output float bin CHAR out_float_path[256] = {0}; sprintf(out_float_path, "%s/float_%s.bin", dump_path, p_outbuf->name); printf("out_float_path: %s\n", out_float_path); FILE* fp_out = NULL; if ((fp_out = fopen(out_float_path, "wb+")) == NULL) { printf("fopen fail\n"); } else { fwrite((VOID *)p_outbuf_float, sizeof(FLOAT), length, fp_out); //fwrite((VOID *)layer_buffer[i].va, sizeof(INT16), length, fp_out); } if(fp_out){ fclose(fp_out); } // save output fixed bin CHAR out_fixed_path[256] = {0}; sprintf(out_fixed_path, "%s/fixed_%s.bin", dump_path, p_outbuf->name); printf("out_fixed_path: %s\n", out_fixed_path); FILE* fp_out1 = NULL; if ((fp_out1 = fopen(out_fixed_path, "wb+")) == NULL) { printf("fopen fail\n"); } else { //fwrite((VOID *)p_outbuf_float, sizeof(FLOAT), length, fp_out1); fwrite((VOID *)p_outbuf->va, sizeof(INT16), length, fp_out1); } if(fp_out1){ fclose(fp_out1); } #endif /* INT32 *p_idx = (INT32 *)get_post_buf(p_outbuf->channel * sizeof(INT32)); AI_NET_OUTPUT_CLASSS *p_classes = (AI_NET_OUTPUT_CLASSS *)get_post_buf(p_outbuf->batch_num * TOP_N * sizeof(AI_NET_OUTPUT_CLASSS)); parm.in_addr = (uintptr_t)p_outbuf_float; parm.classes = p_classes; parm.shape = shape; parm.top_n = TOP_N; parm.class_idx = p_idx; ret = ai_net_accuracy_process(&parm); printf("Classification Results:\r\n"); for (i = 0; i < parm.top_n; i++) { printf("%d. no=%d, label=%s, score=%f\r\n", i + 1, parm.classes[i].no, &p_net->out_class_labels[parm.classes[i].no * LABEL_LEN], parm.classes[i].score); } */ release_post_buf(p_outbuf_float); //release_post_buf(p_idx); //release_post_buf(p_classes); return ret; } #endif static HD_RESULT get_buf_by_out_path_list(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; UINT32 proc_id = p_net->proc_id; UINT32 i; VENDOR_AI3_BUF ai_buf = {0}; printf("########### p_net->net_info.out_buf_cnt %d \r\n",p_net->net_info.out_buf_cnt); /* get out buf */ for (i = 0; i < p_net->net_info.out_buf_cnt; i++) { // get out buf (by out path list) ret = vendor_ai3_net_get(proc_id, p_net->net_info.out_path_list[i], &ai_buf); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) get out buf fail, i(%d), out_path(0x%x)\n", net_path, proc_id, i, p_net->net_info.out_path_list[i]); goto exit; } #if DUMP_POSTPROC_INFO { //CHAR dump_path[23]; // dump out buf if (hd_common_mem_flush_cache((VOID *)ai_buf.va, ai_buf.size) != HD_OK) { printf("flush cache failed.\r\n"); } printf("dump_out_buf: path_id: 0x%x\n", p_net->net_info.out_path_list[i]); ret = network_dump_ai_buf(&ai_buf); if (HD_OK != ret) { printf("net_path(%u) dump out buf fail !!\n", net_path); goto exit; } //snprintf(dump_path, 23, "%s.bin", ai_buf.name); //printf(" DUMP out_buf (%u): %s va = %lx\n", i, dump_path,(ULONG)p_net->out_mem[i].va); //mem_save(&p_net->out_mem[i], dump_path); ret = network_dump_out_buf(net_path, &ai_buf, i); } #endif } exit: return ret; } static HD_RESULT allocate_buf_by_out_path_list(NET_PATH_ID net_path) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + net_path; UINT32 proc_id = p_net->proc_id; UINT32 i; VENDOR_AI3_BUF ai_buf = {0}; CHAR mem_name[23] ; /* get out path list */ p_net->out_mem = (MEM_PARM *)malloc(sizeof(MEM_PARM) * p_net->net_info.out_buf_cnt); memset(p_net->out_mem, 0, sizeof(MEM_PARM) * p_net->net_info.out_buf_cnt); /* get out buf */ for (i = 0; i < p_net->net_info.out_buf_cnt; i++) { // get out buf (by out path list) ret = vendor_ai3_net_get(proc_id, p_net->net_info.out_path_list[i], &ai_buf); if (HD_OK != ret) { printf("proc_id(%u) get out buf fail, i(%d), out_path(0x%x)\n", proc_id, i, p_net->net_info.out_path_list[i]); goto exit; } // // allocate in buf #if FLOAT_OUT ai_buf.size = ai_buf.width * ai_buf.height * ai_buf.channel * ai_buf.batch_num *sizeof(float) ; #endif snprintf(mem_name, 23, "output_buf %u", i); ret = mem_alloc(&p_net->out_mem[i], mem_name, ai_buf.size); if (ret != HD_OK) { printf("proc_id(%u) alloc ai_in_buf fail\r\n", proc_id); goto exit; } printf("alloc_outbuf: pa = 0x%lx, va = 0x%lx, size = %u\n", p_net->out_mem[i].pa, p_net->out_mem[i].va, p_net->out_mem[i].size); } return ret; exit: for (i = 0 ; i < p_net->net_info.out_buf_cnt; i++){ if(p_net->out_mem && p_net->out_mem[i].va) mem_free(&p_net->out_mem[i]); } if(p_net->out_mem) free(p_net->out_mem) ; return ret; } static HD_RESULT network_user_start(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + p_stream->net_path; UINT32 proc_id = p_net->proc_id; p_stream->proc_start = 0; p_stream->proc_exit = 0; p_stream->proc_oneshot = 0; ret = vendor_ai3_net_start(proc_id); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) vendor_ai3_net_start fail !!\n", p_stream->net_path, proc_id); } ret = pthread_create(&p_stream->proc_thread_id, NULL, network_user_thread, (VOID*)(p_stream)); if (ret < 0) { return HD_ERR_FAIL; } p_stream->proc_start = 1; p_stream->proc_exit = 0; p_stream->proc_oneshot = 0; return ret; } static HD_RESULT network_user_oneshot(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret = HD_OK; p_stream->proc_oneshot = 1; return ret; } static HD_RESULT network_user_stop(VIDEO_LIVEVIEW *p_stream) { HD_RESULT ret = HD_OK; NET_PROC* p_net = g_net + p_stream->net_path; UINT32 proc_id = p_net->proc_id; p_stream->proc_exit = 1; if (p_stream->proc_thread_id) { pthread_join(p_stream->proc_thread_id, NULL); } //stop: should be call after last time proc ret = vendor_ai3_net_stop(proc_id); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) vendor_ai3_net_stop fail !!\n", p_stream->net_path, proc_id); } return ret; } static VOID *network_user_thread(VOID *arg) { HD_RESULT ret = HD_OK; VIDEO_LIVEVIEW *p_stream = (VIDEO_LIVEVIEW*)arg; NET_PROC* p_net = g_net + p_stream->net_path; UINT32 proc_id = p_net->proc_id; static struct timeval tstart, tend; static UINT64 cur_time = 0; static UINT64 all_time = 0; static float mean_time = 0; UINT32 count=0; printf("\r\n"); while (p_stream->proc_start == 0) sleep(1); printf("\r\n"); while (p_stream->proc_exit == 0) { if (p_stream->proc_oneshot) { p_stream->proc_oneshot = 0; for (count=0;count<g_proc_num;count++) { // set buf by in_path_list ret = set_buf_by_in_path_list(p_stream); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) set in_buf fail(%d) !!\n", p_stream->net_path, proc_id, ret); goto skip; } ret = set_buf_by_out_path_list(p_stream->net_path); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) set in_buf fail(%d) !!\n", p_stream->net_path, proc_id, ret); goto skip; } // do net proc gettimeofday(&tstart, NULL); if(dump_time_ut){ perf_begin(); } ret = vendor_ai3_net_proc(proc_id); if(dump_time_ut){ perf_end(); } gettimeofday(&tend, NULL); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) proc fail !!\n", p_stream->net_path, proc_id); goto skip; } //count++; cur_time = (UINT64)(tend.tv_sec - tstart.tv_sec) * 1000000 + (tend.tv_usec - tstart.tv_usec); if(count>0){ all_time+=cur_time; mean_time=all_time/(float)(count); if (dump_time_proc){ printf("count %d cur time(us): %lld all time(us): %lld mean time(us): %f \r\n",count,cur_time,all_time,mean_time); } } // printf("net_path(%u), proc_id(%u) oneshot done!\n", p_stream->net_path, proc_id); // get buf by out_path_list if (dump_output) { /* code */ ret = get_buf_by_out_path_list(p_stream->net_path); if (HD_OK != ret) { printf("net_path(%u), proc_id(%u) get out_buf fail(%d) !!\n", p_stream->net_path, proc_id, ret); goto skip; } } } printf("count %d cur time(us): %lld all time(us): %lld mean time(us): %f \r\n",count,cur_time,all_time,mean_time); } usleep(100); } skip: return 0; } /*-----------------------------------------------------------------------------*/ /* Interface Functions */ /*-----------------------------------------------------------------------------*/ MAIN(argc, argv) { VIDEO_LIVEVIEW stream[1] = {0}; HD_COMMON_MEM_INIT_CONFIG mem_cfg = {0}; HD_RESULT ret; INT key; UINT32 j; INT32 idx; #if FLOAT_IN stream[0].input_blob_num = 1; //net_in NET_IN_CONFIG in_cfg = { .input_filename = "/mnt/sd/jpg/float32.bin", .w = 74, .h = 1, .c = 40, .b = 1, .bitdepth = 32, .loff = 296, .fmt = HD_VIDEO_PXLFMT_AI_FLOAT32, .is_comb_img = 1, }; NET_IN_CONFIG in_cfg2 = { .input_filename = "NULL", .w = 0, .h = 0, .c = 0, .b = 0, .bitdepth = 0, .loff = 0, .fmt = 0, .is_comb_img = 0, }; //net proc NET_PROC_CONFIG net_cfg = { .model_filename = "/mnt/sd/para/nvt_model_float32.bin", .label_filename = "/mnt/sd/accuracy/labels.txt" }; #elif MULTI_BATCH_IN /* multi-blob with multi-batch */ stream[0].input_blob_num = 2; //net_in NET_IN_CONFIG in_cfg = { .input_filename = "/mnt/sd/jpg/mblob_mbatch_0.yuv", .w = 12, .h = 12, .c = 2, .b = 8, .bitdepth = 8, .loff = 12, .fmt = HD_VIDEO_PXLFMT_YUV420, .is_comb_img = 1, }; NET_IN_CONFIG in_cfg2 = { .input_filename = "/mnt/sd/jpg/mblob_mbatch_1.bin", .w = 1, .h = 1, .c = 5, .b = 8, .bitdepth = 16, .loff = 2, .fmt = 0xA2101000, .is_comb_img = 1, }; //net proc NET_PROC_CONFIG net_cfg = { .model_filename = "/mnt/sd/para/nvt_model_mblob_mbatch.bin", .label_filename = "/mnt/sd/accuracy/labels.txt" }; #else stream[0].input_blob_num = 3; //net_in NET_IN_CONFIG in_cfg1 = { .input_filename = "/mnt/sd/jpg/mblob.bin", .w = 224, .h = 224, .c = 2, .b = 1, .bitdepth = 8, .loff = 224, .fmt = HD_VIDEO_PXLFMT_YUV420, .is_comb_img = 0, }; NET_IN_CONFIG in_cfg2 = { .input_filename = "/mnt/sd/jpg/mblob.bin", .w = 224, .h = 224, .c = 2, .b = 1, .bitdepth = 8, .loff = 224, .fmt = HD_VIDEO_PXLFMT_YUV420, .is_comb_img = 0, }; NET_IN_CONFIG in_cfg3 = { .input_filename = "/mnt/sd/jpg/mblob.bin", .w = 224, .h = 224, .c = 2, .b = 1, .bitdepth = 8, .loff = 224, .fmt = HD_VIDEO_PXLFMT_YUV420, .is_comb_img = 0, }; //net proc NET_PROC_CONFIG net_cfg = { .model_filename = "/mnt/sd/para/nvt_model_mblob.bin", .label_filename = "/mnt/sd/accuracy/labels.txt" }; #endif // End of #if MULTI_BATCH_IN if(argc < 4){ printf("usage : ai3_net_with_mblob (proc_num) (model_path) (input_blob_num)\n"); printf("usage : (MPROCESS_FOR_AIISP)\n"); printf("usage : (dump_time_UT)\n"); printf("usage : (dump_time_proc)\n"); printf("usage : (dump_output)\n"); printf("usage : (dump_path)\n"); printf("usage : (input_data_path1) (input_w) (input_h) (input_c) (input_b) (input_bitdepth) (input_loff) (input_fmt_10) (input_is_comb_img)\n"); printf("usage : (input_data_path2) (input_w) (input_h) (input_c) (input_b) (input_bitdepth) (input_loff) (input_fmt_10) (input_is_comb_img)\n"); printf("usage : (input_data_path2) (input_w) (input_h) (input_c) (input_b) (input_bitdepth) (input_loff) (input_fmt_10) (input_is_comb_img)\n"); return -1; } printf("\r\n\r\n"); idx = 1; UINT32 proc_num = 0; UINT32 input_blob_num = 0; { if (argc > idx) { sscanf(argv[idx++], "%d", &proc_num); printf("proc_num: %d\n", proc_num); g_proc_num=proc_num; } if (argc > idx) { sscanf(argv[idx++], "%s", net_cfg.model_filename); printf("net_cfg.model_filename: %s\n", net_cfg.model_filename); } if (argc > idx) { sscanf(argv[idx++], "%d", &input_blob_num); printf("input_blob_num: %d\n", input_blob_num); stream[0].input_blob_num=input_blob_num; } if (argc > idx) { sscanf(argv[idx++], "%d", &MPROCESS_FOR_AIISP); printf("MPROCESS_FOR_AIISP : %d\n", MPROCESS_FOR_AIISP); } if (argc > idx) { sscanf(argv[idx++], "%d", &dump_time_ut); printf("dump_time_ut: %d\n", dump_time_ut); } if (argc > idx) { sscanf(argv[idx++], "%d", &dump_time_proc); printf("dump_time_proc: %d\n", dump_time_proc); } if (argc > idx) { sscanf(argv[idx++], "%d", &dump_output); printf("dump_output: %d\n", dump_output); } if (argc > idx) { sscanf(argv[idx++], "%s", dump_path); printf("dump_path: %s\n", dump_path); } if (argc > idx) { sscanf(argv[idx++], "%s", in_cfg1.input_filename); printf("in_cfg1.input_filename: %s\n", in_cfg1.input_filename); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.w)); printf("(in_cfg1.w): %d\n", (in_cfg1.w)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.h)); printf("(in_cfg1.h): %d\n", (in_cfg1.h)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.c)); printf("(in_cfg1.c): %d\n", (in_cfg1.c)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.b)); printf("(in_cfg1.b): %d\n", (in_cfg1.b)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.bitdepth)); printf("(in_cfg1.bitdepth): %d\n", (in_cfg1.bitdepth)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.loff)); printf("(in_cfg1.loff): %d\n", (in_cfg1.loff)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.fmt)); printf("(in_cfg1.fmt): %d\n", (in_cfg1.fmt)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg1.is_comb_img)); printf("(in_cfg1.is_comb_img): %d\n", (in_cfg1.is_comb_img)); } if (argc > idx) { sscanf(argv[idx++], "%s", in_cfg2.input_filename); printf("in_cfg2.input_filename: %s\n", in_cfg2.input_filename); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.w)); printf("(in_cfg2.w): %d\n", (in_cfg2.w)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.h)); printf("(in_cfg2.h): %d\n", (in_cfg2.h)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.c)); printf("(in_cfg2.c): %d\n", (in_cfg2.c)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.b)); printf("(in_cfg2.b): %d\n", (in_cfg2.b)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.bitdepth)); printf("(in_cfg2.bitdepth): %d\n", (in_cfg2.bitdepth)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.loff)); printf("(in_cfg2.loff): %d\n", (in_cfg2.loff)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.fmt)); printf("(in_cfg2.fmt): %d\n", (in_cfg2.fmt)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg2.is_comb_img)); printf("(in_cfg2.is_comb_img): %d\n", (in_cfg2.is_comb_img)); } // cfg3 if (argc > idx) { sscanf(argv[idx++], "%s", in_cfg3.input_filename); printf("in_cfg3.input_filename: %s\n", in_cfg3.input_filename); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.w)); printf("(in_cfg3.w): %d\n", (in_cfg3.w)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.h)); printf("(in_cfg3.h): %d\n", (in_cfg3.h)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.c)); printf("(in_cfg3.c): %d\n", (in_cfg3.c)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.b)); printf("(in_cfg3.b): %d\n", (in_cfg3.b)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.bitdepth)); printf("(in_cfg3.bitdepth): %d\n", (in_cfg3.bitdepth)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.loff)); printf("(in_cfg3.loff): %d\n", (in_cfg3.loff)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.fmt)); printf("(in_cfg3.fmt): %d\n", (in_cfg3.fmt)); } if (argc > idx) { sscanf(argv[idx++], "%d", &(in_cfg3.is_comb_img)); printf("(in_cfg3.is_comb_img): %d\n", (in_cfg3.is_comb_img)); } } // malloc for g_in & g_net g_in = (NET_IN *)malloc(sizeof(NET_IN)*16); g_net = (NET_PROC *)malloc(sizeof(NET_PROC)*16); if ((g_in == NULL) || (g_net == NULL)) { printf("fail to malloc g_in/g_net\n"); goto exit; } stream[0].in_path = 0; stream[0].net_path = 0; // init hdal if(MPROCESS_FOR_AIISP){ ret = hd_common_init(1); // multi-process for aiisp }else{ ret = hd_common_init(0); } //this is no longer need in 690 /* #if defined(_BSP_NS02201_) || defined(_BSP_NS02302_) // set project config for AI hd_common_sysconfig(0, (1<<16), 0, VENDOR_AI_CFG); //enable AI engine #endif */ // init mem { // config common pool network_mem_config(stream[0].net_path, &mem_cfg, &net_cfg); } #if defined(_BSP_NS02201_) || defined(_BSP_NS02302_) if(MPROCESS_FOR_AIISP){ ret = hd_common_mem_init(NULL); // multi-process for aiisp }else{ ret = hd_common_mem_init(&mem_cfg); } if (HD_OK != ret) { printf("hd_common_mem_init err: %d\r\n", ret); goto exit; } #endif // init all modules ret = init_module(); if (ret != HD_OK) { printf("init fail=%d\n", ret); goto exit; } // set open config for (j=0; j < stream[0].input_blob_num; j++) { if (j == 0) { ret = input_set_config((stream[0].in_path + j), &in_cfg1); } else if (j == 1) { ret = input_set_config((stream[0].in_path + j), &in_cfg2); } else if (j == 2) { ret = input_set_config((stream[0].in_path + j), &in_cfg3); } if (HD_OK != ret) { printf("in_path(%u) input_set_config fail=%d\n", (stream[0].in_path + j), ret); goto exit; } } // open video_liveview modules for(j=0; j < stream[0].input_blob_num; j++) { ret = input_open((stream[0].in_path + j)); if (ret != HD_OK) { printf("in_path(%u) input open fail=%d\n", (stream[0].in_path + j), ret); goto exit; } } ret = open_module(&stream[0]); if (ret != HD_OK) { printf("open fail=%d\n", ret); goto exit; } // start input_start(stream[0].in_path); network_user_start(&stream[0]); allocate_buf_by_out_path_list(stream[0].net_path); do { printf("Enter q to exit, r to run once\n"); key = GETCHAR(); if (key == 'r') { // run once network_user_oneshot(&stream[0]); continue; } if (key == 'q' || key == 0x3) { break; } } while(1); // stop input_stop(stream[0].in_path); network_user_stop(&stream[0]); exit: // close video_liveview modules ret = close_module(&stream[0]); if (ret != HD_OK) { printf("close fail=%d\n", ret); } for(j=0; j < stream[0].input_blob_num; j++) { ret = input_close((stream[0].in_path + j)); if (ret != HD_OK) { printf("in_path(%u) input close fail=%d\n", (stream[0].in_path + j), ret); goto exit; } } // uninit all modules ret = exit_module(); if (ret != HD_OK) { printf("exit fail=%d\n", ret); } #if defined(_BSP_NS02201_) || defined(_BSP_NS02302_) // uninit memory ret = hd_common_mem_uninit(); if (ret != HD_OK) { printf("mem fail=%d\n", ret); } #endif // uninit hdal ret = hd_common_uninit(); if (ret != HD_OK) { printf("common fail=%d\n", ret); } // free g_in & g_net if (g_in) free(g_in); if (g_net) free(g_net); return ret; }
11-01
``` #!/bin/bash # This script aims to tune the best server parameter combinations to maximize throughput for given requirement. # See details in README (benchmarks/auto_tune/README.md). TAG=$(date +"%Y_%m_%d_%H_%M") BASE="" MODEL="meta-llama/Llama-3.1-8B-Instruct" SYSTEM="TPU" TP=1 DOWNLOAD_DIR="" INPUT_LEN=4000 OUTPUT_LEN=16 MIN_CACHE_HIT_PCT=0 MAX_LATENCY_ALLOWED_MS=100000000000 NUM_SEQS_LIST="128 256" NUM_BATCHED_TOKENS_LIST="512 1024 2048 4096" LOG_FOLDER="$BASE/auto-benchmark/$TAG" RESULT="$LOG_FOLDER/result.txt" PROFILE_PATH="$LOG_FOLDER/profile" echo "result file: $RESULT" echo "model: $MODEL" rm -rf $LOG_FOLDER rm -rf $PROFILE_PATH mkdir -p $LOG_FOLDER mkdir -p $PROFILE_PATH cd "$BASE/vllm" pip install -q datasets current_hash=$(git rev-parse HEAD) echo "hash:$current_hash" >> "$RESULT" echo "current_hash: $current_hash" best_throughput=0 best_max_num_seqs=0 best_num_batched_tokens=0 best_goodput=0 start_server() { local gpu_memory_utilization=$1 local max_num_seqs=$2 local max_num_batched_tokens=$3 local vllm_log=$4 local profile_dir=$5 pkill -f vllm VLLM_USE_V1=1 VLLM_SERVER_DEV_MODE=1 VLLM_TORCH_PROFILER_DIR=$profile_dir vllm serve $MODEL \ --disable-log-requests \ --port 8004 \ --gpu-memory-utilization $gpu_memory_utilization \ --max-num-seqs $max_num_seqs \ --max-num-batched-tokens $max_num_batched_tokens \ --tensor-parallel-size $TP \ --enable-prefix-caching \ --load-format dummy \ --download-dir "$DOWNLOAD_DIR" \ --max-model-len $(( INPUT_LEN+OUTPUT_LEN )) > "$vllm_log" 2>&1 & # wait for 10 minutes... server_started=0 for i in {1..60}; do RESPONSE=$(curl -s -X GET "http://0.0.0.0:8004/health" -w "%{http_code}" -o /dev/stdout) STATUS_CODE=$(echo "$RESPONSE" | tail -n 1) if [[ "$STATUS_CODE" -eq 200 ]]; then server_started=1 break else sleep 10 fi done if (( ! server_started )); then echo "server did not start within 10 minutes. Please check server log at $vllm_log". return 1 else return 0 fi } update_best_profile() { local profile_dir=$1 local profile_index=$2 sorted_paths=($(find "$profile_dir" -maxdepth 1 -not -path "$profile_dir" | sort)) selected_profile_file= if [[ "$SYSTEM" == "TPU" ]]; then selected_profile_file="${sorted_paths[$profile_index]}/*.xplane.pb" fi if [[ "$SYSTEM" == "GPU" ]]; then selected_profile_file="${sorted_paths[$profile_index]}" fi rm -f $PROFILE_PATH/* cp $selected_profile_file $PROFILE_PATH } run_benchmark() { local max_num_seqs=$1 local max_num_batched_tokens=$2 local gpu_memory_utilization=$3 echo "max_num_seq: $max_num_seqs, max_num_batched_tokens: $max_num_batched_tokens" local vllm_log="$LOG_FOLDER/vllm_log_${max_num_seqs}_${max_num_batched_tokens}.txt" local profile_dir="$LOG_FOLDER/profile_${max_num_seqs}_${max_num_batched_tokens}" echo "vllm_log: $vllm_log" echo rm -f $vllm_log mkdir -p $profile_dir pkill -f vllm local profile_index=0 echo "starting server..." start_server $gpu_memory_utilization $max_num_seqs $max_num_batched_tokens $vllm_log $profile_dir result=$? if [[ "$result" -eq 1 ]]; then echo "server failed to start. gpu_memory_utilization:$gpu_memory_utilization, max_num_seqs:$max_num_seqs, max_num_batched_tokens: $max_num_batched_tokens" else echo "server started." fi echo echo "run benchmark test..." meet_latency_requirement=0 # get a basic qps by using request-rate inf bm_log="$LOG_FOLDER/bm_log_${max_num_seqs}_${max_num_batched_tokens}_requestrate_inf.txt" prefix_len=$(( INPUT_LEN * MIN_CACHE_HIT_PCT / 100 )) adjusted_input_len=$(( INPUT_LEN - prefix_len )) python3 benchmarks/benchmark_serving.py \ --backend vllm \ --model $MODEL \ --dataset-name random \ --random-input-len $adjusted_input_len \ --random-output-len $OUTPUT_LEN \ --ignore-eos \ --disable-tqdm \ --request-rate inf \ --percentile-metrics ttft,tpot,itl,e2el \ --goodput e2el:$MAX_LATENCY_ALLOWED_MS \ --num-prompts 1000 \ --random-prefix-len $prefix_len \ --port 8004 \ --profile &> "$bm_log" throughput=$(grep "Request throughput (req/s):" "$bm_log" | sed 's/[^0-9.]//g') e2el=$(grep "P99 E2EL (ms):" "$bm_log" | awk '{print $NF}') goodput=$(grep "Request goodput (req/s):" "$bm_log" | sed 's/[^0-9.]//g') if (( $(echo "$e2el <= $MAX_LATENCY_ALLOWED_MS" | bc -l) )); then meet_latency_requirement=1 request_rate=inf fi if (( ! meet_latency_requirement )); then # start from request-rate as int(throughput) + 1 request_rate=$((${throughput%.*} + 1)) while ((request_rate > 0)); do profile_index=$((profile_index+1)) # clear prefix cache curl -X POST http://0.0.0.0:8004/reset_prefix_cache sleep 5 bm_log="$LOG_FOLDER/bm_log_${max_num_seqs}_${max_num_batched_tokens}_requestrate_${request_rate}.txt" python3 benchmarks/benchmark_serving.py \ --backend vllm \ --model $MODEL \ --dataset-name random \ --random-input-len $adjusted_input_len \ --random-output-len $OUTPUT_LEN \ --ignore-eos \ --disable-tqdm \ --request-rate $request_rate \ --percentile-metrics ttft,tpot,itl,e2el \ --goodput e2el:$MAX_LATENCY_ALLOWED_MS \ --num-prompts 100 \ --random-prefix-len $prefix_len \ --port 8004 &> "$bm_log" throughput=$(grep "Request throughput (req/s):" "$bm_log" | sed 's/[^0-9.]//g') e2el=$(grep "P99 E2EL (ms):" "$bm_log" | awk '{print $NF}') goodput=$(grep "Request goodput (req/s):" "$bm_log" | sed 's/[^0-9.]//g') if (( $(echo "$e2el <= $MAX_LATENCY_ALLOWED_MS" | bc -l) )); then meet_latency_requirement=1 break fi request_rate=$((request_rate-1)) done fi # write the results and update the best result. if ((meet_latency_requirement)); then echo "max_num_seqs: $max_num_seqs, max_num_batched_tokens: $max_num_batched_tokens, request_rate: $request_rate, e2el: $e2el, throughput: $throughput, goodput: $goodput" echo "max_num_seqs: $max_num_seqs, max_num_batched_tokens: $max_num_batched_tokens, request_rate: $request_rate, e2el: $e2el, throughput: $throughput, goodput: $goodput" >> "$RESULT" if (( $(echo "$throughput > $best_throughput" | bc -l) )); then best_throughput=$throughput best_max_num_seqs=$max_num_seqs best_num_batched_tokens=$max_num_batched_tokens best_goodput=$goodput if [[ "$SYSTEM" == "TPU" ]]; then update_best_profile "$profile_dir/plugins/profile" $profile_index fi if [[ "$SYSTEM" == "GPU" ]]; then update_best_profile "$profile_dir" $profile_index fi fi else echo "max_num_seqs: $max_num_seqs, max_num_batched_tokens: $max_num_batched_tokens does not meet latency requirement ${MAX_LATENCY_ALLOWED_MS}" echo "max_num_seqs: $max_num_seqs, max_num_batched_tokens: $max_num_batched_tokens does not meet latency requirement ${MAX_LATENCY_ALLOWED_MS}" >> "$RESULT" fi echo "best_max_num_seqs: $best_max_num_seqs, best_num_batched_tokens: $best_num_batched_tokens, best_throughput: $best_throughput" pkill vllm sleep 10 printf '=%.0s' $(seq 1 20) return 0 } read -r -a num_seqs_list <<< "$NUM_SEQS_LIST" read -r -a num_batched_tokens_list <<< "$NUM_BATCHED_TOKENS_LIST" # first find out the max gpu-memory-utilization without HBM OOM. gpu_memory_utilization=0.98 find_gpu_memory_utilization=0 while (( $(echo "$gpu_memory_utilization >= 0.9" | bc -l) )); do start_server $gpu_memory_utilization "${num_seqs_list[-1]}" "${num_batched_tokens_list[-1]}" "$LOG_FOLDER/vllm_log_gpu_memory_utilization_$gpu_memory_utilization.log" result=$? if [[ "$result" -eq 0 ]]; then find_gpu_memory_utilization=1 break else gpu_memory_utilization=$(echo "$gpu_memory_utilization - 0.01" | bc) fi done if [[ "$find_gpu_memory_utilization" -eq 1 ]]; then echo "Using gpu_memory_utilization=$gpu_memory_utilization to serve model." else echo "Cannot find a proper gpu_memory_utilization over 0.9 to serve the model, please check logs in $LOG_FOLDER." exit 1 fi for num_seqs in "${num_seqs_list[@]}"; do for num_batched_tokens in "${num_batched_tokens_list[@]}"; do run_benchmark $num_seqs $num_batched_tokens $gpu_memory_utilization done done echo "finish permutations" echo "best_max_num_seqs: $best_max_num_seqs, best_num_batched_tokens: $best_num_batched_tokens, best_throughput: $best_throughput, profile saved in: $PROFILE_PATH" echo "best_max_num_seqs: $best_max_num_seqs, best_num_batched_tokens: $best_num_batched_tokens, best_throughput: $best_throughput, profile saved in: $PROFILE_PATH" >> "$RESULT" ``` 这个是啥代码,详细分析并解释代码
08-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值