Rockchip · AI & Linux Hub

AI inference

Rockchip RKNN Runtime C API: Complete Reference for Base APIs, Matmul and Custom Operators

Complete RKNN C API V2.3.2 reference covering platform support, compilation, structures, parameters, examples and all error codes, with source inconsistencies documented.

· ArmSoM Editorial · Rockchip source documentation · 92 min read

ArmSoM applicability and source

Sources are RK-YH-YF-413, V2.3.2: 52 Chinese pages and 57 English pages. Chinese follows the Chinese original; English follows the English original, fully translated into Russian and German. Neither source contains technical illustrations or code screenshots: all technical tables are editable and all code is copyable text; no figures are invented. The source scope includes RV1103/RV1103B/RV1106/RV1106B/RV1126B, RK2118, RK3562 and the RK3566/RK3568/RK3576/RK3588 series, but individual APIs, queries and parameters are not supported on every platform; consult each support matrix. This is an ArmSoM platform-adaptation reference only. No specific board, SDK/BSP, kernel/driver combination has been verified; match RKNPU Runtime, model format and target NPU hardware. No code, hardware or performance tests were run; source examples are not ArmSoM measurements.

Editorial caution: DEVICE_MEM_INFO support prose conflicts with its matrix. Some INPUT/OUTPUT names, CPU/GPU enums and the zero-copy destruction order are also questionable. Source values are retained; this is not a verified runnable correction. Check the editorial notes and actual SDK headers before using examples.

EDITORIAL-NOTES · ArmSoM Documentation

1. Overview

RKNN C API is the C language interfaces for RKNPU Runtime (runtime library). By using the RKNN C API, developers can use the computing power of the NPU to perform efficient RKNN model inference or matrix multiplication calculation tasks. This article explains each function, data structure and return code definition of RKNN C API.

2. Supported Hardware Platforms

This document applies to the following hardware platforms:

RV1103

RV1103B

RV1106

RV1106B

RV1126B

RK2118

RK3562

RK3566 series

RK3568 series

RK3576 series

RK3588 series

3. RKNPU compilation instructions

When developers compile applications, they must include the header file where the interface function is located, and link to the corresponding RKNPU runtime library according to the hardware platform and system type used. The following describes the RKNN C API header files and runtime library files.

3.1 RKNN C API header files

According to different functional characteristics, the interface of RKNN C API can be divided into three parts. The corresponding relationships between the functions, data structure definitions and header files of each part are as follows:

1. “rknn_api.h” defines the basic interface and data structure for deploying the RKNN model.

2. “rknn_matmul_api.h” defines the matrix multiplication interface and data structure.

3. “rknn_custom_op.h” defines custom operator interface and data structure.

3.2 RKNPU Runtime Library For Linux

1. For the RK3562 , RK3566 series, RK3568 series, RK3576 series, RK3588 series and RV1126B hardware platforms, the RKNPU runtime library file is librknnrt.so in the <sdk_path>/rknpu2/runtime directory, where <sdk_path> is the path to the Rockchip NPU software development kit.

2. For RV1106/RV1103/RV1106B/RV1103B hardware platforms, the RKNPU runtime library file is librknnmrt.so in the <sdk_path>/rknpu2/runtime directory.

3.3 RKNPU Runtime Library For Android

There are two ways to call the RKNN API on the Android platform:

1. The application can link librknnrt.so directly.

2. Application link to librknn_api_android.so implemented by HIDL on Android platform.

Android devices that need to pass the CTS/VTS test need to use the RKNN API implemented based on the Android platform HIDL (librknn_api_android.so does not include matrix multiplication and custom operator functions). If the device does not need to pass the CTS/VTS test, it is recommended to use librknnrt.so directly (including matrix multiplication and custom operator functions). The link to each interface call process is shorter and can provide better performance.

The code for the RKNN API implemented using Android HIDL is located in the vendor/rockchip/hardware/interfaces/neuralnetworks directory of the

RK3562/RK3566/RK3568/RK3576/RK3588 Android system SDK. After the Android system is compiled, a series of library files related to RKNPU will be generated (for application development, you only need to link and use librknn_api_android.so), as shown below:

/vendor/lib/librknn_api_android.so
/vendor/lib/librknnhal_bridge.rockchip.so
/vendor/lib64/librknn_api_android.so
/vendor/lib64/librknnhal_bridge.rockchip.so
/vendor/lib64/rockchip.hardware.neuralnetworks@1.0.so
/vendor/lib64/rockchip.hardware.neuralnetworks@1.0-adapter-helper.so
/vendor/lib64/hw/rockchip.hardware.neuralnetworks@1.0-impl.so
/vendor/bin/hw/rockchip.hardware.neuralnetworks@1.0-service

Alternatively, user can use the following command to recompile and generate the above library separately.

mmm vendor/rockchip/hardware/interfaces/neuralnetworks/ -j8

3.4 RKNPU Runtime Library For RK2118

For the RK2118 hardware platform, the RKNPU runtime library file is located in the system SDK of the RK2118, please refer to the section “Prepare RK2118 SDK” in “Rockchip_RK2118_Quick_Start_RKNN_SDK_EN.pdf”.

4. RKNN C API Description

4.1 C API support of each hardware platform

Due to the different hardware characteristics of different chip platforms, the RKNN C API interface and interface parameter support are also different. The RKNN C API interface support of each hardware platform is shown in

Table 4-1:

Table 4-1 RKNN C API interface support for each hardware platform

  RKNN C API RV1126B/RK3562/RK3566/
RK3568
RK3576/RK3588 RV1106/RV1103/
RV1103B/RV1106B
RK2118
1 rknn_init √ √ √ √
2 rknn_set_core_mask × √ × ×
3 rknn_dup_context √ √ × ×
4 rknn_destroy √ √ √ √
5 rknn_query √ √ √ √
6 rknn_inputs_set √ √ × ×
7 rknn_run √ √ √ √
8 rknn_wait × × × ×
9 rknn_outputs_get √ √ × ×
10 rknn_outputs_release √ √ × ×
11 rknn_create_mem_from_mb_blk × × × ×
12 rknn_create_mem_from_phys √ √ √ √
13 rknn_create_mem_from_fd √ √ √ ×
14 rknn_create_mem √ √ √ √
15 rknn_destroy_mem √ √ √ √
16 rknn_set_weight_mem √ √ √ √
17 rknn_set_internal_mem √ √ √ √
18 rknn_set_io_mem √ √ √ √
19 rknn_set_input_shapes √ √ × ×
20 rknn_mem_sync √ √ √ √
21 rknn_matmul_create √ √ × ×
22 rknn_matmul_set_io_mem √ √ × ×
23 rknn_matmul_set_core_mask × √ × ×
24 rknn_matmul_run √ √ × ×
25 rknn_matmul_destroy √ √ × ×
26 rknn_register_custom_ops √ √ × ×
27 rknn_custom_op_get_op_attr √ √ × ×
28 rknn_set_batch_core_num × √ × ×
29 rknn_matmul_set_quant_params √ √ × ×
30 rknn_matmul_get_quant_params √ √ × ×
31 rknn_matmul_create_dynamic_shape √ √ × ×
32 rknn_matmul_set_dynamic_shape √ √ × ×
33 rknn_B_normal_layout_to_native_layout √ √ × ×
34 rknn_create_mem2 √ √ √ √

The query parameters supported by each hardware platform using the rknn_query function are shown in Table 4- 2:

Table 4-2 Query parameters supported by the rknn_query function on each hardware platform

  rknn_query params RV1126B/RK3562/RK3566/
RK3568
RK3576/ RK3588 RV1106/RV1103/
RV1103B/RV1106B/RK2118
1 RKNN_QUERY_IN_OUT_NUM √ √ √
2 RKNN_QUERY_INPUT_ATTR √ √ √
3 RKNN_QUERY_OUTPUT_ATTR √ √ √
4 RKNN_QUERY_PERF_DETAIL √ √ ×
5 RKNN_QUERY_PERF_RUN √ √ ×
6 RKNN_QUERY_SDK_VERSION √ √ √
7 RKNN_QUERY_MEM_SIZE √ √ √
8 RKNN_QUERY_CUSTOM_STRING √ √ √
9 RKNN_QUERY_NATIVE_INPUT_ATTR √ √ √
10 RKNN_QUERY_NATIVE_OUTPUT_ATTR √ √ √
11 RKNN_QUERY_NATIVE_NC1HWC2_INPUT_ATTR √ √ √
12 RKNN_QUERY_NATIVE_NC1HWC2_OUTPUT_ATTR √ √ √
13 RKNN_QUERY_NATIVE_NHWC_INPUT_ATTR √ √ √
14 RKNN_QUERY_NATIVE_NHWC_OUTPUT_ATTR √ √ √
15 RKNN_QUERY_INPUT_DYNAMIC_RANGE √ √ ×
16 RKNN_QUERY_DEVICE_MEM_INFO × × √
17 RKNN_QUERY_CURRENT_INPUT_ATTR √ √ ×
18 RKNN_QUERY_CURRENT_OUTPUT_ATTR √ √ ×
19 RKNN_QUERY_CURRENT_NATIVE_INPUT_ATTR √ √ ×
20 RKNN_QUERY_CURRENT_NATIVE_OUTPUT_ATTR √ √ ×

4.2 Definition of Basic Data Structcture

rknn_sdk_version

The structure rknn_sdk_version is used to indicate the version information of the RKNN SDK. The following table shows the definition:

Field Type Meaning
api_version char[] SDK API version information.
drv_version char[] SDK driver version information.

rknn_input_output_num

The structure rknn_input_output_num represents the number of input and output Tensor,The following table shows the definition:

Field Type Meaning
n_input uint32_t The number of input tensor.
n_output uint32_t The number of output tensor.

rknn_input_range

The structure rknn_input_range represents an input support shape list information. It contains the input index, the number of supported shapes, data layout format, name and shape list. The definition of the specific structure is shown in the following table:

Field Type Meaning
index uint32_t The index position of the input.
shape_number uint32_t The number of input shapes supported by the RKNN model.
fmt rknn_tensor_format The data layout format corresponding to the shape.
name char[] The name of the input.
dyn_range uint32_t[][] The input shape list, which is a two-dimensional array
containing multiple shape arrays, and the shape is stored first.
n_dims uint32_t The number of valid dimensions for each shape array.

rknn_tensor_attr

The structure rknn_tensor_attr represents the attribute of the model’s Tensor. The following table shows the definition:

Field Type Meaning
index uint32_t Indicates the index position of the input and output Tensor.
n_dims uint32_t The number of Tensor dimensions.
dims uint32_t[] Values for each dimension.
name char[] Tensor name.
n_elems uint32_t The number of Tensor data elements.
size uint32_t The memory size of Tensor data.
fmt rknn_tensor_format The format of Tensor dimension, has the following format:
RKNN_TENSOR_NCHW, RKNN_TENSOR_NHWC,
RKNN_TENSOR_NC1HWC2
type rknn_tensor_type Tensor data type, has the following data types:
RKNN_TENSOR_FLOAT32,
RKNN_TENSOR_FLOAT16, RKNN_TENSOR_INT8,
RKNN_TENSOR_UINT8, RKNN_TENSOR_INT16,
RKNN_TENSOR_UINT16, RKNN_TENSOR_INT32,
RKNN_TENSOR_INT64, RKNN_TENSOR_BOOL
qnt_type rknn_tensor_qnt_type Tensor Quantization Type, has the following types of
quantization:
RKNN_TENSOR_QNT_NONE: Not quantized;
RKNN_TENSOR_QNT_DFP: Dynamic fixed point
quantization;
RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC:
Asymmetric quantification.
fl int8_t RKNN_TENSOR_QNT_DFP: quantization parameter.
scale float RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC:
quantization parameter.
w_stride uint32_t The number of pixels that actually store one line of image data,
which is equal to the number of valid data pixels in one row +
the number of invalid pixels that are filled in for the hardware
to quickly jump to the next line (unit: per pixel) .
size_with_stride uint32_t The actual byte size of image data (including the byte size of
filled invalid pixels).
pass_through uint8_t 0: means unconverted data. 1: means converted data, Note:
Conversion includes normalization and quantization.
h_stride uint32_t This is only used in the context of multi-batch input and can be
set by users. The purpose of this is to allow NPU to read out
beginning of memory address for every batch correctly. It is
equivalent of original model input height + the number of
invalid pixels that are filled in for the hardware to quickly jump
to the next line . If its value is 0, it is the same as model input
height (unit: per pixel) .

rknn_perf_detail

The structure rknn_perf_detail represents the performance details of the model. The definition of the structure is shown in the following table: (Note: RV1106/RV1103/RV1106B/RV1103B/RK2118 unsupported)

Field Type Meaning
perf_data char* The performance details contain the running time of each layer of the network
stored in string type.
data_len uint64_t The data length of string type of perf_data.

rknn_perf_run

The structure rknn_perf_run represents the total inference time of the model. The definition of the structure is shown in the following table: (Note: RV1106/RV1103/RV1106B/RV1103B/RK2118 unsupported)

Field Type Meaning
run_duration int64_t The total inference time of the network (not including setting input/output) in
microseconds.

rknn_mem_size

The structure rknn_mem_size represents the memory allocation when the model is initialized. The definition of the structure is shown in the following table:

Field Type Meaning
total_weight_size uint32_t The memory size allocated for weights of the network.
total_internal_size uint32_t The memory size allocated for internal tensor of the network.
total_dma_allocated_size uint64_t All dma memory size allocated for the network.
total_sram_size uint32_t Only for RK3588, memory size of SRAM reserved for NPU
(Referring to the <<RK3588_NPU_SRAM_usage.md>> for
more details) .
free_sram_size uint32_t Only for RK3588, the current available SRAM (Referring to the
<<RK3588_NPU_SRAM_usage.md>> for more details) .
reserved[12] uint32_t Reserve.

rknn_tensor_mem

The structure rknn_tensor_mem represents the tensor memory information. The definition of the structure is shown in the following table:

Field Type Meaning
virt_addr void* The virtual address of tensor.
phys_addr uint64_t The physical address of tensor.
fd int32_t The file descriptor of tensor.
offset int32_t The offset of fd and virtual address.
size uint32_t The actual size of tensor.
flags uint32_t rknn_tensor_mem has the following type of flags:
RKNN_TENSOR_MEMORY_FALGS_ALLOC_INSIDE: indicates that the
rknn_tensor_mem structure is created during runtime;
RKNN_TENSOR_MEMORY_FLAGS_FROM_FD: It represents the
rknn_tensor_mem created by fd;
RKNN_TENSOR_MEMORY_FLAGS_FROM_PHYS: It represents
rknn_tensor_mem created by physical address; The user does not need to pay
attention to the flags.
priv_data void* private data.

rknn_input

The structure rknn_input represents a data input to the model, used as a parameter to the rknn_inputs_set function. The following table shows the definition:

Field Type Meaning
index uint32_t The index position of this input.
buf void* The pointer of the input data buffer.
size uint32_t The memory size of the input data buffer.
pass_through uint8_t When set to 1, buf will be directly set to the input node of the
model without any pre-processing.
type rknn_tensor_type The type of input data.
fmt rknn_tensor_format The format of input data.

rknn_output

The structure rknn_output represents a data output of the model, used as a parameter to the rknn_outputs_get function. This structure will be assigned with data after calling rknn_outputs_get. The following table shows the definition of each member of rknn_output:

Field Type Meaning
want_float uint8_t Indicates whether the output data needs to be converted to float type, this field
is set by the user.
is_prealloc uint8_t Indicates whether the buffer that stores the output data is pre-allocated, this
field is set by the user.
index uint32_t The index position of this output, this field is set by the user, this field is
returned by the interface.
buf void* The pointer pointing to the output data buffer, this field is returned by the
interface.
size uint32_t Output data buffer size in byte, this field is returned by the interface.

rknn_init_extend

The structure rknn_init_extend represents the extended information when the model is initialized. It is not available currently on RV1106/RV1103/RV1106B/RV1103B/RK2118. The definition of the structure is shown in the following table:

Field Type Meaning
ctx rknn_context The initialized rknn_context object.
real_model_offset int32_t The real offset that is in .rknn model file. Only valid when using
file path as initialized parameter or zero-copy model buffer.
real_model_size uint32_t The real size of rknn model file. Only valid when using file path
as initialized parameter or zero-copy model buffer.
model_buffer_fd int32_t The fd represented by the model memory allocated by the NPU
after initialization with the
RKNN_FLAG_MODEL_BUFFER_ZERO_COPY flag.
model_buffer_flags uint32_t The memory flag represented by the model memory allocated by
the NPU after initialization with the
RKNN_FLAG_MODEL_BUFFER_ZERO_COPY flag.
reserved uint8_t[] The reserved data.

rknn_run_extend

The structure rknn_run_extend represents the extended information during model inference. It is not available currently. The definition of the structure is shown in the following table:

Field Type Meaning
frame_id uint64_t The index of frame of current inference.
non_block int32_t 0 means blocking mode, 1 means non-blocking mode, non-blocking mode
means that the rknn_run call returns immediately.
timeout_ms int32_t The timeout of inference in milliseconds.
fence_fd int32_t For the non-blocking inference (Not Available) .

rknn_output_extend

The structure rknn_output_extend means to obtain the extended information of the output. It is not available currently. The definition of the structure is shown in the following table:

Field Type Meaning
frame_id int32_t The frame index of the output result.

rknn_custom_string

The structure rknn_custom_string represents the custom string set by the user when converting the RKNN model. The definition of the structure is shown in the following table:

Field Type Meaning
string char[] User-defined string.

4.3 Description of Basic API

rknn_init

The function of the rknn_init initialization function is to create a rknn_context object, load the RKNN model, and perform specific initialization behaviors based on the flag and rknn_init_extend structures.

API rknn_init
Description Initialize rknn context.
Parameters rknn_context *context: The pointer of rknn_context object.
  void *model: Binary data for the RKNN model or the path of RKNN model. When the
parameter size is greater than 0, model represents binary data; when the parameter size is
equal to 0, model represents the RKNN model path.
  uint32_t size: When model is stored in binary data, it indicates the size of the model. The
size is 0 when model is given as the path.
  uint32_t flag: Initialization flag, the default initialization behavior needs to be set to 0.
  rknn_init_extend: The extended information during specific initialization. It is disabled at
the moment, which indicates this must be passed by the NULL. If using share weight, it
should pass the pointer of another rknn_context pointing to another model.
Return int: Error code (See RKNN Error Code).

Sample Code:

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

Each initialization flag is explained as follows:

RKNN_FLAG_COLLECT_PERF_MASK: used to query the time of each layer of the network at runtime;

RKNN_FLAG_MEM_ALLOC_OUTSIDE: used to indicate that model input, output, weight, and intermediate tensor memory are all allocated by the user. It mainly has two functions:

1. All memory is allocated by the user, which facilitates the overall arrangement of the entire system memory.

2. Used for memory reuse, especially for situations like RV1106/RV1103/RV1106B/RV1103B/RK2118 where memory is extremely tight.

Assume that there are two models, model A and model B. These two models are designed to run in series, so the memory of the intermediate tensors of the two models can be reused. The sample code is as follows:

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: Weight used to share another model’s weight. Mainly used to simulate variable length model input (this function is replaced by the dynamic shape function after the RKNPU runtime library version is greater than or equal to 1.5.0). For example, for some speech models, the input length is variable, but because the NPU cannot support variable-length input, it is necessary to generate several RKNN models with different resolutions. Among them, only one RKNN model retains complete weights, and the other RKNN models do not have weights. When initializing an unweighted RKNN model, using this flag allows the current context to share the weights of the complete RKNN model. Assuming that two models with resolutions A and B are required, the usage process is as follows:

1. Use RKNN-Toolkit2 to generate a model with resolution A.

2. Use RKNN-Toolkit2 to generate a model with resolution B without weight. In rknn.config(), remove_weight should be set to True. The main purpose is to reduce the size of model B.

3. On the board, initialize model A normally.

4. Initialize model B through the flags of RKNN_FLAG_SHARE_WEIGHT_MEM.

5. Others should be used in the original way. The board reference code is as follows:

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: used to initialize an empty context. It can only call the rknn_query interface to query the total size of the model weight memory and the total size of the intermediate tensor, but cannot perform inference;

RKNN_FLAG_INTERNAL_ALLOC_OUTSIDE: Indicates that the intermediate tensor of the model is allocated by the user. It is often used by the user to manage and reuse the intermediate tensor memory between multiple models;

RKNN_FLAG_EXECUTE_FALLBACK_PRIOR_DEVICE_GPU: Indicates that all layers not supported by the NPU are preferred to run on the GPU, but it is not guaranteed to run on the GPU. The actual running back-end device depends on the runtime support for the operator;

RKNN_FLAG_ENABLE_SRAM: Indicates that the intermediate tensor memory is allocated on SRAM as much as possible;

RKNN_FLAG_SHARE_SRAM: used for the current context to try to share the SRAM memory address space of another context. It is required that the RKNN_FLAG_ENABLE_SRAM flag must be enabled when the current context is initialized;

RKNN_FLAG_DISABLE_PROC_HIGH_PRIORITY: Indicates that the current context uses the default process priority. If this flag is not set, the nice value of the process is -19;

RKNN_FLAG_DISABLE_FLUSH_INPUT_MEM_CACHE: The runtime does not flush input tensor cache, the user must ensure that the input tensor has flushed the cache before calling rknn_run.

RKNN_FLAG_DISABLE_FLUSH_OUTPUT_MEM_CACHE: The runtime does not actively clear the output tensor cache. In this case, direct access to output_mem->virt_addr by the user can lead to cache consistency issues. If the user intends to use output_mem->virt_addr, it is necessary to utilize rknn_mem_sync(ctx, mem, RKNN_MEMORY_SYNC_FROM_DEVICE) to refresh the cache. This flag is typically used when the output data from the NPU is not accessed by the CPU, such as when the output data is accessed by the GPU or RGA.

RKNN_FLAG_MODEL_BUFFER_ZERO_COPY: It means that the incoming model buffer of the rknn_init interface is the memory allocated by the rknn_create_mem or rknn_create_mem2 interface, and the model buffer does not need to be copied once inside the runtime to reduce the memory occupation of the runtime, but the user needs to ensure that the model memory is valid before the context is destroyed. And free that memory after destroying the context. When you initialize a context, rknn_init the rknn_init_extend parameters of the interface, whose members real_model_offset, real_model_size, model_buffer_fd, and model_buffer_flags rknn_tensor_mem returned based on the rknn_create_mem2 interface.

RKNN_MEM_FLAG_ALLOC_NO_CONTEXT: When allocating memory using rknn_create_mem2 interfaces, after setting this flag, the ctx parameter is allowed to be 0 or NULL. Thus, the user can obtain the memory allocated by the NPU driver before initializing any of the contexts, and the returned memory structure needs to be released using the rknn_destroy_mem interface, and the released interface can use any context as a parameter. Example code such as:

 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);

rknn_set_core_mask

This function sets the specific cores running inside the NPU. For now, it only works at the RK3588 and RK3576. It will return the error code if it is set on platform with a single-core NPU architecture.

API rknn_set_core_mask
Description Set the cores for the NPU.
Parameters rknn_context context: The object of rknn context.
  rknn_core_mask core_mask: The specification of NPU core setting. It has the following
choices:
RKNN_NPU_CORE_AUTO : Referring to automatic mode, meaning that it will select the
idle core inside the NPU;
RKNN_NPU_CORE_0 : Running on the NPU0 core;
RKNN_NPU_CORE_1: Runing on the NPU1 core;
RKNN_NPU_CORE_2: Runing on the NPU2 core;
RKNN_NPU_CORE_0_1: Running on both NPU0 and NPU1 core simultaneously;
RKNN_NPU_CORE_0_1_2: Running on both NPU0, NPU1 and NPU2 simultaneously.
RKNN_NPU_CORE_ALL: Running on all of NPU cores depending on the platform;
Return int: Error code (See RKNN Error Code).
rknn_context ctx;
rknn_core_mask core_mask = RKNN_NPU_CORE_0;
int ret = rknn_set_core_mask(ctx, core_mask);

For multi-cores mode (when enabling RKNN_NPU_CORE_0_1 and RKNN_NPU_CORE_0_1_2), the following ops have better acceleration : Conv, DepthwiseConvolution, Add, Concat, Relu, Clip, Relu6, ThresholdedRelu. Prelu, LeakyRelu. Other type of op will fallback to Core0 to continue running. In the future update, some ops like Pool or ConvTranpose will be supported.

rknn_set_batch_core_num

The rknn_set_batch_core_num function specifies the number of NPU cores of the multi-batch RKNN model (the model exported by setting rknn_batch_size greater than 1 during RKNN-Toolkit2 conversion). This function only supports the RK3588 and RK3576 platform.

API rknn_set_batch_core_num
Description Set the number of NPU cores for multi-batch RKNN model running.
Parameters rknn_context context: The object of rknn context.
  int core_num: Specifies the number of cores to run.
Return int: Error code (See RKNN Error Code).

Sample Code:

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

rknn_dup_context

The rknn_dup_context creates a new context object referring to the same model. The new context is useful in the condition where the weight of the model need to be reused during executing the same model on the multi-thread (Unavailable for RV1106/RV1103/RV1106B/RV1103B/RK2118) .

API rknn_dup_context
Description Creates a new context for the same model, to reuse the weight of the model.
Parameters rknn_context *context_in: The pointer of rknn_context object. After the function is called,
the obejct of the input context will be initialized.
  rknn_context *context_out: The pointer of a rknn_context output object where information
about this new created object is returned.
Return int: Error code (See RKNN Error Code).

Sample Code:

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

rknn_destroy

This function is used to release the rknn_context and its related resources.

API rknn_destroy
Description Destroy the rknn_context object and its related resources.
Parameters rknn_context context: The rknn_context object that is going to be destroyed.
Return int: Error code (See RKNN Error Code).

Sample Code:

rknn_context ctx;
int ret = rknn_destroy(ctx);

rknn_query

The rknn_query function can query the information of models and SDK, including model input and output information, layer-by-layer running time, total model inference time, SDK version, memory usage information, user-defined strings and other information.

API rknn_query
Description Query the information about the model and the SDK.
Parameters rknn_context context: The object of rknn_contex.
  rknn_query_cmd : The query command.
  void* info: The structure object that stores the result of the query.
  uint32_t size: The size of the info structure object.
Return int: Error code (See RKNN Error Code).

Currently, the SDK supports following query commands:

Query command Return result
structure
Function
RKNN_QUERY_IN_OUT_NUM rknn_input_output_num Query the number of input and output Tensors.
RKNN_QUERY_INPUT_ATTR rknn_tensor_attr Query the input Tensor attribute.
RKNN_QUERY_OUTPUT_ATTR rknn_tensor_attr Query the output Tensor attribute.
RKNN_QUERY_PERF_DETAIL rknn_perf_detail Query the running time of each layer of the network. It
only works when the flag of
RKNN_FLAG_COLLECT_PERF_MASK is set via
using the rknn_init.
RKNN_QUERY_PERF_RUN rknn_perf_run Query the total time of inference (excluding time in
setting input/output) in microseconds .
RKNN_QUERY_SDK_VERSION rknn_sdk_version Query the SDK version.
RKNN_QUERY_MEM_SIZE rknn_mem_size Query the memory size allocated for the weights and
internal tensors in the network.
RKNN_QUERY_CUSTOM_STRING rknn_custom_string Query the user-defined strings in the RKNN model.
RKNN_QUERY_NATIVE_INPUT_ATTR rknn_tensor_attr When using the zero-copy API interface, it queries the
native input Tensor attribute, which is the model input
attribute directly read by the NPU.
RKNN_QUERY_NATIVE_OUTPUT_ATTR rknn_tensor_attr When using the zero-copy API interface, query the native
output Tensor attribute, which is the model output
attribute directly from the NPU.
RKNN_QUERY_NATIVE_NC1HWC2_INPUT_ATTR rknn_tensor_attr When using the zero-copy API interface, it queries the
native input Tensor attribute, which is the model input
attribute directly read by the NPU.it is same with
RKNN_QUERY_NATIVE_INPUT_ATTR.
RKNN_QUERY_NATIVE_NC1HWC2_OUTPUT_ATTR rknn_tensor_attr When using the zero-copy API interface, it queries the
native output Tensor attribute, which is the model input
attribute directly read by the NPU.it is same with
RKNN_QUERY_NATIVE_OUTPUT_ATTR.
RKNN_QUERY_NATIVE_NHWC_INPUT_ATTR rknn_tensor_attr When using the zero-copy API interface, it queries the
native input Tensor attribute, which is the model input
attribute directly read by the NPU.it is same with
RKNN_QUERY_NATIVE_INPUT_ATTR.
RKNN_QUERY_NATIVE_NHWC_OUTPUT_ATTR rknn_tensor_attr When using the zero-copy API interface, it queries the
native output NHWC Tensor attribute, which is the
model input attribute directly read by the NPU.
RKNN_QUERY_DEVICE_MEM_INFO rknn_tensor_mem Query the memory properties of the model buffer.
RKNN_QUERY_INPUT_DYNAMIC_RANGE rknn_input_range When using the RKNN model that supports dynamic
shapes, query the model to support input information
such as the number of shapes, list, data layout and name
corresponding to the shape.
RKNN_QUERY_CURRENT_INPUT_ATTR rknn_tensor_attr When using the RKNN model that supports dynamic
shapes, query the input attributes used by the model for
current inference.
RKNN_QUERY_CURRENT_OUTPUT_ATTR rknn_tensor_attr When using the RKNN model that supports dynamic
shapes, query the output attributes used by the model for
current inference.
RKNN_QUERY_CURRENT_NATIVE_INPUT_ATTR rknn_tensor_attr When using the RKNN model that supports dynamic
shapes, query the NPU native input attributes used by the
model’s current inference.
RKNN_QUERY_CURRENT_NATIVE_OUTPUT_ATTR rknn_tensor_attr When using the RKNN model that supports dynamic
shapes, query the NPU native output attributes used by
the model’s current inference.

Next we will explain each query command in detail.

1. Query the SDK version

The RKNN_QUERY_SDK_VERSION command can be used to query the version information of the RKNN SDK. You need to create the rknn_sdk_version structure object first.

Sample Code:

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. Query the number of input and output Tensor

The RKNN_QUERY_IN_OUT_NUM command can be used to query the number of model input and output Tensor. You need to create the rknn_input_output_num structure object first.

Sample Code:

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. Query input Tensor attribute (for general API interface)

The RKNN_QUERY_INPUT_ATTR command can be used to query the attribute of the model input Tensor. You need to create the rknn_tensor_attr structure object first (Note: the tensor queried by

RV1106/RV1103/RV1106B/RV1103B/RK2118 is the tensor originally entered as native) .

Sample Code:

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. Query output Tensor attribute (for general API interface)

The RKNN_QUERY_OUTPUT_ATTR command can be used to query the attribute of the model output Tensor. You need to create the rknn_tensor_attr structure object first.

Sample Code:

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. Query layer-by-layer inference time of model

After the rknn_run interface is called, the RKNN_QUERY_PERF_DETAIL command can be used to query the layer-by-layer inference time in microseconds. The premise of using this command is that the flag parameter of the rknn_init interface needs to include the RKNN_FLAG_COLLECT_PERF_MASK flag.

Sample Code:

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. Query total inference time of model

After the rknn_run interface is called, the RKNN_QUERY_PERF_RUN command can be used to query the inference time of the model (not including setting input/output) in microseconds.

Sample Code:

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. Query the memory allocation of the model

After the rknn_init interface is called, when the user needs to allocate memory for network by themself, the RKNN_QUERY_MEM_SIZE command can be used to query the weights of the model and the internal memory (excluding input and output) in the network. The requirement of using this command is that the flag parameter of the rknn_init interface needs to enable the RKNN_FLAG_MEM_ALLOC_OUTSIDE flag.

Sample Code:

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. Query User-defined string in the model

After the rknn_init interface is called, if the user has added custom strings when generating the RKNN model, the RKNN_QUERY_CUSTOM_STRING command can be used to retrieve user-defined strings. For example, when converting the RKNN model, the user fills in the custom characters of “RGB” to identify that the RKNN model input is a three-channel image in RGB format instead of a three-channel image in BGR format. At runtime, the data is converted into an RGB image based on the queried “RGB” information.

Sample Code:

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. Query native input tensor attribute (for zero-copy API interface)

The RKNN_QUERY_NATIVE_INPUT_ATTR command(the same to RKNN_QUERY_NATIVE_NC1HWC2_INPUT_ATTR) can be used to query the native attribute of the model input Tensor. User need to create the rknn_tensor_attr structure object first.

Sample Code:

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. Query native output tensor attribute (for zero-copy API interface)

The RKNN_QUERY_NATIVE_OUTPUT_ATTR command(the same to RKNN_QUERY_NATIVE_NC1HWC2_OUTPUT_ATTR) can be used to query the native attribute of the model output Tensor. User need to create the rknn_tensor_attr structure object first.

Sample Code:

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. Query native output tensor attribute (for zero-copy API interface)

The RKNN_QUERY_NATIVE_NHWC_INPUT_ATTR command can be used to query the NHWC attribute of the model input Tensor. User need to create the rknn_tensor_attr structure object first.

Sample Code:

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. Query native output tensor attribute (for zero-copy API interface)

The RKNN_QUERY_NATIVE_NHWC_OUTPUT_ATTR command can be used to query the NHWC attribute of the model output Tensor. User need to create the rknn_tensor_attr structure object first.

Sample Code:

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. Query the dynamic input shape information supported by the RKNN model (Note: RV1106/RV1103/RV1106B/RV1103B/RK2118 does not support this interface)

After the rknn_init interface is called, pass in the RKNN_QUERY_INPUT_DYNAMIC_RANGE command to query the input shape information supported by the model, including the number of input shapes, the list of input shapes, the layout and name of the input shapes, and other information. The rknn_input_range structure object needs to be created first.

The sample code is as follows:

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));
}
14. Query the memory information of model buffer(Note: RV1106/RV1103/RV1106B/RV1103B/RK2118 does not support this interface)

After the rknn_init interface is called, the RKNN_QUERY_DEVICE_MEM_INFO command can query the attributes of the model buffer created inside the runtime, including fd and physical address.

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));
15. Query the input dynamic shape currently used by the RKNN model

After the rknn_set_input_shapes interface is called, pass in the RKNN_QUERY_CURRENT_INPUT_ATTR command to query the input attribute information currently used by the model. The rknn_tensor_attr structure needs to be created first (Note:

RV1106/RV1103/RV1103B/RV1106B/RK2118 does not support this command).

The sample code is as follows:

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. Query the output dynamic shape currently used by the RKNN model

After the rknn_set_input_shapes interface is called, pass in the RKNN_QUERY_CURRENT_OUTPUT_ATTR command to query the output attribute information currently used by the model. The rknn_tensor_attr structure needs to be created first (Note:

RV1106/RV1103/RV1103B/RV1106B/RK2118 does not support this command).

The sample code is as follows:

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. Query the native input dynamic shape currently used by the RKNN model

After the rknn_set_input_shapes interface is called, pass in the RKNN_QUERY_CURRENT_NATIVE_INPUT_ATTR command to query the native input attribute information currently used by the model. The rknn_tensor_attr structure needs to be created first (Note:

RV1106/RV1103/RV1103B/RV1106B/RK2118 does not support this command).

The sample code is as follows:

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. Query the native output dynamic shape currently used by the RKNN model

After the rknn_set_input_shapes interface is called, pass in the RKNN_QUERY_CURRENT_OUTPUT_ATTR command to query the native output attribute information currently used by the model. The rknn_tensor_attr structure needs to be created first (Note:

RV1106/RV1103/RV1103B/RV1106B/RK2118 does not support this command).

The sample code is as follows:

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));
}

rknn_inputs_set

The input data of the model can be set by the rknn_inputs_set function. This function can support multiple inputs, each of which is a rknn_input structure object. The user needs to set these object field before passing in rknn_inputs_set function (Note: unavailable on RV1106/RV1103/RV1103B/RV1106B/RK2118).

API rknn_inputs_set
Description Set the model input data.
Parameter rknn_context context: The object of rknn_contex.
  uint32_t n_inputs: Number of inputs.
  rknn_input inputs[]: Array of rknn_input.
Return int: Error code (See RKNN Error Code).

Sample Code:

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);

rknn_run

The rknn_run function will perform a model inference. The input data need to be configured by the rknn_inputs_set function or zero-copy interface before rknn_run is called.

API rknn_run
Description Perform a model inference.
Parameter rknn_context context: The object of rknn_contex.
  rknn_run_extend* extend: Reserved for extension. It is not used currently and accepted
NULL only.
Return int: Error code (See RKNN Error Code).

Sample Code:

ret = rknn_run(ctx, NULL);

rknn_outputs_get

The rknn_outputs_get function can get the output data from the model. This function can get multiple output data, each of which is a rknn_output structure object that needs to be created and initialized in turn before the function is called (Note: RV1106/RV1103/RV1106B/RV1103B/RK2118 unsupported) .

There are two ways to store buffers for output data:

1. The user allocate and release buffers themselves. In this case, the rknn_output.is_prealloc needs to be set to 1, and the rknn_output.buf points to users’ allocated buffer.

2. The other is allocated by rknn. At this time, the rknn_output .is_prealloc needs to be set to 0. After the function is executed, rknn_output.buf will be created and store the output data.

API rknn_outputs_get
Description Get model inference output data.
Parameter rknn_context context: The object of rknn_context.
  uint32_t n_outputs: Number of output.
  rknn_output outputs[]: Array of rknn_output.
  rknn_run_extend* extend: Reserved for extension, currently not used yet. Accepting NULL
only.
Return int: Error code (See RKNN Error Code).

Sample Code:

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);

rknn_outputs_release

The rknn_outputs_release function will release the relevant resources of the rknn_output object.

API rknn_outputs_release
Description Release the rknn_output object.
Parameter rknn_context context: rknn_context object.
  uint32_t n_outputs: Number of output.
  rknn_output outputs[]: The array of rknn_output to be released.
Return int: Error code (See RKNN Error Code).

Sample Code:

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

rknn_create_mem_from_phys

When the user wants to allocate memory for NPU, the rknn_create_mem_from_phys function can create a rknn_tensor_mem structure and return its pointer. This function will pass the physical address, virtual address and size, and the information related to the external memory to the rknn_tensor_mem structure.

API rknn_create_mem_from_phys
Description Create rknn_tensor_mem structure and allocate memory through physical address.
Parameter rknn_context context: rknn_context object.
  uint64_t phys_addr: The physical address of buffer.
  void *virt_addr: The virtual address of buffer, it is the start address of the memory
corresponding to fd.
  uint32_t size: The size of buffer.
Return rknn_tensor_mem*: The tensor memory information structure pointer.

Sample Code:

//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);

rknn_create_mem_from_fd

When the user wants to allocate the memory for NPU, the rknn_create_mem_from_fd creates a rknn_tensor_mem structure and return its pointer. This function filled with the file descriptor, logical address and size, and the information related to the external memory will be assigned to the rknn_tensor_mem structure.

API rknn_create_mem_from_fd
Description
Parameter
Create rknn_tensor_mem structure and allocate memory through file descriptor.
  rknn_context context: rknn_context object.
  int32_t fd: The file descriptor of buffer.
  void *virt_addr: The virtual address of buffer, which indicates the beginning of
fd.
  uint32_t size: The size of buffer.
  int32_t offset: The offset corresponding for file descriptor and virtual address.
Return rknn_tensor_mem*: The tensor memory information structure pointer.

Sample Code:

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

rknn_create_mem

When the user wants to allocate memory which can be used directly in the NPU, the rknn_create_mem function can allocate the memory size specified by the user and return a rknn_tensor_mem structure.

API rknn_create_mem
Description Create rknn_tensor_mem structure internally and allocate memory during runtime.
Parameter rknn_context context: rknn_context object.
  uint32_t size: The size of buffer.
Return rknn_tensor_mem*: The tensor memory information structure pointer.

Sample Code:

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

rknn_create_mem2

When the user wants to allocate memory which can be used directly in the NPU, the rknn_create_mem2 function can allocate the memory size and memory type specified by the user and return a rknn_tensor_mem structure.

API rknn_create_mem2
Description Create rknn_tensor_mem structure internally and allocate memory during runtime.
Parameter rknn_context context: rknn_context object.
  uint64_t size: The size of buffer.
  uint64_t alloc_flags: Controls whether the allocated memory is cacheable.
RKNN_FLAG_MEMORY_CACHEABLE:Create cacheable memory.
RKNN_FLAG_MEMORY_NON_CACHEABLE: Create non-cacheable memory.
RKNN_FLAG_MEMORY_FLAGS_DEFAULT:same with
RKNN_FLAG_MEMORY_CACHEABLE
Return rknn_tensor_mem*: The tensor memory information structure pointer.

The main difference between rknn_create_mem2 and rknn_create_mem is that rknn_create_mem2 brings an alloc_flags, which can specify whether the allocated memory is cacheable, while rknn_create_mem cannot be specified, and the default is cacheable.

Sample Code:

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

rknn_destroy_mem

The rknn_destroy_mem function destroys the rknn_tensor_mem structure. However, the memory allocated by the user needs to be released manually.

API rknn_destroy_mem
Description Destroy rknn_tensor_mem structure.
Parameter rknn_context context: rknn_context object.
  rknn_tensor_mem*: The tensor memory information structure pointer.
Return int: Error code (See RKNN Error Code).

Sample Code:

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

rknn_set_weight_mem

If the user has allocated memory for the network weights, after initializing the corresponding rknn_tensor_mem structure, the NPU can use the memory through the rknn_set_weight_mem function. This function must be called before calling rknn_run.

API rknn_set_weight_mem
Description Set up the rknn_tensor_mem structure containing weights memory information.
Parameter rknn_context context: rknn_context object.
  rknn_tensor_mem*: The tensor memory information structure pointer.
Return int: Error code (See RKNN Error Code).

Sample Code:

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

rknn_set_internal_mem

If the user has allocated memory for the internal tensor in network, after initializing the corresponding rknn_tensor_mem structure, the NPU can use the memory through the rknn_set_internal_mem function. This function must be called before calling rknn_run.

API rknn_set_internal_mem
Description Set up the rknn_tensor_mem structure containing internal tensor memory information in
network.
Parameter rknn_context context: rknn_context object.
  rknn_tensor_mem*: The pointer to the tensor memory information structure.
Return int: Error code (See RKNN Error Code).

Sample Code:

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

rknn_set_io_mem

If the user has allocated memory for the input/output tensor in network, after initializing the corresponding rknn_tensor_mem structure, the NPU can use the memory through the rknn_set_io_mem function. This function must be called before calling rknn_run.

API rknn_set_io_mem
Description Set up the rknn_tensor_mem structure containing input/output tensor memory information
in network.
Parameter rknn_context context: rknn_context object.
  rknn_tensor_mem*: The pointer to the tensor memory information structure .
  rknn_tensor_attr *: The attribute of input or output tensor buffer.
Return int: Error code (See RKNN Error Code).

Sample Code:

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]);

rknn_set_input_shape(deprecated)

This interface has been deprecated. Please use the rknn_set_input_shapes interface to bind input shapes. The current version is unavailable. If you want to continue using this interface, please use version 1.5.0 SDK and refer to the usage guide document of version 1.5.0.

rknn_set_input_shapes

For dynamic shape input RKNN models, the currently used input shape must be specified before inference. The interface passes in the number of inputs and the rknn_tensor_attr array, which contains each input shape and corresponding data layout information. The index, name, shape (dims) and memory layout information (fmt) of each rknn_tensor_attr structure object must be filled. Other members of the rknn_tensor_attr structure do not need to be set. Before using this interface, you can use the rknn_query function to query the number of input shapes and the list of dynamic shapes supported by the RKNN model, and the shape of the input data is required to be in the list of input shapes supported by the model. When running for the first time or switching a new input shape every time, you need to call this interface to set a new shape, otherwise, you don’t need to call this interface repeatedly.

API rknn_set_input_shapes
Description Set the input shape currently used by the model.
Parameter rknn_context context: rknn_context object.
  uint32_t n_inputs: The number of input tensors。
  rknn_tensor_attr *: The attribute array pointer of tensor to pass all the input shape
information. The user needs to set the index, name, dims, fmt, and n_dims members of each
input attribute structure, and other members do not need to be set.
Return int: Error code (See RKNN Error Code).

Sample Code:

for (int i = 0; i < io_num.n_input; i++) {
  for (int j = 0; j < input_attrs[i].n_dims; ++j) {
    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;
}

rknn_mem_sync

The memory created by the rknn_create_mem function has the cacheable flag by default. For the memory created with the cacheable flag, when it is used by the CPU and NPU at the same time, the cache behavior will cause data consistency problems. This interface is used to synchronize a memory created with the cacheable flag to ensure that the data accessed by the CPU and NPU in this memory is consistent.

API rknn_mem_sync
Description Synchronize CPU cache and DDR data.
Parameter rknn_context context: rknn_context object.
  rknn_tensor_mem* mem: tensor memory information structure pointer.
  rknn_mem_sync_mode mode: Indicates the mode for refreshing CPU cache and DDR data.
RKNN_MEMORY_SYNC_TO_DEVICE: Indicates that the CPU cache data is
synchronized to the DDR. This mode is usually used to write the data in the cache back to
the DDR before the NPU accesses the same memory after the CPU writes to the memory.
RKNN_MEMORY_SYNC_FROM_DEVICE: Indicates that DDR data is synchronized
to the CPU cache. It is usually used after the NPU writes to the memory. Use this mode to
make the cache data invalid the next time the CPU accesses the same memory, and the CPU
re-reads the data from the DDR.
RKNN_MEMORY_SYNC_BIDIRECTIONAL: Indicates that the CPU cache data is
synchronized to the DDR and the CPU re-reads the data from the DDR.
Return int: Error code (See RKNN Error Code).

Sample Code:

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;
}

4.4 Definition of Matrix Multiplication Data Structure

rknn_matmul_info

rknn_matmul_info indicates the specification information for performing matrix multiplication, which includes the size of matrix multiplication, data type and memory arrangement of input and output matrices. The definition of the structure is shown in the following table:

Field Type Meaning
M int32_t The number of rows of the A matrix.
K int32_t The number of columns of the A matrix.
N int32_t The number of columns of the B matrix.
type rknn_matmul_type Data type of input and output matrices:
RKNN_FLOAT16_MM_FLOAT16_TO_FLOAT32: Indicates
that matrices A and B are of type float16, and matrix C is of type
float;
RKNN_INT8_MM_INT8_TO_INT32: Indicates that matrices A
and B are of type int8, and matrix C is of type int32;
RKNN_INT8_MM_INT8_TO_INT8: Indicates that matrices A
and B are of type int8, and matrix C is of type int8;
RKNN_FLOAT16_MM_FLOAT16_TO_FLOAT16::
Indicates that matrices A and B are of type float16, and matrix C
is of type float16;
RKNN_FLOAT16_MM_INT8_TO_FLOAT32: Indicates that
matrix A is of type float16, matrix B is type int8, and matrix C is
type float;
RKNN_FLOAT16_MM_INT8_TO_FLOAT16: Indicates that
matrix A is of type float16, matrix B is type int8, and matrix C is
type float16;
RKNN_FLOAT16_MM_INT4_TO_FLOAT32: Indicates that
matrix A is of type float16, matrix B is type int4, and matrix C is
type float;
RKNN_FLOAT16_MM_INT4_TO_FLOAT16: Indicates that
matrix A is of type float16, matrix B is type int4, and matrix C is
type float16;
RKNN_INT8_MM_INT8_TO_FLOAT32: Indicates that
matrices A and B are of type int8, and matrix C is of type float;
RKNN_INT4_MM_INT4_TO_INT16: Indicates that matrices A
and B are of type int4, and matrix C is of type int16;
RKNN_INT8_MM_INT4_TO_INT32: Indicates that matrix A
is of type int8, matrix B is type int4, and matrix C is type int32;
B_layout int16_t The memory layout of the B matrix. 0: Indicates [K,N] shape
arrangement.
RKNN_MM_LAYOUT_NORM: Indicates that matrix B is
arranged according to the original shape, i.e. the shape of KxN;
RKNN_MM_LAYOUT_NATIVE: Indicates that matrix B is
arranged in a high-performance shape
RKNN_MM_LAYOUT_TP_NORM: Matrix B is arranged
according to the shape after Transpose, i.e., the shape row of NxK
B_quant_type int16_t Specifies the type of quantization method for matrix B.
RKNN_QUANT_TYPE_PER_LAYER_SYM: Matrix B is
symmetrically quantized according to the Per-Layer method;
RKNN_QUANT_TYPE_PER_LAYER_ASYM: Matrix B is
asymmetrically quantized according to the Per-Layer method;
RKNN_QUANT_TYPE_PER_CHANNEL_SYM: Matrix B is
symmetrically quantized according to the Per-Channel method ;
RKNN_QUANT_TYPE_PER_CHANNEL_ASYM: indicates
that matrix B is asymmetrically quantized in the Per-Channel
mode;
RKNN_QUANT_TYPE_PER_GROUP_SYM: indicates that
matrix B is symmetrically quantized in the Per-Group mode;
RKNN_QUANT_TYPE_PER_GROUP_ASYM: Matrix B is
asymmetrically quantified according to the Per-Group method
AC_layout int16_t Specifies how the data is arranged for Matrix A and Matrix C.
RKNN_MM_LAYOUT_NORM: Indicates that matrices A and
C are arranged in their original shapes;
RKNN_MM_LAYOUT_NATIVE: Represents matrices A and C
arranged in high-performance shapes
AC_quant_type int16_t Specifies the quantization type of matrices A and C.
RKNN_QUANT_TYPE_PER_LAYER_SYM: Represents the
symmetrical quantization of matrices A and C in a Per-Layer
method;
RKNN_QUANT_TYPE_PER_LAYER_ASYM: Represents the
asymmetric quantization of matrices A and C in the Per-Layer
method
iommu_domain_id int32_t The index of the IOMMU address space domain where the matrix
context resides. The IOMMU address space corresponds to the
context one-to-one, and the size of each IOMMU address space is
4 GB. This parameter is mainly used when the parameters of
matrices A, B, and C are large and need to be switched to another
domain after the NPU allocated more than 4 GB of memory in
one domain.
group_size int16_t The number of elements in a group takes effect only when group
quantization is enabled.
reserved int8_t[] Reservation field.

rknn_matmul_tensor_attr

rknn_matmul_tensor_attr represents the attribute of each matrix tensor, which includes the name, shape, size and data type of the matrix. The definition of the structure is shown in the following table:

Field Type Meaning
name char[] The name of the matrix.
n_dims uint32_t The number of dimensions of the matrix.
dims uint32_t[] The shape of the matrix.
size uint32_t the size of the matrix.
type rknn_tensor_type The data type of matrix

rknn_matmul_io_attr

rknn_matmul_io_attr represents the attributes of all input and output tensors of the matrix, which includes the attributes of matrices A, B, and C. The definition of the structure is shown in the following table:

Field Type Meaning
A rknn_matmul_tensor_attr The tensor attribute of matrix A.
B rknn_matmul_tensor_attr The tensor attribute of matrix B.
C rknn_matmul_tensor_attr The tensor attribute of matrix C.

rknn_quant_params

rknn_quant_params represents the quantization parameters of the matrix, including name and the pointers and lengths of the scale and zero_point arrays. name is used to identify the name of the matrix, which can be obtained from the rknn_matmul_io_attr structure obtained when initializing the matrix context. The structure definition is shown in the following table:

Field Type Meaning
name char[] The name of the matrix.
scale float* The scale array pointer of matrix.
scale_len int32_t The scale array length of the matrix
zp int32_t* The zero_point array pointer of matrix
zp_len int32_t The zero_point array length of matrix

rknn_matmul_shape

rknn_matmul_shape represents the M, K and N of matrix multiplication of a specific shape. When initializing the matrix multiplication context of a dynamic shape, you need to provide the number of shapes and use the rknn_matmul_shape structure array to represent all input shapes. The structure definition is shown in the following table:

Field Type Meaning
M int32_t The number of rows of the A matrix.
K int32_t The number of columns of matrix A.
N int32_t The number of columns of matrix C.

4.5 Description of Matrix Multiplication API

rknn_matmul_create

The function of this function is to complete the initialization of the matrix multiplication context based on the incoming matrix multiplication specification and other information, and return the shape, size, data type and other information of the input and output tensor. Here, the rknn_matmul_ctx pointer and rknn_context are the same data structure.

API rknn_matmul_create
Description Initializes the matrix multiplication context.
Parameters rknn_matmul_ctx* ctx: Matrix multiplication context pointer.
  rknn_matmul_info* info: Pointer to the specification information structure of matrix
multiplication.
  rknn_matmul_io_attr* io_attr: Pointer to the matrix multiplication input and output tensor
attribute structure.
Return int: Error code (See RKNN Error Code).

Sample Code:

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;
}

rknn_matmul_set_io_mem

This function is used to set the input/output memory for the matrix multiplication operation. Before calling this function, first use the rknn_tensor_mem structure pointer created by the rknn_create_mem interface, and then pass it into the function with the rknn_matmul_tensor_attr structure pointer of the matrix A, B or C returned by the rknn_matmul_create function, and set the input and output memory to the matrix multiplication in context. Before calling this function, the data of matrix A and matrix B should be prepared according to the memory arrangement configured in rknn_matmul_info.

API rknn_matmul_set_io_mem
Description Sets the input/output memory for matrix multiplication.
Parameters rknn_matmul_ctx ctx: Matrix multiplication context.
  rknn_tensor_mem* mem: Pointer to tensor memory information structure.
  rknn_matmul_tensor_attr* attr: Pointer to matrix multiplication input and output tensor
attribute structure.
Return int: Error code (See RKNN Error Code).

Sample Code:

// 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;
}

rknn_matmul_set_core_mask

This function is used to set the available NPU cores for matrix multiplication (only RK3588 and RK3576 platform is supported). Before calling this function, you need to initialize the matrix multiplication context through the rknn_matmul_create function. The mask value that can be set by this function specifies the cores that need to be used to improve the performance and efficiency of matrix multiplication operations.

API rknn_matmul_set_core_mask
Description Sets the NPU core mask for matrix multiply operations.
Parameters rknn_matmul_ctx ctx: Matrix multiplication context.
  rknn_core_mask core_mask: The NPU core mask value of the matrix multiplication
operation, which is used to specify the available NPU cores. Each bit of the mask represents
a core. If the corresponding bit is 1, it means that the core is available; otherwise, it means
that the core is unavailable (see rknn_set_core_mask API parameters for detailed mask
description).
Return int: Error code (See RKNN Error Code).

Sample Code:

rknn_matmul_set_core_mask(ctx, RKNN_NPU_CORE_AUTO);

rknn_matmul_set_quant_params

rknn_matmul_set_quant_params is used to set the quantization parameters of each matrix, and supports two methods of quantization parameter settings: Per-Channel quantization and Per-Layer quantization. When using Per-Channel quantization, the length of the scale and zp arrays in rknn_quant_params is equal to N. When using Per-Layer quantization, the scale and zp arrays in rknn_quant_params have length 1. Call this interface before rknn_matmul_run to set the quantization parameters of all matrices. If this interface is not called, the default quantization method is Per-Layer quantization, scale=1.0, zero_point=0.

API rknn_matmul_set_quant_params
Description Set the quantization parameters of the matrix.
Parameters rknn_matmul_ctx ctx: matrix multiplication context.
  rknn_quant_params* params: quantization parameter information of the matrix.
Return int: Error code (See RKNN Error Code).

Sample Code:

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, &params_a);

rknn_matmul_get_quant_params

rknn_matmul_get_quant_params is used when the rknn_matmul_type type is equal to RKNN_INT8_MM_INT8_TO_INT32 and the Per-Channel quantization mode is used to obtain the scale values of all channels of matrix B after scale normalization. The obtained scale value is multiplied by the original scale value of A to obtain the scale value of C. It can be used to approximately calculate the scale of C when the matrix C does not have a real scale.

API rknn_matmul_get_quant_params
Description Get the quantization parameters of matrix B.
Parameters rknn_matmul_ctx ctx: matrix multiplication context.
  rknn_quant_params* params: quantization parameter information of matrix B.
  float* scale: scale pointer of matrix B.
Return int: Error code (See RKNN Error Code).

Sample Code:

float b_scale;
rknn_matmul_get_quant_params(ctx, &params_b, &b_scale);

rknn_matmul_create_dynamic_shape

rknn_matmul_create_dynamic_shape is used to create a dynamic shape matrix multiplication context. This interface needs to pass in the rknn_matmul_info structure, the number of shapes and the corresponding shape array. The shape array will record multiple M, K and N values. After successful initialization, you will get the array of rknn_matmul_io_attr, which contains the shape, size and data type of all input and output matrices. Currently, it only supports setting multiple different M, K and N.

API rknn_matmul_create_dynamic_shape
Description Initialize the context for dynamic shape matrix multiplication.
Parameters rknn_matmul_ctx *ctx: matrix multiplication context pointer.
  rknn_matmul_info* info: matrix multiplication specification information structure pointer.
Among them, M, K and N do not need to be set.
  int shape_num: The number of shapes supported by the matrix context.
  rknn_matmul_shape dynamic_shapes[]: Shape array supported by matrix context.
  rknn_matmul_io_attr io_attrs[]: matrix multiplication input and output tensor attribute
structure array.
Return int: Error code (See RKNN Error Code).

Sample Code:

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;
}

rknn_matmul_create_dyn_shape(deprecated)

This interface has been deprecated and the rknn_matmul_create_dynamic_shape interface has been used instead.

rknn_matmul_set_dynamic_shape

rknn_matmul_set_dynamic_shape is used to specify a certain shape used in matrix multiplication. After creating the matrix multiplication context of the dynamic shape, select one of the rknn_matmul_shape structures as the input parameter, and call this interface to set the shape used for the operation.

API rknn_matmul_set_dynamic_shape
Description Set matrix multiplication shape.
Parameters rknn_matmul_ctx ctx: matrix multiplication context.
  rknn_matmul_shape* shape: Specifies the shape used for matrix multiplication.
Return int: Error code (See RKNN Error Code).

Sample Code:

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

rknn_B_normal_layout_to_native_layout

rknn_B_normal_layout_to_native_layout is used to convert data arranged in the original shape of matrix B (KxN) into data arranged in a high-performance data arrangement.

API rknn_B_normal_layout_to_native_layout
Description Convert the data arrangement of matrix B from the original shape to a high-performance
shape.
Parameters void* B_input: Matrix B data pointer of original shape.
  void* B_output: High-performance shape matrix B data pointer.
  int K: The number of rows of matrix B.
  int N: The number of columns of matrix B.
  int subN: equal to B.dims[2] in the rknn_matmul_io_attr structure.
  int subK: equal to B.dims[3] in the rknn_matmul_io_attr structure.
  rknn_matmul_info* info: The information struct pointer for matrix multiplication.
Return int: Error code (See RKNN Error Code).

Sample Code:

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);

rknn_matmul_run

This function is used to run a matrix multiplication operation and save the result in the output matrix C. Before calling this function, the input matrices A and B need to prepare data first, and set them to the input buffer through the rknn_matmul_set_io_mem function. The output matrix C needs to be set to the output buffer through the rknn_matmul_set_io_mem function, and the tensor attribute of the output matrix is obtained through the rknn_matmul_create function.

API rknn_matmul_run
Description Perform a matrix multiplication operation.
Parameters rknn_matmul_ctx ctx: Matrix multiplication context.
Return int: Error code (See RKNN Error Code).

Sample Code:

int ret = rknn_matmul_run(ctx);

rknn_matmul_destroy

This function is used to destroy the matrix multiplication operation context and release related resources. After using the matrix multiplication pointer created by the rknn_matmul_create function, you need to call this function to destroy it.

API rknn_matmul_destroy
Description Destroys the matrix multiply operation context.
Parameters rknn_matmul_ctx ctx: Matrix multiplication context.
Return int: Error code (See RKNN Error Code).

Sample Code:

int ret = rknn_matmul_destroy(ctx);

4.6 Definition of Custom Operator Data Structure

rknn_gpu_op_context

rknn_gpu_op_context represents the context information of the custom operator run by the specified GPU. The definition of the structure is shown in the following table:

Field Type Meaning
cl_context void* OpenCL’s cl_context object, please force type conversion to cl_context
when using it.
cl_command_queue void* OpenCL’s cl_command_queue object, please force type conversion to
cl_command_queue when using it.
cl_kernel void* OpenCL’s cl_kernel object, please force type conversion to cl_kernel
when using it.

rknn_custom_op_context

rknn_custom_op_context represents the context information of the custom operator. The definition of the structure is shown in the following table:

Field Type Meaning
target rknn_target_type Backend device that executes custom operators:
RKNN_TARGET_TYPE_CPU: CPU
RKNN_TARGET_TYPE_CPU: GPU
internal_ctx rknn_custom_op_interal_context Private context inside the operator.
gpu_ctx rknn_gpu_op_context Contains the OpenCL context information of the
custom operator. When the execution backend device
is a GPU, OpenCL objects such as cl_context are
obtained from this structure in the callback function.
priv_data void* Data pointers left to developers to manage.

rknn_custom_op_tensor

rknn_custom_op_tensor represents the input/output tensor information of the custom operator. The definition of the structure is shown in the following table:

Field Type Meaning
attr rknn_tensor_attr Contains the name, shape, size and other information of the tensor.
mem rknn_tensor_mem Contains tensor’s memory address, fd, valid data offset and other
information.

rknn_custom_op_attr

rknn_custom_op_attr represents the parameters or attribute information of the custom operator. The definition of the structure is shown in the following table:

Field Type Meaning
name char[] The parameter name of the custom operator.
dtype rknn_tensor_type The data type of each element.
n_elems uint32_t Number of elements.
data void* The virtual address of the parameter data memory segment.

rknn_custom_op

rknn_custom_op represents the registration information of the custom operator. The definition of the structure is shown in the following table:

Field Type Meaning
version uint32_t Custom operator version number.
target rknn_target_type Custom operator execution backend
type.
op_type char[] Custom operator type.
cl_kernel_name char[] OpenCL kernel function name.
cl_kernel_source char* OpenCL resource name. When
cl_source_size is equal to 0, it
represents the absolute path of the file;
when cl_source_size is greater than 0,
it represents the string of kernel
function code.
cl_source_size uint64_t When cl_kernel_source is a string, it
indicates the length of the string; when
cl_kernel_source is a file path, it is set
to 0.
cl_build_options char[] Compilation options for the OpenCL
kernel.
init int ()(rknn_custom_op_context op_ctx,
rknn_custom_op_tensor* inputs, uint32_t
n_inputs, rknn_custom_op_tensor*
outputs, uint32_t n_outputs);
Custom operator initialization callback
function pointer. Called once during
registration. It can be set to NULL
when not needed.
prepare int ()(rknn_custom_op_context op_ctx,
rknn_custom_op_tensor* inputs, uint32_t
n_inputs, rknn_custom_op_tensor*
outputs, uint32_t n_outputs);
Preprocessing callback function
pointer. Called once during rknn_run.
It can be set to NULL when not
needed.
compute int ()(rknn_custom_op_context op_ctx,
rknn_custom_op_tensor* inputs, uint32_t
n_inputs, rknn_custom_op_tensor*
outputs, uint32_t n_outputs);
The callback function pointer of the
custom operator function. Called once
during rknn_run. Cannot be set to
NULL.
compute_native int ()(rknn_custom_op_context op_ctx,
rknn_custom_op_tensor* inputs, uint32_t
n_inputs, rknn_custom_op_tensor*
outputs, uint32_t n_outputs);
High-performance computing callback
function pointer. The difference
between it and the compute callback
function is the format of the input and
output tensor. Not supported yet,
currently set to NULL.
destroy int ()(rknn_custom_op_context
op_ctx);
The callback function pointer for
destroying resources. Called once
during rknn_destroy.

4.7 Description of Custom Operator API

rknn_register_custom_ops

After the context is successfully initialized, this function is used to register several custom operator information in the context, including custom operator types, running backend types, OpenCL kernel information, and callback function pointers. After successful registration, during the inference phase, the rknn_run interface will call the callback function implemented by the developer.

API rknn_register_custom_ops
Description Register several custom operators into the context.
Parameters rknn_context *context: the rknn_context pointer. Before the function is called, the context
must have been successfully initialized.
  rknn_custom_op* op: the custom operator information array, each element of the array is a
rknn_custom_op structure object.
  uint32_t custom_op_num: custom operator information array length.
Return int: Error code (See RKNN Error Code).

Sample Code:

// 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;
}

rknn_custom_op_get_op_attr

This function is used to obtain the parameter information of the custom operator in the callback function of the custom operator, such as the axis parameter of the Softmax operator. It passes in the field name of the custom operator parameter and a rknn_custom_op_attr structure pointer. After calling this interface, the parameter value will be stored in the data member in the rknn_custom_op_attr structure. The developer forces the pointer according to the dtype member in the returned structure. Convert it into the first address of the array of a specific data type in C language, and then read out the complete parameter value according to the number of elements.

API rknn_custom_op_get_op_attr
Description Get the parameters or properties of a custom operator.
Parameters rknn_custom_op_context* op_ctx: custom operator context pointer.
  const char* attr_name: field name of custom operator parameter.
  rknn_custom_op_attr* op_attr: a structure representing the custom operator parameter
value.
Return No value.

Sample Code:

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];
}
…

5. RKNN Error Code

The return code of the RKNN API function is defined as shown in the following table.

Error Code Message
RKNN_SUCC(0) Execution is successful.
RKNN_ERR_FAIL (-1) Execution error.
RKNN_ERR_TIMEOUT (-2) Execution timeout.
RKNN_ERR_DEVICE_UNAVAILABLE (-3) NPU device is unavailable.
RKNN_ERR_MALLOC_FAIL (-4) Memory allocation is failed.
RKNN_ERR_PARAM_INVALID (-5) Parameter error.
RKNN_ERR_MODEL_INVALID (-6) RKNN model is invalid.
RKNN_ERR_CTX_INVALID (-7) rknn_context is invalid.
RKNN_ERR_INPUT_INVALID (-8) rknn_input object is invalid.
RKNN_ERR_OUTPUT_INVALID (-9) rknn_output object is invalid.
RKNN_ERR_DEVICE_UNMATCH (-10) Version does not match.
RKNN_ERR_INCOMPATILE_OPTIMIZATION_LEVEL_VERSION
(-12)
This RKNN model use
optimization level mode, but
not compatible with current
driver.
RKNN_ERR_TARGET_PLATFORM_UNMATCH (-13) This RKNN model doesn’t
compatible with current
platform.

Explore this topic → · Learning paths →