Rockchip · AI & Linux Hub

AI-инференс

RKNN Runtime C API V2.5.0 — Владение памятью и общий/zero-copy процессы

RKNN Runtime C API V2.5.0 — Владение памятью и общий/zero-copy процессы | Полные параметры, примеры и ограничения платформ

· ArmSoM · 9 мин чтения

Платформа и источник

Статья подготовлена по PDF производителя RKNN V2.5.0 и относится только к перечисленным в нём чипам и интерфейсам. Для платы ArmSoM сначала проверьте SoC, драйвер NPU, Toolkit/Runtime, SDK/BSP и версию ядра. Проверки на оборудовании ArmSoM не проводились; примеры и измерения оригинала не являются тестами ArmSoM.

Навигация по серии

3. Общие соглашения C API

3.1 Различия платформ

Из-за аппаратных различий набор интерфейсов и параметров RKNN C API зависит от платформы. Поддержка интерфейсов приведена в таблице 3-1:

Таблица 3-1. Поддержка RKNN C API на аппаратных платформах

  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 √ √ √ √

Поддержка параметров запроса rknn_query на разных платформах приведена в таблице 3-2:

Таблица 3-2. Поддерживаемые параметры rknn_query по платформам

  Параметры rknn_query 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 √ √ ×

3.2 Владение памятью

Память API: тензорная память, выделенная rknn_create_mem, принадлежит вызывающей стороне. По окончании использования её необходимо освободить rknn_destroy_mem. Не допускайте двойного освобождения.

Память пользователя: память, переданная rknn_set_weight_mem, rknn_set_internal_mem и rknn_set_io_mem, остаётся собственностью вызывающей стороны, которая освобождает её после использования.

Обёртки внешней памяти: rknn_create_mem_from_fd, rknn_create_mem_from_phys и rknn_create_mem_from_mb_blk связывают ранее выделенную память (дескриптор файла, физический адрес или mb_blk) с RKNN для zero-copy. Объект-обёртку rknn_tensor_mem также необходимо освободить через rknn_destroy_mem.

3.3 Срок действия входных и выходных данных

Массив inputs и данные, на которые указывает buf в rknn_inputs_set, должны оставаться действительными во время вызова.

Массив outputs для rknn_outputs_get пользователь создаёт заранее, задавая index. При is_prealloc=1 buf заранее выделяется пользователем и должен быть действительным во время вызова. При is_prealloc=0 buf выделяет интерфейс, и память остаётся действительной до rknn_outputs_release. После освобождения указатель buf недействителен и не должен использоваться.

Память входных/выходных тензоров, заданная rknn_set_io_mem, должна оставаться действительной во время вызова и быть установлена до rknn_run.

3.4 Возвращаемые значения и обработка ошибок

Большинство интерфейсов возвращают int: 0 означает успех, отрицательное значение — ошибку. Некоторые возвращают указатели (rknn_create_mem, rknn_create_mem_from_fd, rknn_create_mem_from_phys, rknn_create_mem_from_mb_blk) и NULL при ошибке.

Полные определения приведены в 6.1 «Коды состояния».

Проверяйте результат каждого вызова и определяйте причину по коду: например, RKNN_ERR_DEVICE_UNMATCH означает несовпадение версии, RKNN_ERR_CTX_INVALID — недействительный контекст.

3.5 Общий API и zero-copy API

При инференсе данные проходят обработку входа, выполнение модели на NPU и обработку выхода. В зависимости от формата и квантования используются общий API либо zero-copy API. Основные различия использования и последовательности вызовов:

Общий API: простой набор интерфейсов rknn_inputs_set/rknn_outputs_get/rknn_outputs_release. При каждом обновлении кадра данные внешнего модуля копируются во входную память NPU Runtime. Нормализация, квантование, преобразование компоновки и деквантование выполняются преимущественно CPU, инференс — NPU.

Zero-copy API: создаёт или оборачивает память через rknn_create_mem/rknn_create_mem_from_fd/rknn_create_mem_from_phys и задаёт её через rknn_set_io_mem. Прямое использование заранее выделенной памяти NPU Runtime или внешней системы, например DRM, уменьшает копирование, повышает производительность и снижает трафик памяти. Нормализация, квантование и инференс выполняются на NPU.

Выбор интерфейса: при наличии только виртуального адреса входных данных используется только общий API; при физическом адресе или fd — zero-copy API. Общий и zero-copy API нельзя смешивать.

Последовательность общего API (рисунок 3-1):

  1. Вызовите rknn_init() для инициализации модели;
  1. Запросите атрибуты входов/выходов через rknn_query();
  1. Предварительно обработайте вход;
  1. Задайте входные данные через rknn_inputs_set();
  1. Выполните инференс через rknn_run();
  1. Получите результаты через rknn_outputs_get();
  1. Обработайте выход;
  1. Освободите выходную память через rknn_outputs_release();
  1. Уничтожьте RKNN через rknn_destroy().

Иллюстрация из исходного PDF — 11

Рисунок 3-1. Последовательность общего API

Последовательность zero-copy API (пример с памятью входа/выхода, выделенной Runtime, рисунок 3-2):

  1. Вызовите rknn_init() для инициализации модели;
  1. Запросите нативные атрибуты через rknn_query() (RKNN_QUERY_NATIVE_INPUT_ATTR/RKNN_QUERY_NATIVE_OUTPUT_ATTR);
  1. Предварительно обработайте вход (необязательно);
  1. Создайте входные/выходные rknn_tensor_mem через rknn_create_mem() (для внешней памяти используйте rknn_create_mem_from_fd()/rknn_create_mem_from_phys());
  1. Задайте входную/выходную память через rknn_set_io_mem();
  1. Выполните инференс через rknn_run();
  1. Прочитайте выходную память из rknn_tensor_mem и выполните постобработку;
  1. Освободите входную/выходную память через rknn_destroy_mem();
  1. Уничтожьте RKNN через rknn_destroy().

Иллюстрация из исходного PDF — 12

Рисунок 3-2. Последовательность zero-copy API с внутренним выделением памяти

Подробнее о rknn_set_io_mem() см. 5.4 «Тензоры и память».

Источник и редакционные примечания

Технические главы разделены по назначению. Код, идентификаторы и параметры сохранены. Китайская версия следует китайскому оригиналу; английская, русская и немецкая — английскому. В главы без иллюстраций вымышленные изображения не добавлены.

Оговорки оригинала: номера глав и примерные журналы сохранены; ранние версии SDK в журналах не являются версией этой статьи. Runtime переходит от главы 3 к 5 и повторяет номера запросов. Таблица rknn_init называет extend отключённым, но далее описывает user_key и общие веса. Текст о нативном динамическом выходе указывает RKNN_QUERY_CURRENT_OUTPUT_ATTR, пример — RKNN_QUERY_CURRENT_NATIVE_OUTPUT_ATTR. Некоторые описания native NHWC/NC1HWC2 смешивают вход и выход. Проверяйте фактические заголовки V2.5.0 и целевой SDK: поведение не подтверждено тестами. Ссылка RK2118 в оригинале называется RKNN3_RK2118_Quick_Start.pdf, а в текущем каталоге находится руководство RKNN2.

RKNN-Toolkit2 · ArmSoM documentation

Другие статьи по теме → · Учебные маршруты →