日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

瑞芯微(EASY EAI)RV1126B 模型部署API說明

廣州靈眸科技有限公司 ? 2026-05-07 17:49 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1. 基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)定義

1.1 rknn_sdk_version

結(jié)構(gòu)體rknn_sdk_version用來表示RKNN SDK的版本信息,結(jié)構(gòu)體的定義如下:

v2-16ce7266b168a79896d6992ca6567ade_720w.webp

1.2 rknn_input_output_num
結(jié)構(gòu)體rknn_input_output_num表示輸入輸出tensor個(gè)數(shù),其結(jié)構(gòu)體成員變量如下表所示:

v2-1ccd0aaa1b31d7dfae3732b56fe156b8_720w.webp

1.3 rknn_input_range
結(jié)構(gòu)體rknn_input_range表示一個(gè)輸入的支持形狀列表信息。它包含了輸入的索引、支持的形狀個(gè)數(shù)、數(shù)據(jù)布局格式、名稱以及形狀列表,具體的結(jié)構(gòu)體的定義如下表所示:

v2-a3f67c7304e44c1cdf1361de7e95a0c4_720w.webp

1.4 rknn_tensor_attr
結(jié)構(gòu)體rknn_tensor_attr表示模型的tensor的屬性,結(jié)構(gòu)體的定義如下表所示:

v2-7a3d9555f94f43aa57deab274b3cb43e_720w.webp

1.5 rknn_perf_detail
結(jié)構(gòu)體rknn_perf_detail表示模型的性能詳情,結(jié)構(gòu)體的定義如下表所示(RV1106/RV1106B/RV1103/RV1103B/RK2118暫不支持):

v2-f7ae861e8ccacf66a760611b65620aec_720w.webp

1.6 rknn_perf_run
結(jié)構(gòu)體rknn_perf_run表示模型的總體性能,結(jié)構(gòu)體的定義如下表所示(RV1106/RV1106B/RV1103/RV1103B/RK2118暫不支持):

v2-0162bf35cb0c232f7b53486f7f5ed7e3_720w.webp

1.7 rknn_mem_size
結(jié)構(gòu)體rknn_mem_size表示初始化模型時(shí)的內(nèi)存分配情況,結(jié)構(gòu)體的定義如下表所示:

v2-f1a7e1d3786efaba4563a9d564fc76de_720w.webp

1.8 rknn_tensor_mem
結(jié)構(gòu)體rknn_tensor_mem表示tensor的內(nèi)存信息。結(jié)構(gòu)體的定義如下表所示:

v2-dde0358b094dac4b3e5cc0d6d601b9e4_720w.webp

1.9 rknn_input
結(jié)構(gòu)體rknn_input表示模型的一個(gè)數(shù)據(jù)輸入,用來作為參數(shù)傳入給rknn_inputs_set函數(shù)。結(jié)構(gòu)體的定義如下表所示:

v2-6f2e09a37a55761b92797c834aed5a38_720w.webp

1.10 rknn_output
結(jié)構(gòu)體rknn_output表示模型的一個(gè)數(shù)據(jù)輸出,用來作為參數(shù)傳入給rknn_outputs_get函數(shù),在函數(shù)執(zhí)行后,結(jié)構(gòu)體對象將會(huì)被賦值。結(jié)構(gòu)體的定義如下表所示:

v2-1c65e3d06222fdb6316acf63653c7fc1_720w.webp

1.11 rknn_init_extend
結(jié)構(gòu)體rknn_init_extend表示初始化模型時(shí)的擴(kuò)展信息。結(jié)構(gòu)體的定義如下表所示(RV1106/RV1106B/RV1103/RV1103B/RK2118暫不支持):

v2-cf32be0a5dfbceccbf3da35d78ed4d2d_720w.webp

1.12 rknn_run_extend
結(jié)構(gòu)體rknn_run_extend表示模型推理時(shí)的擴(kuò)展信息,目前暫不支持使用。結(jié)構(gòu)體的定義如下表所示:

v2-bfdf4dacb8d7a84ea75c9f1da92ba51f_720w.webp

1.13 rknn_output_extend
結(jié)構(gòu)體rknn_output_extend表示獲取輸出的擴(kuò)展信息,目前暫不支持使用。結(jié)構(gòu)體的定義如下表所示:

v2-636df6f492be226c40ed79d51ed7106a_720w.webp

1.14 rknn_custom_string
結(jié)構(gòu)體rknn_custom_string表示轉(zhuǎn)換RKNN模型時(shí),用戶設(shè)置的自定義字符串,結(jié)構(gòu)體的定義如下表所示:

v2-e076f1bb00c57807b8e06c73de64258c_720w.webp

2. 基礎(chǔ)API說明


2.1 rknn_init
rknn_init初始化函數(shù)功能為創(chuàng)建rknn_context對象、加載RKNN模型以及根據(jù)flag和rknn_init_extend結(jié)構(gòu)體執(zhí)行特定的初始化行為。

v2-81aca4b391ebd3b43d23280480c56170_720w.webp

示例代碼如下:

rknn_context ctx;
int ret = rknn_init(&ctx, model_data, model_data_size, 0, NULL);


各個(gè)初始化標(biāo)志說明如下:
RKNN_FLAG_COLLECT_PERF_MASK:用于運(yùn)行時(shí)查詢網(wǎng)絡(luò)各層時(shí)間;
RKNN_FLAG_MEM_ALLOC_OUTSIDE:用于表示模型輸入、輸出、權(quán)重、中間tensor內(nèi)存全部由用戶分配,它主要有兩方面的作用:
1. 所有內(nèi)存均是用戶自行分配,便于對整個(gè)系統(tǒng)內(nèi)存進(jìn)行統(tǒng)籌安排。
2. 用于內(nèi)存復(fù)用,特別是針對RV1103/RV1106/RV1103B/RV1106B/RK2118這種內(nèi)存極為緊張的情況。
假設(shè)有模型A、B 兩個(gè)模型,這兩個(gè)模型在設(shè)計(jì)上串行運(yùn)行的,那么這兩個(gè)模型的中間tensor的內(nèi)存就可以復(fù)用。示例代碼如下:

rknn_context ctx_a, ctx_b;

rknn_init(&ctx_a, model_path_a, 0, RKNN_FLAG_MEM_ALLOC_OUTSIDE, NULL);
rknn_query(ctx_a, RKNN_QUERY_MEM_SIZE, &mem_size_a, sizeof(mem_size_a));

rknn_init(&ctx_b, model_path_b, 0, RKNN_FLAG_MEM_ALLOC_OUTSIDE, NULL);
rknn_query(ctx_b, RKNN_QUERY_MEM_SIZE, &mem_size_b, sizeof(mem_size_b));

max_internal_size = MAX(mem_size_a.total_internal_size, mem_size_b.total_internal_size);
internal_mem_max = rknn_create_mem(ctx_a, max_internal_size);

internal_mem_a = rknn_create_mem_from_fd(ctx_a, internal_mem_max->fd,
     internal_mem_max->virt_addr, mem_size_a.total_internal_size, 0);
rknn_set_internal_mem(ctx_a, internal_mem_a);

internal_mem_b = rknn_create_mem_from_fd(ctx_b, internal_mem_max->fd,
     internal_mem_max->virt_addr, mem_size_b.total_internal_size, 0);
rknn_set_internal_mem(ctx_b, internal_mem_b);


RKNN_FLAG_SHARE_WEIGHT_MEM:用于共享另一個(gè)模型的weight權(quán)重。主要用于模擬不定長度模型輸入(RKNPU運(yùn)行時(shí)庫版本大于等于1.5.0后該功能被動(dòng)態(tài)shape功能替代)。比如對于某些語音模型,
輸入長度不定,但由于NPU無法支持不定長輸入,因此需要生成幾個(gè)不同分辨率的RKNN模,其中,只有一個(gè)RKNN模型的保留完整權(quán)重,其他RKNN模型不帶權(quán)重。在初始化不帶權(quán)重RKNN模型時(shí),使用該標(biāo)志能讓當(dāng)前上下文共享完整RKNN模型的權(quán)重。假設(shè)需要分辨率A、B兩個(gè)模型,則使用流程如下:
1. 使用RKNN-Toolkit2生成分辨率A的模型。
2. 使用RKNN-Toolkit2生成不帶權(quán)重的分辨率B的模型,rknn.config()中,remove_weight要設(shè)置成True,主要目的是減少模型B的大小。
3. 在板子上,正常初始化模型A。
4. 通過RKNN_FLAG_SHARE_WEIGHT_MEM的flags初始化模型B。
5. 其他按照原來的方式使用。板端參考代碼如下:

rknn_context ctx_a, ctx_b;
rknn_init(&ctx_a, model_path_a, 0, 0, NULL);

rknn_init_extend extend;
extend.ctx = ctx_a;
rknn_init(&ctx_b, model_path_b, 0, RKNN_FLAG_SHARE_WEIGHT_MEM, &extend);


RKNN_FLAG_COLLECT_MODEL_INFO_ONLY:用于初始化一個(gè)空上下文,僅用于調(diào)用rknn_query接口查詢模型weight內(nèi)存總大小和中間tensor總大小,無法進(jìn)行推理;
RKNN_FLAG_INTERNAL_ALLOC_OUTSIDE: 表示模型中間tensor由用戶分配,常用于用戶自行管理和復(fù)用多個(gè)模型之間的中間tensor內(nèi)存;
RKNN_FLAG_EXECUTE_FALLBACK_PRIOR_DEVICE_GPU: 表示所有NPU不支持的層優(yōu)先選擇運(yùn)行在GPU上,但并不保證運(yùn)行在GPU上,實(shí)際運(yùn)行的后端設(shè)備取決于運(yùn)行時(shí)對該算子的支持情況;
RKNN_FLAG_ENABLE_SRAM: 表示中間tensor內(nèi)存盡可能分配在SRAM上;
RKNN_FLAG_SHARE_SRAM: 用于當(dāng)前上下文嘗試共享另一個(gè)上下文的SRAM內(nèi)存地址空間,要求當(dāng)前上下文初始化時(shí)必須同時(shí)啟用RKNN_FLAG_ENABLE_SRAM標(biāo)志;
RKNN_FLAG_DISABLE_PROC_HIGH_PRIORITY: 表示當(dāng)前上下文使用默認(rèn)進(jìn)程優(yōu)先級。不設(shè)置該標(biāo)志,進(jìn)程nice值是-19;
RKNN_FLAG_DISABLE_FLUSH_INPUT_MEM_CACHE: 設(shè)置該標(biāo)志后,runtime內(nèi)部不主動(dòng)刷新輸入tensor緩存,用戶必須確保輸入tensor在調(diào)用 rknn_run 之前已刷新緩存。主要用于當(dāng)輸入數(shù)據(jù)沒有CPU訪問時(shí),減少runtime內(nèi)部刷cache的耗時(shí)。
RKNN_FLAG_DISABLE_FLUSH_OUTPUT_MEM_CACHE: 設(shè)置該標(biāo)志后,runtime不主動(dòng)清除輸出tensor緩存。此時(shí)用戶不能直接訪問output_mem->virt_addr,這會(huì)導(dǎo)致緩存一致性問題。 如果用戶想使用
output_mem->virt_addr,必須使用 rknn_mem_sync (ctx, mem, RKNN_MEMORY_SYNC_FROM_DEVICE)來刷新緩存。該標(biāo)志一般在NPU的輸出數(shù)據(jù)不被CPU訪問時(shí)使用,比如輸出數(shù)據(jù)由 GPU 或 RGA 訪問以減少刷新緩存所需的時(shí)間。
RKNN_FLAG_MODEL_BUFFER_ZERO_COPY:表示rknn_init接口的傳入的模型buffer是rknn_create_mem或者rknn_create_mem2接口分配的內(nèi)存,runtime內(nèi)部不需要拷貝一次模型buffer,減少運(yùn)行時(shí)的內(nèi)存占用,但需要用戶保證上下文銷毀前模型內(nèi)存有效,并且在銷毀上下文后釋放該內(nèi)存。初始化上下文時(shí),rknn_init接口的rknn_init_extend參數(shù),其成員real_model_offset、real_model_size、model_buffer_fd和model_buffer_flags根據(jù)rknn_create_mem2接口返回的rknn_tensor_mem設(shè)置。
RKNN_MEM_FLAG_ALLOC_NO_CONTEXT:在使用rknn_create_mem2接口分配內(nèi)存時(shí),設(shè)置該標(biāo)志后,允許ctx參數(shù)是0或者NULL。從而用戶在未初始化任何一個(gè)上下文之前就能獲取NPU驅(qū)動(dòng)分配的內(nèi)存,返回的內(nèi)存結(jié)構(gòu)體需使用rknn_destroy_mem接口釋放,釋放的接口可使用任意一個(gè)上下文作為參數(shù)。
示例代碼如下:

 rknn_tensor_mem* model_mem = rknn_create_mem2(ctx, model_size,
RKNN_MEM_FLAG_ALLOC_NO_CONTEXT);
 memcpy(model_mem->virt_addr, model_data, model_size);
 rknn_init_extend init_ext;
 memset(&init_ext, 0, sizeof(rknn_init_extend));
 init_ext.real_model_offset = 0;
 init_ext.real_model_size = model_size;
 init_ext.model_buffer_fd = model_mem->fd;
 init_ext.model_buffer_flags = model_mem->flags;
 int ret = rknn_init(&ctx, model_mem->virt_addr, model_size, RKNN_FLAG_MODEL_BUFFER_ZERO_COPY,
&init_ext);

// do rknn inference...

rknn_destroy_mem(ctx, model_mem);
rknn_destroy(ctx);



2.2 rknn_set_core_mask
rknn_set_core_mask函數(shù)指定工作的NPU核心,該函數(shù)僅支持RK3576/RK3588平臺,在單核NPU架構(gòu)的平臺上設(shè)置會(huì)返回錯(cuò)誤。

v2-c8e14a8e806456d76d3b64dc3a78fd13_720w.webp


示例代碼如下:

rknn_context ctx;
rknn_core_mask core_mask = RKNN_NPU_CORE_0;
int ret = rknn_set_core_mask(ctx, core_mask);


在RKNN_NPU_CORE_0_1及RKNN_NPU_CORE_0_1_2模式下,目前以下OP能獲得更好的加速:Conv、DepthwiseConvolution、Add、Concat、Relu、Clip、Relu6、ThresholdedRelu、PRelu、LeakyRelu,其余類型OP將fallback至單核Core0中運(yùn)行,部分類型OP(如Pool類、ConvTranspose等)將在后續(xù)更新版本中支持。


2.3 rknn_set_batch_core_num
rknn_set_batch_core_num函數(shù)指定多batch RKNN模型(RKNN-Toolkit2轉(zhuǎn)換時(shí)設(shè)置rknn_batch_size大于1導(dǎo)出的模型)的NPU核心數(shù)量,該函數(shù)僅支持RK3588/RK3576平臺。

v2-efe17b6ab3531bcc113f0a23e2f4a297_720w.webp

示例代碼如下:

rknn_context ctx;
int ret = rknn_set_batch_core_num(ctx, 2);


2.4 rknn_dup_context
rknn_dup_context生成一個(gè)指向同一個(gè)模型的新context,可用于多線程執(zhí)行相同模型時(shí)的權(quán)重復(fù)用。RV1106/RV1103/RV1106B/RV1103B/RK2118平臺暫不支持 。

v2-08124d8b666c6c14ce65dffd1a830305_720w.webp

示例代碼如下:

rknn_context ctx_in;
rknn_context ctx_out;
int ret = rknn_dup_context(&ctx_in, &ctx_out);


2.5 rknn_destroy
rknn_destroy函數(shù)將釋放傳入的rknn_context及其相關(guān)資源。

v2-9ebcde604f01d4c45faa5765504738f5_720w.webp

示例代碼如下:

rknn_context ctx;
int ret = rknn_destroy(ctx);


2.6 rknn_query
rknn_query函數(shù)能夠查詢獲取到模型輸入輸出信息、逐層運(yùn)行時(shí)間、模型推理的總時(shí)間、SDK版本、內(nèi)存占用信息、用戶自定義字符串等信息。

v2-6fe6ffa8504d272f1ed7f6c9463aaba2_720w.webp

當(dāng)前SDK支持的查詢命令如下表所示:

查詢命令返回結(jié)果結(jié)構(gòu)體功能
RKNN_QUERY_IN_OUT_NUMrknn_input_output_num查詢輸入輸出tensor個(gè)數(shù)。
RKNN_QUERY_INPUT_ATTRrknn_tensor_attr查詢輸入tensor屬性。
RKNN_QUERY_OUTPUT_ATTRrknn_tensor_attr查詢輸出tensor屬性。
RKNN_QUERY_PERF_DETAILrknn_perf_detail查詢網(wǎng)絡(luò)各層運(yùn)行時(shí)間,需要調(diào)用rknn_init接口時(shí),設(shè)置RKNN_FLAG_COLLECT_PERF_MASK標(biāo)志才能生效。
RKNN_QUERY_PERF_RUNrknn_perf_run查詢推理模型(不包含設(shè)置輸入/輸出)的耗時(shí),單位是微秒。
RKNN_QUERY_SDK_VERSIONrknn_sdk_version查詢SDK版本。
RKNN_QUERY_MEM_SIZErknn_mem_size查詢分配給權(quán)重和網(wǎng)絡(luò)中間tensor的內(nèi)存大小。
RKNN_QUERY_CUSTOM_STRINGrknn_custom_string查詢RKNN模型里面的用戶自定義字符串信息。
RKNN_QUERY_NATIVE_INPUT_ATTRrknn_tensor_attr使用零拷貝API接口時(shí),查詢原生輸入tensor屬性,它是NPU直接讀取的模型輸入屬性。
RKNN_QUERY_NATIVE_OUTPUT_ATTRrknn_tensor_attr使用零拷貝API接口時(shí),查詢原生輸出tensor屬性,它是NPU直接輸出的模型輸出屬性。
RKNN_QUERY_NATIVE_NC1HWC2_INPUT_ATTRrknn_tensor_attr使用零拷貝API接口時(shí),查詢原生輸入tensor屬性,它是NPU直接讀取的模型輸入屬性與RKNN_QUERY_NATIVE_INPUT_ATTR查詢結(jié)果一致。
RKNN_QUERY_NATIVE_NC1HWC2_OUTPUT_ATTRrknn_tensor_attr使用零拷貝API接口時(shí),查詢原生輸出tensor屬性,它是NPU直接輸出的模型輸出屬與RKNN_QUERY_NATIVE_OUTPUT_ATTR查詢結(jié)果一致性。
RKNN_QUERY_NATIVE_NHWC_INPUT_ATTRrknn_tensor_attr使用零拷貝API接口時(shí),查詢原生輸入 tensor屬性與RKNN_QUERY_NATIVE_INPUT_ATTR查詢結(jié)果一致 。
RKNN_QUERY_NATIVE_NHWC_OUTPUT_ATTRrknn_tensor_attr使用零拷貝API接口時(shí),查詢原生輸出NHWC tensor屬性。
RKNN_QUERY_DEVICE_MEM_INFOrknn_tensor_mem查詢模型buffer的內(nèi)存屬性。
RKNN_QUERY_INPUT_DYNAMIC_RANGErknn_input_range使用支持動(dòng)態(tài)形狀RKNN模型時(shí),查詢模型支持輸入形狀數(shù)量、列表、形狀對應(yīng)的數(shù)據(jù)布局和名稱等信息。
RKNN_QUERY_CURRENT_INPUT_ATTRrknn_tensor_attr使用支持動(dòng)態(tài)形狀RKNN模型時(shí),查詢模型當(dāng)前推理所使用的輸入屬性。
RKNN_QUERY_CURRENT_OUTPUT_ATTRrknn_tensor_attr使用支持動(dòng)態(tài)形狀RKNN模型時(shí),查詢模型當(dāng)前推理所使用的輸出屬性。
RKNN_QUERY_CURRENT_NATIVE_INPUT_ATTRrknn_tensor_attr使用支持動(dòng)態(tài)形狀RKNN模型時(shí),查詢模型當(dāng)前推理所使用的NPU原生輸入屬性。
RKNN_QUERY_CURRENT_NATIVE_OUTPUT_ATTRrknn_tensor_attr使用支持動(dòng)態(tài)形狀RKNN模型時(shí),查詢模型當(dāng)前推理所使用的NPU原生輸出屬性。


各個(gè)指令用法的詳細(xì)說明,如下:
1. 查詢SDK版本
傳入RKNN_QUERY_SDK_VERSION命令可以查詢RKNN SDK的版本信息。其中需要先創(chuàng)建rknn_sdk_version結(jié)構(gòu)體對象。
示例代碼如下:

rknn_sdk_version version;
ret = rknn_query(ctx, RKNN_QUERY_SDK_VERSION, &version, sizeof(rknn_sdk_version));
printf("sdk api version: %s\n", version.api_version);
printf("driver version: %s\n", version.drv_version);


2. 查詢輸入輸出tensor個(gè)數(shù)
在rknn_init接口調(diào)用完畢后,傳入RKNN_QUERY_IN_OUT_NUM命令可以查詢模型輸入輸出tensor的個(gè)數(shù)。其中需要先創(chuàng)建rknn_input_output_num結(jié)構(gòu)體對象。
示例代碼如下:

rknn_input_output_num io_num;
ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));
printf("model input num: %d, output num: %d\n", io_num.n_input, io_num.n_output);


3. 查詢輸入tensor屬性(用于通用API接口)
在rknn_init接口調(diào)用完畢后,傳入RKNN_QUERY_INPUT_ATTR命令可以查詢模型輸入tensor的屬性。其中需要先創(chuàng)建rknn_tensor_attr結(jié)構(gòu)體對象 (注意:RV1106/RV1103/RV1106B/RV1103B/RK2118查詢出來的tensor是原始輸入native的tensor) 。
示例代碼如下:

rknn_tensor_attr input_attrs[io_num.n_input];
memset(input_attrs, 0, sizeof(input_attrs));
for (int i = 0; i < io_num.n_input; i++) {
   input_attrs[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]), sizeof(rknn_tensor_attr));
}


4. 查詢輸出tensor屬性(用于通用API接口)
在rknn_init接口調(diào)用完畢后,傳入RKNN_QUERY_OUTPUT_ATTR命令可以查詢模型輸出tensor的屬性。其中需要先創(chuàng)建rknn_tensor_attr結(jié)構(gòu)體對象。
示例代碼如下:

rknn_tensor_attr output_attrs[io_num.n_output];
memset(output_attrs, 0, sizeof(output_attrs));
for (int i = 0; i < io_num.n_output; i++) {
   output_attrs[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]), sizeof(rknn_tensor_attr));
}


5. 查詢模型推理的逐層耗時(shí)
在rknn_run接口調(diào)用完畢后,rknn_query接口傳入RKNN_QUERY_PERF_DETAIL可以查詢網(wǎng)絡(luò)推理時(shí)逐層的耗時(shí),單位是微秒。使用該命令的前提是,在rknn_init接口的flag參數(shù)需要包含
RKNN_FLAG_COLLECT_PERF_MASK標(biāo)志。
示例代碼如下:

rknn_context ctx;
int ret = rknn_init(&ctx, model_data, model_data_size, RKNN_FLAG_COLLECT_PERF_MASK, NULL);
...
ret = rknn_run(ctx,NULL);
...
rknn_perf_detail perf_detail;
ret = rknn_query(ctx, RKNN_QUERY_PERF_DETAIL, &perf_detail, sizeof(perf_detail));


6. 查詢模型推理的總耗時(shí)
在rknn_run接口調(diào)用完畢后,rknn_query接口傳入RKNN_QUERY_PERF_RUN可以查詢上模型推理(不包含設(shè)置輸入/輸出)的耗時(shí),單位是微秒。
示例代碼如下:

rknn_context ctx;
int ret = rknn_init(&ctx, model_data, model_data_size, 0, NULL);
...
ret = rknn_run(ctx,NULL);
...
rknn_perf_run perf_run;
ret = rknn_query(ctx, RKNN_QUERY_PERF_RUN, &perf_run, sizeof(perf_run));


7. 查詢模型的內(nèi)存占用情況
在rknn_init接口調(diào)用完畢后,當(dāng)用戶需要自行分配網(wǎng)絡(luò)的內(nèi)存時(shí),rknn_query接口傳入RKNN_QUERY_MEM_SIZE可以查詢模型的權(quán)重、網(wǎng)絡(luò)中間tensor的內(nèi)存(不包括輸入和輸出)、推演模型所用的所有DMA內(nèi)存的以及SRAM內(nèi)存(如果sram沒開或者沒有此項(xiàng)功能則為0)的占用情況。使用該命令的前提是在rknn_init接口的flag參數(shù)需要包含RKNN_FLAG_MEM_ALLOC_OUTSIDE標(biāo)志。
示例代碼如下:

rknn_context ctx;
int ret = rknn_init(&ctx, model_data, model_data_size, RKNN_FLAG_MEM_ALLOC_OUTSIDE , NULL);
rknn_mem_size mem_size;
ret = rknn_query(ctx, RKNN_QUERY_MEM_SIZE, &mem_size, sizeof(mem_size));


8. 查詢模型中用戶自定義字符串
在rknn_init接口調(diào)用完畢后,當(dāng)用戶需要查詢生成RKNN模型時(shí)加入的自定義字符串,rknn_query接口傳入RKNN_QUERY_CUSTOM_STRING可以獲取該字符串。例如,在轉(zhuǎn)換RKNN模型時(shí),用戶填入“RGB”的自定義字符來標(biāo)識RKNN模型輸入是RGB格式三通道圖像而不是BGR格式三通道圖像,在運(yùn)行時(shí)則根據(jù)查詢到的“RGB”信息將數(shù)據(jù)轉(zhuǎn)換成RGB圖像。
示例代碼如下:

rknn_context ctx;
int ret = rknn_init(&ctx, model_data, model_data_size, 0, NULL);
rknn_custom_string custom_string;
ret = rknn_query(ctx, RKNN_QUERY_CUSTOM_STRING, &custom_string, sizeof(custom_string));


9. 查詢原生輸入tensor屬性(用于零拷貝API接口)
在rknn_init接口調(diào)用完畢后,傳入RKNN_QUERY_NATIVE_INPUT_ATTR命令(同RKNN_QUERY_NATIVE_NC1HWC2_INPUT_ATTR)可以查詢模型原生輸入tensor的屬性。其中需要先創(chuàng)建rknn_tensor_attr結(jié)構(gòu)體對象。
示例代碼如下:

rknn_tensor_attr input_attrs[io_num.n_input];
memset(input_attrs, 0, sizeof(input_attrs));
for (int i = 0; i < io_num.n_input; i++) {
   input_attrs[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_NATIVE_INPUT_ATTR, &(input_attrs[i]), sizeof(rknn_tensor_attr));
}


10. 查詢原生輸出tensor屬性(用于零拷貝API接口)
在rknn_init接口調(diào)用完畢后,傳入RKNN_QUERY_NATIVE_OUTPUT_ATTR命令(同RKNN_QUERY_NATIVE_NC1HWC2_OUTPUT_ATTR)可以查詢模型原生輸出tensor的屬性。其中需要先創(chuàng)建rknn_tensor_attr結(jié)構(gòu)體對象。
示例代碼如下:

rknn_tensor_attr output_attrs[io_num.n_output];
memset(output_attrs, 0, sizeof(output_attrs));
for (int i = 0; i < io_num.n_output; i++) {
   output_attrs[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_NATIVE_OUTPUT_ATTR, &(output_attrs[i]), sizeof(rknn_tensor_attr));
}


11. 查詢NHWC格式原生輸入tensor屬性(用于零拷貝API接口)
在rknn_init接口調(diào)用完畢后,傳入RKNN_QUERY_NATIVE_NHWC_INPUT_ATTR命令可以查詢模型NHWC格式輸入tensor的屬性。其中需要先創(chuàng)建rknn_tensor_attr結(jié)構(gòu)體對象。
示例代碼如下:

rknn_tensor_attr input_attrs[io_num.n_input];
memset(input_attrs, 0, sizeof(input_attrs));
for (int i = 0; i < io_num.n_input; i++) {
   input_attrs[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_NATIVE_NHWC_INPUT_ATTR,
             &(input_attrs[i]), sizeof(rknn_tensor_attr));
}


12. 查詢NHWC格式原生輸出tensor屬性(用于零拷貝API接口)
在rknn_init接口調(diào)用完畢后,傳入RKNN_QUERY_NATIVE_NHWC_OUTPUT_ATTR命令可以查詢模型NHWC格式輸出tensor的屬性。其中需要先創(chuàng)建rknn_tensor_attr結(jié)構(gòu)體對象。
示例代碼如下:

rknn_tensor_attr output_attrs[io_num.n_output];
memset(output_attrs, 0, sizeof(output_attrs));
for (int i = 0; i < io_num.n_output; i++) {
   output_attrs[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_NATIVE_NHWC_OUTPUT_ATTR,
             &(output_attrs[i]), sizeof(rknn_tensor_attr));
}


13. 查詢模型buffer的內(nèi)存屬性(注:僅RV1106/RV1103/RV1106B/RV1103B/RK2118支持該查詢)
在rknn_init接口調(diào)用完畢后,傳入RKNN_QUERY_DEVICE_MEM_INFO命令可以查詢Runtime內(nèi)部開辟的模型buffer的包括fd、物理地址等屬性。

rknn_tensor_mem mem_info;
memset(&mem_info, 0, sizeof(mem_info));
ret = rknn_query(ctx, RKNN_QUERY_DEVICE_MEM_INFO, &mem_info, sizeof(mem_info));


14. 查詢RKNN模型支持的動(dòng)態(tài)輸入形狀信息(注:RV1106/RV1103/RV1106B/RV1103B/RK2118不支持該接口
在rknn_init接口調(diào)用完畢后,傳入RKNN_QUERY_INPUT_DYNAMIC_RANGE命令可以查詢模型支持的輸入形狀信息,包含輸入形狀個(gè)數(shù) 、輸入形狀列表、輸入形狀對應(yīng)的布局和名稱等信息。其中需要先創(chuàng)建rknn_input_range結(jié)構(gòu)體對象。
示例代碼如下:

rknn_input_range dyn_range[io_num.n_input];
memset(dyn_range, 0, io_num.n_input * sizeof(rknn_input_range));
for (uint32_t i = 0; i < io_num.n_input; i++) {
   dyn_range[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_INPUT_DYNAMIC_RANGE,
             &dyn_range[i], sizeof(rknn_input_range));
}


15. 查詢RKNN模型當(dāng)前使用的輸入動(dòng)態(tài)形狀
在rknn_set_input_shapes接口調(diào)用完畢后,傳入RKNN_QUERY_CURRENT_INPUT_ATTR命令可以查詢模型當(dāng)前使用的輸入屬性信息。其中需要先創(chuàng)建rknn_tensor_attr結(jié)構(gòu)體(注:
RV1106/RV1103/RV1106B/RV1103B/RK2118不支持該命令)。
示例代碼如下:

rknn_tensor_attr cur_input_attrs[io_num.n_input];
memset(cur_input_attrs, 0, io_num.n_input * sizeof(rknn_tensor_attr));
for (uint32_t i = 0; i < io_num.n_input; i++) {
   cur_input_attrs[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_CURRENT_INPUT_ATTR,
             &(cur_input_attrs[i]), sizeof(rknn_tensor_attr));
}


16. 查詢RKNN模型當(dāng)前使用的輸出動(dòng)態(tài)形狀
在rknn_set_input_shapes接口調(diào)用完畢后,傳入RKNN_QUERY_CURRENT_OUTPUT_ATTR命令可以查詢模型當(dāng)前使用的輸出屬性信息。其中需要先創(chuàng)建rknn_tensor_attr結(jié)構(gòu)體(注:
RV1106/RV1103/RV1106B/RV1103B/RK2118不支持該命令)。
示例代碼如下:

rknn_tensor_attr cur_output_attrs[io_num.n_output];
memset(cur_output_attrs, 0, io_num.n_output * sizeof(rknn_tensor_attr));
for (uint32_t i = 0; i < io_num.n_output; i++) {
   cur_output_attrs[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_CURRENT_OUTPUT_ATTR,
             &(cur_output_attrs[i]), sizeof(rknn_tensor_attr));
}


17. 查詢RKNN模型當(dāng)前使用的原生輸入動(dòng)態(tài)形狀
在rknn_set_input_shapes接口調(diào)用完畢后,傳入RKNN_QUERY_CURRENT_NATIVE_INPUT_ATTR命令可以查詢模型當(dāng)前使用的原生輸入屬性信息。其中需要先創(chuàng)建rknn_tensor_attr結(jié)構(gòu)體(注:
RV1106/RV1103/RV1106B/RV1103B/RK2118不支持該命令)。
示例代碼如下:

rknn_tensor_attr cur_input_attrs[io_num.n_input];
memset(cur_input_attrs, 0, io_num.n_input * sizeof(rknn_tensor_attr));
for (uint32_t i = 0; i < io_num.n_input; i++) {
   cur_input_attrs[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_CURRENT_NATIVE_INPUT_ATTR,
             &(cur_input_attrs[i]), sizeof(rknn_tensor_attr));
}


18. 查詢RKNN模型當(dāng)前使用的原生輸出動(dòng)態(tài)形狀
在rknn_set_input_shapes接口調(diào)用完畢后,傳入RKNN_QUERY_CURRENT_NATIVE_OUTPUT_ATTR命令可以查詢模型當(dāng)前使用的原生輸出屬性信息。其中需要先創(chuàng)建rknn_tensor_attr結(jié)構(gòu)體(注:RV1106/RV1103/RV1106B/RV1103B/RK2118不支持該命令)。
示例代碼如下:

rknn_tensor_attr cur_output_attrs[io_num.n_output];
memset(cur_output_attrs, 0, io_num.n_output * sizeof(rknn_tensor_attr));
for (uint32_t i = 0; i < io_num.n_output; i++) {
   cur_output_attrs[i].index = i;
   ret = rknn_query(ctx, RKNN_QUERY_CURRENT_NATIVE_OUTPUT_ATTR,
             &(cur_output_attrs[i]), sizeof(rknn_tensor_attr));
}


2.6rknn_inputs_set
通過rknn_inputs_set函數(shù)可以設(shè)置模型的輸入數(shù)據(jù)。該函數(shù)能夠支持多個(gè)輸入,其中每個(gè)輸入是rknn_input結(jié)構(gòu)體對象,在傳入之前用戶需要設(shè)置該對象,注:RV1106/RV1103/RV1106B/RV1103B/RK2118不支持該接口。

v2-3c051e8b4e17ef836f4970ba3caa7965_720w.webp

示例代碼如下:

rknn_input inputs[1];
memset(inputs, 0, sizeof(inputs));
inputs[0].index = 0;
inputs[0].type = RKNN_TENSOR_UINT8;
inputs[0].size = img_width*img_height*img_channels;
inputs[0].fmt = RKNN_TENSOR_NHWC;
inputs[0].buf = in_data;
inputs[0].pass_through = 0;

ret = rknn_inputs_set(ctx, 1, inputs);


2.7 rknn_run
rknn_run函數(shù)將執(zhí)行一次模型推理,調(diào)用之前需要先通過rknn_inputs_set函數(shù)或者零拷貝的接口設(shè)置輸入數(shù)據(jù)。

v2-b6d0cc4082fd1765250a641007fa9949_720w.webp

示例代碼如下:

ret = rknn_run(ctx, NULL);


2.8 rknn_outputs_get
rknn_outputs_get函數(shù)可以獲取模型推理的輸出數(shù)據(jù)。該函數(shù)能夠一次獲取多個(gè)輸出數(shù)據(jù)。其中每個(gè)輸出是rknn_output結(jié)構(gòu)體對象,在函數(shù)調(diào)用之前需要依次創(chuàng)建并設(shè)置每個(gè)rknn_output對象。
對于輸出數(shù)據(jù)的buffer存放可以采用兩種方式:一種是用戶自行申請和釋放,此時(shí)rknn_output對象的is_prealloc需要設(shè)置為1,并且將buf指針指向用戶申請的buffer;另一種是由rknn來進(jìn)行分配,此時(shí)
rknn_output對象的is_prealloc設(shè)置為0即可,函數(shù)執(zhí)行之后buf將指向輸出數(shù)據(jù)。注:RV1106/RV1103/RV1106B/RV1103B/RK2118不支持該接口

v2-4d25111c916370e836773b5ee7c69f9d_720w.webp

示例代碼如下:

rknn_output outputs[io_num.n_output];
memset(outputs, 0, sizeof(outputs));
for (int i = 0; i < io_num.n_output; i++) {
   outputs[i].index = i;
   outputs[i].is_prealloc = 0;
   outputs[i].want_float = 1;
}
ret = rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);


2.9 rknn_outputs_release
rknn_outputs_release函數(shù)將釋放rknn_outputs_get函數(shù)得到的輸出的相關(guān)資源。

v2-f58b7964c07f94455c181ee83830b9f1_720w.webp

示例代碼如下:

ret = rknn_outputs_release(ctx, io_num.n_output, outputs);


2.10 rknn_create_mem_from_phys
當(dāng)用戶需要自己分配內(nèi)存讓NPU使用時(shí),通過rknn_create_mem_from_phys函數(shù)可以創(chuàng)建一個(gè)rknn_tensor_mem結(jié)構(gòu)體并得到它的指針,該函數(shù)通過傳入物理地址、虛擬地址以及大小,外部內(nèi)存相關(guān)的信息會(huì)賦值給rknn_tensor_mem結(jié)構(gòu)體。

v2-2d0906cf381a175c375646954caa8981_720w.webp

示例代碼如下:

//suppose we have got buffer information as input_phys, input_virt and size
rknn_tensor_mem* input_mems [1];
input_mems[0] = rknn_create_mem_from_phys(ctx, input_phys, input_virt, size);


2.11 rknn_create_mem_from_fd
當(dāng)用戶要自己分配內(nèi)存讓NPU使用時(shí),rknn_create_mem_from_fd函數(shù)可以創(chuàng)建一個(gè)rknn_tensor_mem結(jié)構(gòu)體并得到它的指針,該函數(shù)通過傳入文件描述符fd、偏移、虛擬地址以及大小,外部內(nèi)存相關(guān)的信息會(huì)賦值給rknn_tensor_mem結(jié)構(gòu)體。

v2-ac0584fbf612ef87ce6b28949e86ea1f_720w.webp

示例代碼如下:
2.12 rknn_create_mem
當(dāng)用戶要NPU內(nèi)部分配內(nèi)存時(shí),rknn_create_mem函數(shù)可以分配用戶指定的內(nèi)存大小,并返回一個(gè)rknn_tensor_mem結(jié)構(gòu)體。

v2-cbeddd315e730a47be927a27b614d1da_720w.webp

示例代碼如下:

//suppose we have got buffer size
rknn_tensor_mem* input_mems [1];
input_mems[0] = rknn_create_mem(ctx, size);


2.13 rknn_create_mem2
當(dāng)用戶要NPU內(nèi)部分配內(nèi)存時(shí),rknn_create_mem2函數(shù)可以分配用戶指定的內(nèi)存大小及內(nèi)存類型,并返回一個(gè)rknn_tensor_mem結(jié)構(gòu)體。

v2-1c348d927068fecf4df79eedd0d4901a_720w.webp

rknn_create_mem2與rknn_create_mem的主要區(qū)別是rknn_create_mem2帶了一個(gè)alloc_flags,可以指定分配的內(nèi)存是否cacheable的,而rknn_create_mem不能指定,默認(rèn)就是cacheable。
示例代碼如下:
2.14 rknn_destroy_mem
rknn_destroy_mem函數(shù)會(huì)銷毀rknn_tensor_mem結(jié)構(gòu)體,用戶分配的內(nèi)存需要自行釋放。

v2-0dd79a86fa9491b7b27d91506547f86b_720w.webp

示例代碼如下:

rknn_tensor_mem* input_mems [1];
int ret = rknn_destroy_mem(ctx, input_mems[0]);


2.15 rknn_set_weight_mem
如果用戶自己為網(wǎng)絡(luò)權(quán)重分配內(nèi)存,初始化相應(yīng)的rknn_tensor_mem結(jié)構(gòu)體后,在調(diào)用rknn_run前,通過rknn_set_weight_mem函數(shù)可以讓NPU使用該內(nèi)存。

v2-760a6bc546d8cd1a78440cc4c81ea94c_720w.webp

示例代碼如下:

rknn_tensor_mem* weight_mems [1];
int ret = rknn_set_weight_mem(ctx, weight_mems[0]);


2.16 rknn_set_internal_mem
如果用戶自己為網(wǎng)絡(luò)中間tensor分配內(nèi)存,初始化相應(yīng)的rknn_tensor_mem結(jié)構(gòu)體后,在調(diào)用rknn_run前,通過rknn_set_internal_mem函數(shù)可以讓NPU使用該內(nèi)存。

v2-b1e64777bc260a39a8e0f20e8bd814ad_720w.webp

示例代碼如下:

rknn_tensor_mem* internal_tensor_mems [1];
int ret = rknn_set_internal_mem(ctx, internal_tensor_mems[0]);


2.17 rknn_set_io_mem
如果用戶自己為網(wǎng)絡(luò)輸入/輸出tensor分配內(nèi)存,初始化相應(yīng)的rknn_tensor_mem結(jié)構(gòu)體后,在調(diào)用rknn_run前,通過rknn_set_io_mem函數(shù)可以讓NPU使用該內(nèi)存。

v2-0eef124d324c4aa5a31a3e2d009f1329_720w.webp


示例代碼如下:

rknn_tensor_attr output_attrs[1];
rknn_tensor_mem* output_mems[1];
ret = rknn_query(ctx, RKNN_QUERY_NATIVE_OUTPUT_ATTR, &(output_attrs[0]), sizeof(rknn_tensor_attr));
output_mems[0] = rknn_create_mem(ctx, output_attrs[0].size_with_stride);
rknn_set_io_mem(ctx, output_mems[0], &output_attrs[0]);


2.18rknn_set_input_shape(deprecated)
該接口已經(jīng)廢棄,請使用rknn_set_input_shapes接口綁定輸入形狀。當(dāng)前版本不可用,如要繼續(xù)使用該接口,請使用1.5.0版本SDK并參考1.5.0版本的使用指南文檔。
2.19 rknn_set_input_shapes
對于動(dòng)態(tài)形狀輸入RKNN模型,在推理前必須指定當(dāng)前使用的輸入形狀。該接口傳入輸入個(gè)數(shù)和rknn_tensor_attr數(shù)組,包含了每個(gè)輸入形狀和對應(yīng)的數(shù)據(jù)布局信息,將每個(gè)rknn_tensor_attr結(jié)構(gòu)體對象的
索引、名稱、形狀(dims)和內(nèi)存布局信息(fmt)必須填充,rknn_tensor_attr結(jié)構(gòu)體其他成員無需設(shè)置。在使用該接口前,可先通過rknn_query函數(shù)查詢RKNN模型支持的輸入形狀數(shù)量和動(dòng)態(tài)形狀列表,要求輸入數(shù)據(jù)的形狀在模型支持的輸入形狀列表中。初次運(yùn)行或每次切換新的輸入形狀,需要調(diào)用該接口設(shè)置新的形狀,否則,不需要重復(fù)調(diào)用該接口。

v2-bb67d91f0ff41ec9cdf8fb81c7981eac_720w.webp

示例代碼如下:

for (int i = 0; i < io_num.n_input; i++) {
   for (int j = 0; j < input_attrs[i].n_dims; ++j) {
//使用第一個(gè)動(dòng)態(tài)輸入形狀
      input_attrs[i].dims[j] = dyn_range[i].dyn_range[0][j];
   }
}
ret = rknn_set_input_shapes(ctx, io_num.n_input, input_attrs);
if (ret < 0) {
   fprintf(stderr, "rknn_set_input_shapes error! ret=%d\n", ret);
   return -1;
}


2.20 rknn_mem_sync
rknn_create_mem函數(shù)創(chuàng)建的內(nèi)存默認(rèn)是帶cacheable標(biāo)志的,對于帶cacheable標(biāo)志創(chuàng)建的內(nèi)存,在被CPU和NPU同時(shí)使用時(shí),由于cache行為會(huì)導(dǎo)致數(shù)據(jù)一致性問題。該接口用于同步一塊帶cacheable標(biāo)志創(chuàng)建的內(nèi)存,保證CPU和NPU訪問這塊內(nèi)存的數(shù)據(jù)是一致的。

v2-93fdeafbc653b0c9fdde55b6361b00bc_720w.webp

示例代碼如下:

ret =rknn_mem_sync(ctx, &outputs[0].mem,
RKNN_MEMORY_SYNC_FROM_DEVICE);
if (ret < 0) {
   fprintf(stderr, " rknn_mem_sync error! ret=%d\n", ret);
   return -1;
}


3. 矩陣乘法數(shù)據(jù)結(jié)構(gòu)定義


3.1 rknn_matmul_info
rknn_matmul_info表示用于執(zhí)行矩陣乘法的規(guī)格信息,它包含了矩陣乘法的規(guī)模、輸入和輸出矩陣的數(shù)據(jù)類型和內(nèi)存排布。結(jié)構(gòu)體的定義如下表所示:

v2-a4bdc1641a4380afedc00cbc94097be0_720w.webp

3.2 rknn_matmul_tensor_attr
rknn_matmul_tensor_attr表示每個(gè)矩陣tensor的屬性,它包含了矩陣的名字、形狀、大小和數(shù)據(jù)類型。結(jié)構(gòu)體的定義如下表所示:

v2-8727bdab660341f3ee5849839835f6f5_720w.webp


3.2 rknn_matmul_io_attr
rknn_matmul_io_attr表示矩陣所有輸入和輸出tensor的屬性,它包含了矩陣A、B和C的屬性。結(jié)構(gòu)體的定義如下表所示:

v2-073652291cadd87fc65043225bb29ee5_720w.webp


3.3 rknn_quant_params
rknn_quant_params表示矩陣的量化參數(shù),包括name以及scale和zero_point數(shù)組的指針和長度,name用來標(biāo)識矩陣的名稱,它可以從初始化矩陣上下文時(shí)得到的rknn_matmul_io_attr結(jié)構(gòu)體中獲取。結(jié)構(gòu)體定義如下表所示:

v2-514cb5e8d7a5a77386abca94f554c4d3_720w.webp

3.4 rknn_matmul_shape
rknn_matmul_shape表示某個(gè)特定shape的矩陣乘法的M、K和N,在初始化動(dòng)態(tài)shape的矩陣乘法上下文時(shí),需要提供shape的數(shù)量,并使用rknn_matmul_shape結(jié)構(gòu)體數(shù)組表示所有的輸入的shape。結(jié)構(gòu)體定義如下表所示:

v2-e00b9676476285495b873417798905e5_720w.webp


4. 矩陣乘法API說明

4.1 rknn_matmul_create
該函數(shù)的功能是根據(jù)傳入的矩陣乘法規(guī)格等信息,完成矩陣乘法上下文的初始化,并返回輸入和輸出tensor的形狀、大小和數(shù)據(jù)類型等信息。

v2-0a2a96a18c257886e70426ff0a69a914_720w.webp

示例代碼如下:

rknn_matmul_info info;
memset(&info, 0, sizeof(rknn_matmul_info));
info.M = 4;
info.K = 64;
info.N = 32;
info.type = RKNN_INT8_MM_INT8_TO_INT32;
info.B_layout = RKNN_MM_LAYOUT_NORM;
info.AC_layout = RKNN_MM_LAYOUT_NORM;

rknn_matmul_io_attr io_attr;
memset(&io_attr, 0, sizeof(rknn_matmul_io_attr));

int ret = rknn_matmul_create(&ctx, &info, &io_attr);
if (ret < 0) {
   printf("rknn_matmul_create fail! ret=%d\n", ret);
   return -1;
}


4.2 rknn_matmul_set_io_mem
該函數(shù)用于設(shè)置矩陣乘法運(yùn)算的輸入/輸出內(nèi)存。在調(diào)用該函數(shù)前,先使用rknn_create_mem接口創(chuàng)建的rknn_tensor_mem結(jié)構(gòu)體指針,接著將其與rknn_matmul_create函數(shù)返回的矩陣A、B或C的
rknn_matmul_tensor_attr結(jié)構(gòu)體指針傳入該函數(shù),把輸入和輸出內(nèi)存設(shè)置到矩陣乘法上下文中。在調(diào)用該函數(shù)前,要根據(jù)rknn_matmul_info中配置的內(nèi)存排布準(zhǔn)備好矩陣A和矩陣B的數(shù)據(jù)。

v2-38ddc429d7a91c359926ee9ed0fdc09c_720w.webp


示例代碼如下:

// Create A
rknn_tensor_mem* A = rknn_create_mem(ctx, io_attr.A.size);
if (A == NULL) {
  printf("rknn_create_mem fail!\n");
  return -1;
}
memset(A->virt_addr, 1, A->size);
rknn_matmul_io_attr io_attr;
memset(&io_attr, 0, sizeof(rknn_matmul_io_attr));

int ret = rknn_matmul_create(&ctx, &info, &io_attr);
if (ret < 0) {
  printf("rknn_matmul_create fail! ret=%d\n", ret);
  return -1;
}
// Set A
ret = rknn_matmul_set_io_mem(ctx, A, &io_attr.A);
if (ret < 0) {
  printf("rknn_matmul_set_io_mem fail! ret=%d\n", ret);
  return -1;
}


4.3 rknn_matmul_set_core_mask
該函數(shù)用于設(shè)置矩陣乘法運(yùn)算時(shí)可用的NPU核心(僅支持RK3588和RK3576平臺)。在調(diào)用該函數(shù)前,需要先通過rknn_matmul_create函數(shù)初始化矩陣乘法上下文。可通過該函數(shù)設(shè)置的掩碼值,指定需要使用的核心,以提高矩陣乘法運(yùn)算的性能和效率。

v2-f99dd5af90006f8722e22c889bf800bd_720w.webp

示例代碼如下:

rknn_matmul_set_core_mask(ctx, RKNN_NPU_CORE_AUTO);


4.4 rknn_matmul_set_quant_params
rknn_matmul_set_quant_params用于設(shè)置每個(gè)矩陣的量化參數(shù),支持Per-Channel量化、Per-Layer量化和PerGroup量化方式的量化參數(shù)設(shè)置。當(dāng)使用Per-Group量化時(shí),rknn_quant_params中的scale和zp數(shù)組的長度等于N*K/group_size。當(dāng)使用Per-Channel量化時(shí),rknn_quant_params中的scale和zp數(shù)組的長度等于N。當(dāng)使用Per-Layer量化時(shí),rknn_quant_params中的scale和zp數(shù)組的長度為1。在rknn_matmul_run之前調(diào)用此接口設(shè)置所有矩陣的量化參數(shù)。如果不調(diào)用此接口,則默認(rèn)量化方式為Per-Layer量化,scale=1.0,zero_point=0。

v2-81008d929f75edb79b82757daefacbd3_720w.webp


示例代碼如下:

rknn_quant_params params_a;
memcpy(params_a.name, io_attr.A.name, RKNN_MAX_NAME_LEN);
params_a.scale_len = 1;
params_a.scale = (float *)malloc(params_a.scale_len * sizeof(float));
params_a.scale[0] = 0.2;
params_a.zp_len = 1;
params_a.zp = (int32_t *)malloc(params_a.zp_len * sizeof(int32_t));
params_a.zp[0] = 0;
rknn_matmul_set_quant_params(ctx, ¶ms_a);


4.5 rknn_matmul_get_quant_params
rknn_matmul_get_quant_params用于rknn_matmul_type類型等于RKNN_INT8_MM_INT8_TO_INT32并且Per-Channel量化方式時(shí),獲取矩陣B所有通道scale歸一化后的scale值,獲取的scale值和A的原始scale值相乘可以得到C的scale值??梢杂糜谠诰仃嘋沒有真實(shí)scale時(shí),近似計(jì)算得到C的scale。

v2-7801d3ed9a1c8dba56f5e96db826af36_720w.webp

示例代碼如下:

float b_scale;
rknn_matmul_get_quant_params(ctx, ¶ms_b, &b_scale);


4.6 rknn_matmul_create_dyn_shape(deprecated)
該接口已廢棄,改用rknn_matmul_create_dynamic_shape接口。
4.7 rknn_matmul_create_dynamic_shape
rknn_matmul_create_dynamic_shape用于創(chuàng)建動(dòng)態(tài)shape矩陣乘法上下文,該接口需要傳入rknn_matmul_info結(jié)構(gòu)體、shape數(shù)量以及對應(yīng)的shape數(shù)組,shape數(shù)組會(huì)記錄多個(gè)M、K和N值。在初始化成功后,會(huì)得到rknn_matmul_io_attr的數(shù)組,數(shù)組中包含了所有的輸入輸出矩陣的shape、大小和數(shù)據(jù)類型等信息。目前支持設(shè)置多個(gè)不同的M,K和N。

v2-2d33754930362745b467f1c7f11141e1_720w.webp

示例代碼如下:

const int shape_num = 2;
rknn_matmul_shape shapes[shape_num];
for (int i = 0; i < shape_num; ++i) {
  shapes[i].M = i+1;
  shapes[i].K = 64;
  shapes[i].N = 32;
}
rknn_matmul_io_attr io_attr[shape_num];
memset(io_attr, 0, sizeof(rknn_matmul_io_attr) * shape_num);

int ret = rknn_matmul_create_dynamic_shape(&ctx, &info, shape_num, shapes, io_attr);
if (ret < 0) {
  fprintf(stderr, " rknn_matmul_create_dynamic_shape fail! ret=%d\n", ret);
  return -1;
}


4.8 rknn_matmul_set_dynamic_shape
rknn_matmul_set_dynamic_shape用于指定矩陣乘法使用的某一個(gè)shape。在創(chuàng)建動(dòng)態(tài)shape的矩陣乘法上下文后,選取其中一個(gè)rknn_matmul_shape結(jié)構(gòu)體作為輸入?yún)?shù),調(diào)用此接口設(shè)置運(yùn)算使用的shape。

v2-019ca645721ff507b46474484895775f_720w.webp

示例代碼如下:

ret = rknn_matmul_set_dynamic_shape(ctx, &shapes[0]);
if (ret != 0) {
  fprintf(stderr, "rknn_matmul_set_dynamic_shapes fail!\n");
  return -1;
}


4.9 rknn_B_normal_layout_to_native_layout
rknn_B_normal_layout_to_native_layout用于將矩陣B的原始形狀排列的數(shù)據(jù)(KxN)轉(zhuǎn)換為高性能數(shù)據(jù)排列方式的數(shù)據(jù)。

v2-c357913103afb75951235fd38da18ce9_720w.webp


示例代碼如下:

int32_t subN = io_attr.B.dims[2];
int32_t subK = io_attr.B.dims[3];
rknn_B_normal_layout_to_native_layout(B_Matrix, B->virt_addr, K, N, subN, subK, &info);


4.10 rknn_matmul_run
該函數(shù)用于運(yùn)行矩陣乘法運(yùn)算,并將結(jié)果保存在輸出矩陣C中。在調(diào)用該函數(shù)前,輸入矩陣A和B需要先準(zhǔn)備好數(shù)據(jù),并通過rknn_matmul_set_io_mem函數(shù)設(shè)置到輸入緩沖區(qū)。輸出矩陣C需要先通過
rknn_matmul_set_io_mem函數(shù)設(shè)置到輸出緩沖區(qū),而輸出矩陣的tensor屬性則通過rknn_matmul_create函數(shù)獲取。

v2-093c659de366d50d76f161bd6e1b2a4c_720w.webp

示例代碼如下:

int ret = rknn_matmul_run(ctx);


4.11 rknn_matmul_destroy
該函數(shù)用于銷毀矩陣乘法運(yùn)算上下文,釋放相關(guān)資源。在使用完rknn_matmul_create函數(shù)創(chuàng)建的矩陣乘法上下文指針后,需要調(diào)用該函數(shù)進(jìn)行銷毀。

v2-42c8b3aeab070d695029a760313663bb_720w.webp

示例代碼如下:

int ret = rknn_matmul_destroy(ctx);


5. 自定義算子數(shù)據(jù)結(jié)構(gòu)定義


5.1rknn_gpu_op_context
rknn_gpu_op_context表示指定GPU運(yùn)行的自定義算子的上下文信息。結(jié)構(gòu)體的定義如下表所示:

v2-ca74fd3d8e1d705d4ba13eb4cbc507b7_720w.webp

5.2 rknn_custom_op_context
rknn_custom_op_context表示自定義算子的上下文信息。結(jié)構(gòu)體的定義如下表所示:

v2-4064f63bdbdac5f0c549f220d7291c1c_720w.webp

5.3 rknn_custom_op_tensor
rknn_custom_op_tensor表示自定義算子的輸入/輸出的tensor信息。結(jié)構(gòu)體的定義如下表所示:

v2-6cab1ae0df7f83b1b9c6bf4c0a0eba88_720w.webp


5.4 rknn_custom_op_attr
rknn_custom_op_attr表示自定義算子的參數(shù)或?qū)傩孕畔ⅰ=Y(jié)構(gòu)體的定義如下表所示:

v2-adf42d5cacf4a0be9dcd27c44db8924a_720w.webp

5.5 rknn_custom_op
rknn_custom_op表示自定義算子的注冊信息。結(jié)構(gòu)體的定義如下表所示:

v2-a95b72324a373a389a956ca105b75cbc_720w.webp

6. 自定義算子API說明


6.1rknn_register_custom_ops
在初始化上下文成功后,該函數(shù)用于在上下文中注冊若干個(gè)自定義算子的信息,包括自定義算子類型、運(yùn)行后端類型、OpenCL內(nèi)核信息以及回調(diào)函數(shù)指針。注冊成功后,在推理階段,rknn_run接口會(huì)調(diào)用開發(fā)者實(shí)現(xiàn)的回調(diào)函數(shù)。

v2-923622285f7136f6230ae6ec69188107_720w.webp

示例代碼如下:

// CPU operators
rknn_custom_op user_op[2];
memset(user_op, 0, 2 * sizeof(rknn_custom_op));
strncpy(user_op[0].op_type, "cstSoftmax", RKNN_MAX_NAME_LEN - 1);
user_op[0].version = 1;
user_op[0].target = RKNN_TARGET_TYPE_CPU;
user_op[0].init = custom_op_init_callback;
user_op[0].compute = compute_custom_softmax_float32;
user_op[0].destroy = custom_op_destroy_callback;

strncpy(user_op[1].op_type, "ArgMax", RKNN_MAX_NAME_LEN - 1);
user_op[1].version = 1;
user_op[1].target = RKNN_TARGET_TYPE_CPU;
user_op[1].init = custom_op_init_callback;
user_op[1].compute = compute_custom_argmax_float32;
user_op[1].destroy = custom_op_destroy_callback;

ret = rknn_register_custom_ops(ctx, user_op, 2);
if (ret < 0) {
  printf("rknn_register_custom_ops fail! ret = %d\n", ret);
  return -1;
}


6.2 rknn_custom_op_get_op_attr
該函數(shù)用于在自定義算子的回調(diào)函數(shù)中獲取自定義算子的參數(shù)信息,例如Softmax算子的axis參數(shù)。它傳入自定義算子參數(shù)的字段名稱和一個(gè)rknn_custom_op_attr結(jié)構(gòu)體指針,調(diào)用該接口后,參數(shù)值會(huì)存儲(chǔ)在rknn_custom_op_attr結(jié)構(gòu)體中的data成員中,開發(fā)者根據(jù)返回的結(jié)構(gòu)體內(nèi)dtype成員將該指針強(qiáng)制轉(zhuǎn)換成C語言中特定數(shù)據(jù)類型的數(shù)組首地址,再按照元素?cái)?shù)量讀取出完整參數(shù)值

v2-2627fff0bac777ac5f9ee22f7b5b1a70_720w.webp

示例代碼如下:

rknn_custom_op_attr op_attr;
rknn_custom_op_get_op_attr(op_ctx, "axis", &op_attr);
if (op_attr.n_elems == 1 && op_attr.dtype == RKNN_TENSOR_INT64) {
   axis = ((int64_t*)op_attr.data)[0];
}
…



7. RKNN返回值錯(cuò)誤碼


RKNN API函數(shù)的返回值錯(cuò)誤碼定義如下表所示:

v2-654f3d1a39e62cb49b77ef4fb1bb924f_720w.webp
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 人工智能
    +關(guān)注

    關(guān)注

    1821

    文章

    50388

    瀏覽量

    267149
  • 開發(fā)板
    +關(guān)注

    關(guān)注

    26

    文章

    6440

    瀏覽量

    121239
  • 瑞芯微
    +關(guān)注

    關(guān)注

    27

    文章

    866

    瀏覽量

    54691
  • EASY-EAI靈眸科技
    +關(guān)注

    關(guān)注

    4

    文章

    113

    瀏覽量

    3730
  • RV1126B
    +關(guān)注

    關(guān)注

    0

    文章

    102

    瀏覽量

    256
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    (EASY EAI)RV1126B 音頻輸入

    1.聲卡資源介紹EASY-EAI-Nano-TB僅有一塊由RV1126B主控輸出的聲卡。通過串口調(diào)試或ssh調(diào)試,可以進(jìn)入開發(fā)板終端。執(zhí)行aplay命令查看聲卡相關(guān)的詳細(xì)信息,如下所示
    的頭像 發(fā)表于 12-18 13:41 ?2633次閱讀
    <b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b>(<b class='flag-5'>EASY</b> <b class='flag-5'>EAI</b>)<b class='flag-5'>RV1126B</b> 音頻輸入

    (EASY EAI)RV1126B PWM使用

    1.PWM簡介1.1開發(fā)板PWM資源1.2查找PWM節(jié)點(diǎn)rv1126b的pwm資源表如下:【PWM1CH0】對應(yīng)的是pwm1_4ch_0,寄存地址為20700000?!綪WM1CH1】對應(yīng)
    的頭像 發(fā)表于 01-06 10:49 ?8580次閱讀
    <b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b>(<b class='flag-5'>EASY</b> <b class='flag-5'>EAI</b>)<b class='flag-5'>RV1126B</b> PWM使用

    (EASY EAI)RV1126B 音頻輸出

    1.聲卡資源介紹EASY-EAI-Nano-TB僅有一塊由RV1126B主控輸出的聲卡。通過串口調(diào)試或ssh調(diào)試,可以進(jìn)入開發(fā)板終端。執(zhí)行aplay命令查看聲卡相關(guān)的詳細(xì)信息,如下所示
    的頭像 發(fā)表于 04-01 17:13 ?8597次閱讀
    <b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b>(<b class='flag-5'>EASY</b> <b class='flag-5'>EAI</b>)<b class='flag-5'>RV1126B</b> 音頻輸出

    EASY EAI Nano-TB(RV1126B)開發(fā)板試用】+初識篇

    Nano-TB是靈眸科技研發(fā)的一款應(yīng)用于AIoT領(lǐng)域的開發(fā)板,它基于RV1126B處理器,集成了4個(gè)Cortex-A53及獨(dú)立的NEON協(xié)處理器,它支持4K@30fps的H.
    發(fā)表于 10-25 22:06

    EASY EAI Nano-TB(RV1126B)開發(fā)板試用】命令行功能測試-shell腳本進(jìn)行IO控制-紅綠燈項(xiàng)目

    接上文【EASY EAI Nano-TB(RV1126B)開發(fā)板試用】通過wifi連接,使用ssh登錄EASY EAI Nano-TB(
    發(fā)表于 11-02 18:34

    EASY EAI Nano-TB(RV1126B)開發(fā)板試用】命令行功能測試-shell腳本進(jìn)行IO控制-紅綠燈按鈕項(xiàng)目

    0接上文【EASY EAI Nano-TB(RV1126B)開發(fā)板試用】命令行功能測試-shell腳本進(jìn)行IO控制-紅綠燈項(xiàng)目-實(shí)現(xiàn)開機(jī)起動(dòng) EASYEAINano-TB(RV1126B
    發(fā)表于 11-03 10:00

    EASY EAI Nano-TB(RV1126B)開發(fā)板試用】+1、開箱上電

    ,避免因接觸不良導(dǎo)致顯示或采集異常。 2 硬件解析:強(qiáng)勁AI核心與豐富接口 2.1 核心處理器性能 EASY EAI Nano-TB開發(fā)板的核心基于
    發(fā)表于 11-19 21:39

    EASY EAI Nano-TB(RV1126B)開發(fā)板試用】介紹、系統(tǒng)安裝

    ,并介紹了系統(tǒng)鏡像安裝部署的相關(guān)流程。 介紹 EASY-EAI-Nano-TB是靈眸科技研發(fā)的一款應(yīng)用于AIoT領(lǐng)域的AIOT主板。 核心板基于
    發(fā)表于 12-23 18:05

    RV1126&RV1109替換RV1126B-P說明_V1.0

    RV1126&RV1109替換RV1126B-P說明_V1.0目前
    發(fā)表于 08-11 12:02 ?2次下載

    RV1126系列選型指南:從RV1126RV1126B,一文看懂升級差異

    2025年7月,正式發(fā)布新一代AI視覺芯片RV1126B。作為其金牌方案商,EASYEAI靈眸科技同步推出搭載該芯片的AIoT核心板EAI11
    的頭像 發(fā)表于 09-04 10:50 ?5284次閱讀
    <b class='flag-5'>RV1126</b>系列選型指南:從<b class='flag-5'>RV1126</b>到<b class='flag-5'>RV1126B</b>,一文看懂升級差異

    【免費(fèi)試用】EASY EAI Nano-TB(RV1126B)開發(fā)套件評測

    EASY-EAI-Nano-TB是靈眸科技研發(fā)的一款應(yīng)用于AIoT領(lǐng)域的AIOT主板。核心板基于RV1126B處理器設(shè)計(jì),并引入了新
    的頭像 發(fā)表于 09-23 08:09 ?1313次閱讀
    【免費(fèi)試用】<b class='flag-5'>EASY</b> <b class='flag-5'>EAI</b> Nano-TB(<b class='flag-5'>RV1126B</b>)開發(fā)套件評測

    RV1126B特性概述

    RV1126BRockchip在2025年第二季度全新推出的Arm架構(gòu)AI視覺芯片,搭載4核Cortex-A53與自研3Tops算力NPU。全面替代上一代的
    的頭像 發(fā)表于 10-09 11:22 ?2279次閱讀
    <b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b><b class='flag-5'>RV1126B</b>特性概述

    替代升級實(shí)錘!實(shí)測RV1126B,CPU性能吊打RV1126

    AI智能芯片迭代提速,推出了全新的Arm架構(gòu)AI視覺芯片RV1126B,是否替換RV1126,CPU性能是擠牙膏還是大突破。帶著這些核
    的頭像 發(fā)表于 12-11 17:13 ?2631次閱讀
    替代升級實(shí)錘!實(shí)測<b class='flag-5'>RV1126B</b>,CPU性能吊打<b class='flag-5'>RV1126</b>

    (EASY EAI)RV1126B 人體關(guān)鍵點(diǎn)識別

    的特點(diǎn)。本人員檢測算法在數(shù)據(jù)集表現(xiàn)如下所示:基于EASY-EAI-Nano-TB(RV1126B)硬件主板的運(yùn)行效率:17個(gè)人體關(guān)鍵點(diǎn)索引定義:2.快速上手2.1開發(fā)
    的頭像 發(fā)表于 01-23 10:13 ?3887次閱讀
    <b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b>(<b class='flag-5'>EASY</b> <b class='flag-5'>EAI</b>)<b class='flag-5'>RV1126B</b> 人體關(guān)鍵點(diǎn)識別

    (EASY EAI)RV1126B rknn-toolkit-lite2使用方法

    1.rknn-toolkit-lite2介紹RKNN-Toolkit-Lite2是(Rockchip)專為旗下RK系列芯片(如RV1126B、RK3576、RK3588等)打造的
    的頭像 發(fā)表于 04-22 17:38 ?693次閱讀
    <b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b>(<b class='flag-5'>EASY</b> <b class='flag-5'>EAI</b>)<b class='flag-5'>RV1126B</b> rknn-toolkit-lite2使用方法
    山东省| 滨州市| 四子王旗| 吉隆县| 白沙| 黄龙县| 石门县| 太湖县| 奇台县| 古浪县| 崇明县| 西宁市| 苏尼特右旗| 根河市| 鹿邑县| 越西县| 家居| 清苑县| 黑山县| 静海县| 江孜县| 台南市| 灵台县| 民权县| 平山县| 金湖县| 枣强县| 株洲市| 海兴县| 黄骅市| 黑山县| 黑龙江省| 赤水市| 翁源县| 松原市| 普洱| 宁阳县| 温宿县| 松潘县| 滦南县| 盐山县|