Anwendbarkeit auf ArmSoM und Quelle
Quellen sind RK-YH-YF-413, V2.3.2: 52 chinesische und 57 englische Seiten. Chinesisch folgt dem chinesischen Original; Englisch dem englischen Original, das vollständig ins Russische und Deutsche übersetzt wurde. Die Quellen enthalten keine technischen Abbildungen oder Code-Screenshots: Alle Tabellen sind editierbar und sämtlicher Code kopierbarer Text; Abbildungen werden nicht erfunden. Genannt werden RV1103/RV1103B/RV1106/RV1106B/RV1126B, RK2118, RK3562 sowie die Serien RK3566/RK3568/RK3576/RK3588. Einzelne APIs, Abfragen und Parameter gelten jedoch nicht für alle Plattformen; die Unterstützungsmatrizen sind maßgeblich. Dies ist lediglich eine ArmSoM-Anpassungsreferenz, ohne Prüfung konkreter Boards, SDK/BSP- oder Kernel-/Treiberkombinationen. RKNPU Runtime, Modellformat und NPU-Hardware müssen zusammenpassen. Code-, Hardware- oder Leistungstests wurden nicht ausgeführt; Beispiele sind keine ArmSoM-Messwerte.
Hinweis: Die Beschreibung der DEVICE_MEM_INFO-Unterstützung widerspricht der Matrix. Auch INPUT/OUTPUT-Bezeichnungen, CPU/GPU-Aufzählungen und die Freigabereihenfolge bei Zero-Copy sind fraglich. Quellwerte bleiben erhalten; dies ist keine geprüfte, ausführbare Korrekturfassung. Vor Nutzung Hinweise und tatsächliche SDK-Header prüfen.
EDITORIAL-NOTES · ArmSoM Documentation
1. Übersicht
RKNN C API stellt C-Schnittstellen für RKNPU Runtime bereit. Damit lässt sich die Rechenleistung der NPU für effiziente RKNN-Modellinferenz oder Matrixmultiplikationen nutzen. Beschrieben werden die Funktionen, Datenstrukturen und Rückgabecodes der RKNN C API.
2. Unterstützte Hardwareplattformen
Das Dokument gilt für folgende Hardwareplattformen:
RV1103
RV1103B
RV1106
RV1106B
RV1126B
RK2118
RK3562
RK3566-Serie
RK3568-Serie
RK3576-Serie
RK3588-Serie
3. RKNPU-Build-Anleitung
Beim Kompilieren einer Anwendung ist die Headerdatei der Schnittstellenfunktion einzubinden und die passende RKNPU-Runtime-Bibliothek für Hardwareplattform und Systemtyp zu linken. Nachfolgend werden die Headerdateien der RKNN C API und die Runtime-Bibliotheksdateien beschrieben.
3.1 Headerdateien der RKNN C API
Die RKNN C API gliedert sich nach Funktionen in drei Teile. Funktionen, Datenstrukturdefinitionen und Headerdateien sind wie folgt zugeordnet:
1. “rknn_api.h” definiert die grundlegenden Schnittstellen und Datenstrukturen zur Bereitstellung von RKNN-Modellen.
2. “rknn_matmul_api.h” definiert Schnittstellen und Datenstrukturen für Matrixmultiplikation.
3. “rknn_custom_op.h” definiert Schnittstellen und Datenstrukturen benutzerdefinierter Operatoren.
3.2 RKNPU-Runtime-Bibliothek für Linux
1. Für RK3562, die Serien RK3566, RK3568, RK3576, RK3588 und RV1126B ist die RKNPU-Runtime-Bibliothek librknnrt.so im Verzeichnis <sdk_path>/rknpu2/runtime. <sdk_path> ist der Pfad zum Rockchip-NPU-SDK.
2. Für RV1106/RV1103/RV1106B/RV1103B ist die RKNPU-Runtime-Bibliothek librknnmrt.so im Verzeichnis <sdk_path>/rknpu2/runtime.
3.3 RKNPU-Runtime-Bibliothek für Android
Unter Android lässt sich die RKNN API auf zwei Arten aufrufen:
1. Die Anwendung linkt direkt gegen librknnrt.so.
2. Die Anwendung linkt gegen die unter Android mittels HIDL implementierte librknn_api_android.so.
Android-Geräte, die CTS/VTS bestehen müssen, benötigen die RKNN API auf Basis von Android HIDL; librknn_api_android.so enthält keine Matrixmultiplikation und keine benutzerdefinierten Operatoren. Ist CTS/VTS nicht erforderlich, wird die direkte Nutzung von librknnrt.so empfohlen, die beide Funktionen enthält. Der Aufrufweg jeder Schnittstelle ist kürzer und kann bessere Leistung bieten.
Der über Android HIDL implementierte RKNN-API-Code liegt im Verzeichnis vendor/rockchip/hardware/interfaces/neuralnetworks des Android-System-SDK für RK3562/RK3566/RK3568/RK3576/RK3588.
Nach dem Android-Systembuild werden folgende RKNPU-Bibliotheksdateien erzeugt. Für die Anwendungsentwicklung genügt das Linken gegen librknn_api_android.so:
/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
Alternativ können diese Bibliotheken mit folgendem Befehl separat neu gebaut werden:
mmm vendor/rockchip/hardware/interfaces/neuralnetworks/ -j8
3.4 RKNPU-Runtime-Bibliothek für RK2118
Für RK2118 befindet sich die RKNPU-Runtime-Bibliothek im System-SDK des RK2118. Siehe Abschnitt “Prepare RK2118 SDK” in “Rockchip_RK2118_Quick_Start_RKNN_SDK_EN.pdf”.
4. Beschreibung der RKNN C API
4.1 C-API-Unterstützung der Hardwareplattformen
Aufgrund unterschiedlicher Hardwareeigenschaften unterscheiden sich die Unterstützung der RKNN-C-API-Schnittstellen und ihrer Parameter je Plattform. Tabelle 4-1 zeigt die Schnittstellenunterstützung.
Tabelle 4-1:
Tabelle 4-1: RKNN-C-API-Schnittstellenunterstützung je Hardwareplattform
| 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 | √ | √ | √ | √ |
Die je Hardwareplattform unterstützten Abfrageparameter von rknn_query stehen in Tabelle 4-2:
Tabelle 4-2: Unterstützte rknn_query-Abfrageparameter je Hardwareplattform
| rknn_query-Parameter | 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 Definitionen grundlegender Datenstrukturen
rknn_sdk_version
Die Struktur rknn_sdk_version enthält die Versionsinformationen des RKNN SDK. Ihre Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| api_version | char[] | SDK-API-Versionsinformationen. |
| drv_version | char[] | SDK-Treiberversionsinformationen. |
rknn_input_output_num
Die Struktur rknn_input_output_num beschreibt die Anzahl der Ein- und Ausgabetensoren. Ihre Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| n_input | uint32_t | Anzahl der Eingabetensoren. |
| n_output | uint32_t | Anzahl der Ausgabetensoren. |
rknn_input_range
Die Struktur rknn_input_range beschreibt die Liste unterstützter Eingabeformen: Eingabeindex, Anzahl der Formen, Datenlayout, Name und Formenliste. Die genaue Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| index | uint32_t | Index der Eingabe. |
| shape_number | uint32_t | Anzahl der vom RKNN-Modell unterstützten Eingabeformen. |
| fmt | rknn_tensor_format | Datenlayout der entsprechenden Form. |
| name | char[] | Name der Eingabe. |
| dyn_range | uint32_t[][] | Liste der Eingabeformen: zweidimensionales Array mehrerer Formenarrays; die Form wird zuerst gespeichert. |
| n_dims | uint32_t | Anzahl gültiger Dimensionen jedes Formenarrays. |
rknn_tensor_attr
Die Struktur rknn_tensor_attr beschreibt die Attribute eines Modelltensors. Ihre Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| index | uint32_t | Index des Ein- oder Ausgabetensors. |
| n_dims | uint32_t | Anzahl der Tensordimensionen. |
| dims | uint32_t[] | Werte der einzelnen Dimensionen. |
| name | char[] | Tensorname. |
| n_elems | uint32_t | Anzahl der Tensordaten-Elemente. |
| size | uint32_t | Speichergröße der Tensordaten. |
| fmt | rknn_tensor_format | Tensorlayout: RKNN_TENSOR_NCHW, RKNN_TENSOR_NHWC, RKNN_TENSOR_NC1HWC2. |
| type | rknn_tensor_type | Tensordatentyp: 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 | Quantisierungstyp: RKNN_TENSOR_QNT_NONE — nicht quantisiert; RKNN_TENSOR_QNT_DFP — dynamische Festkommaquantisierung; RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC — asymmetrische Quantisierung. |
| fl | int8_t | Quantisierungsparameter für RKNN_TENSOR_QNT_DFP. |
| scale | float | Quantisierungsparameter für RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC. |
| w_stride | uint32_t | Tatsächliche Pixelanzahl zum Speichern einer Bildzeile: gültige Zeilenpixel plus ungültige Füllpixel, über die die Hardware schnell zur nächsten Zeile gelangt. Einheit: Pixel. |
| size_with_stride | uint32_t | Tatsächliche Bilddatengröße in Byte, einschließlich ungültiger Füllpixel. |
| pass_through | uint8_t | 0 — nicht konvertierte Daten; 1 — konvertierte Daten. Die Konvertierung umfasst Normalisierung und Quantisierung. |
| h_stride | uint32_t | Nur bei Multi-Batch-Eingaben verwendet und vom Benutzer einstellbar, damit die NPU die Anfangsadresse jedes Batch korrekt liest. Entspricht der ursprünglichen Modelleingabehöhe plus ungültigen Füllpixeln für den schnellen Hardware-Zeilensprung. Bei 0 entspricht es der Modelleingabehöhe. Einheit: Pixel. |
rknn_perf_detail
Die Struktur rknn_perf_detail beschreibt detaillierte Leistungsdaten des Modells. Ihre Definition folgt in der Tabelle. Hinweis: RV1106/RV1103/RV1106B/RV1103B/RK2118 werden nicht unterstützt.
| Feld | Typ | Bedeutung |
|---|---|---|
| perf_data | char* | Detaillierte Leistungsdaten: Laufzeit jeder Netzwerkschicht als Zeichenfolge. |
| data_len | uint64_t | Länge der Zeichenfolgendaten von perf_data. |
rknn_perf_run
Die Struktur rknn_perf_run beschreibt die gesamte Inferenzzeit des Modells. Ihre Definition folgt in der Tabelle. Hinweis: RV1106/RV1103/RV1106B/RV1103B/RK2118 werden nicht unterstützt.
| Feld | Typ | Bedeutung |
|---|---|---|
| run_duration | int64_t | Gesamte Inferenzzeit des Netzwerks in Mikrosekunden, ohne das Setzen von Ein- und Ausgaben. |
rknn_mem_size
Die Struktur rknn_mem_size beschreibt die Speicherzuweisung bei der Modellinitialisierung. Ihre Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| total_weight_size | uint32_t | Für Netzwerkgewichte zugewiesene Speichergröße. |
| total_internal_size | uint32_t | Für interne Netzwerktensoren zugewiesene Speichergröße. |
| total_dma_allocated_size | uint64_t | Gesamter dem Netzwerk zugewiesener DMA-Speicher. |
| total_sram_size | uint32_t | Nur RK3588: für die NPU reservierte SRAM-Größe. Weitere Angaben in RK3588_NPU_SRAM_usage.md. |
| free_sram_size | uint32_t | Nur RK3588: aktuell verfügbarer SRAM. Weitere Angaben in RK3588_NPU_SRAM_usage.md. |
| reserved[12] | uint32_t | Reserviert. |
rknn_tensor_mem
Die Struktur rknn_tensor_mem beschreibt den Tensorspeicher. Ihre Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| virt_addr | void* | Virtuelle Adresse des Tensors. |
| phys_addr | uint64_t | Physische Adresse des Tensors. |
| fd | int32_t | Dateideskriptor des Tensors. |
| offset | int32_t | Offset von fd und virtueller Adresse. |
| size | uint32_t | Tatsächliche Tensorgröße. |
| flags | uint32_t | Flags von rknn_tensor_mem: RKNN_TENSOR_MEMORY_FALGS_ALLOC_INSIDE — Struktur intern in der Runtime erstellt; RKNN_TENSOR_MEMORY_FLAGS_FROM_FD — über fd erstellt; RKNN_TENSOR_MEMORY_FLAGS_FROM_PHYS — über eine physische Adresse erstellt. Der Benutzer muss diese Flags nicht berücksichtigen. |
| priv_data | void* | Private Daten. |
rknn_input
Die Struktur rknn_input repräsentiert Modelleingabedaten und dient als Parameter von rknn_inputs_set. Ihre Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| index | uint32_t | Index dieser Eingabe. |
| buf | void* | Zeiger auf den Eingabedatenpuffer. |
| size | uint32_t | Speichergröße des Eingabedatenpuffers. |
| pass_through | uint8_t | Bei 1 wird buf ohne Vorverarbeitung direkt als Modelleingabeknoten gesetzt. |
| type | rknn_tensor_type | Typ der Eingabedaten. |
| fmt | rknn_tensor_format | Format der Eingabedaten. |
rknn_output
Die Struktur rknn_output repräsentiert Modellausgabedaten und dient als Parameter von rknn_outputs_get. Nach dem Aufruf von rknn_outputs_get wird sie mit Daten belegt. Die Tabelle definiert alle Felder:
| Feld | Typ | Bedeutung |
|---|---|---|
| want_float | uint8_t | Ob die Ausgabedaten in float zu konvertieren sind; vom Benutzer gesetzt. |
| is_prealloc | uint8_t | Ob der Ausgabedatenpuffer vorab zugewiesen ist; vom Benutzer gesetzt. |
| index | uint32_t | Index dieser Ausgabe. Die Quelle bezeichnet das Feld sowohl als vom Benutzer gesetzt als auch von der Schnittstelle zurückgegeben; der Widerspruch bleibt kenntlich. |
| buf | void* | Von der Schnittstelle zurückgegebener Zeiger auf den Ausgabedatenpuffer. |
| size | uint32_t | Von der Schnittstelle zurückgegebene Ausgabepuffergröße in Byte. |
rknn_init_extend
Die Struktur rknn_init_extend enthält erweiterte Informationen zur Modellinitialisierung. Im beschriebenen Stand ist sie auf RV1106/RV1103/RV1106B/RV1103B/RK2118 nicht verfügbar. Ihre Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| ctx | rknn_context | Initialisiertes rknn_context-Objekt. |
| real_model_offset | int32_t | Tatsächlicher Offset in der .rknn-Modelldatei. Nur gültig bei Initialisierung über einen Dateipfad oder Zero-Copy-Modellpuffer. |
| real_model_size | uint32_t | Tatsächliche Größe der rknn-Modelldatei. Nur gültig bei Initialisierung über einen Dateipfad oder Zero-Copy-Modellpuffer. |
| model_buffer_fd | int32_t | fd des durch die NPU zugewiesenen Modellspeichers nach Initialisierung mit RKNN_FLAG_MODEL_BUFFER_ZERO_COPY. |
| model_buffer_flags | uint32_t | Speicherflags des durch die NPU zugewiesenen Modellspeichers nach Initialisierung mit RKNN_FLAG_MODEL_BUFFER_ZERO_COPY. |
| reserved | uint8_t[] | Reservierte Daten. |
rknn_run_extend
Die Struktur rknn_run_extend enthält erweiterte Informationen während der Modellinferenz. Im beschriebenen Stand ist sie nicht verfügbar. Ihre Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| frame_id | uint64_t | Frameindex der aktuellen Inferenz. |
| non_block | int32_t | 0 — blockierend; 1 — nicht blockierend, wobei rknn_run sofort zurückkehrt. |
| timeout_ms | int32_t | Inferenz-Timeout in Millisekunden. |
| fence_fd | int32_t | Für nicht blockierende Inferenz; nicht verfügbar. |
rknn_output_extend
Die Struktur rknn_output_extend dient zum Abruf erweiterter Ausgabeinformationen. Im beschriebenen Stand ist sie nicht verfügbar. Ihre Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| frame_id | int32_t | Frameindex des Ausgabeergebnisses. |
rknn_custom_string
Die Struktur rknn_custom_string enthält die vom Benutzer bei der RKNN-Modellkonvertierung festgelegte Zeichenfolge. Ihre Definition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| string | char[] | Benutzerdefinierte Zeichenfolge. |
4.3 Beschreibung der grundlegenden APIs
rknn_init
Die Initialisierungsfunktion rknn_init erstellt ein rknn_context-Objekt, lädt das RKNN-Modell und führt die durch Flags und rknn_init_extend festgelegte Initialisierung aus.
| API | rknn_init |
|---|---|
| Beschreibung | Initialisiert den rknn-Kontext. |
| Parameter | rknn_context *context: Zeiger auf das rknn_context-Objekt. |
| void *model: Binärdaten des RKNN-Modells oder dessen Pfad. Bei size>0 Binärdaten, bei size=0 Modellpfad. | |
| uint32_t size: Größe des als Binärdaten übergebenen Modells; 0, wenn model einen Pfad enthält. | |
| uint32_t flag: Initialisierungsflag; für das Standardverhalten auf 0 setzen. | |
| rknn_init_extend: erweiterte Informationen für besondere Initialisierung. Die Quelle nennt diese deaktiviert und fordert NULL, verlangt beim Teilen von Gewichten jedoch einen Zeiger auf einen anderen rknn_context für ein anderes Modell. Beide Aussagen bleiben erhalten. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
rknn_context ctx;
int ret = rknn_init(&ctx, model_data, model_data_size, 0, NULL);
Die Initialisierungsflags werden nachfolgend erläutert:
RKNN_FLAG_COLLECT_PERF_MASK: ermöglicht die Abfrage der Laufzeit jeder Netzwerkschicht.
RKNN_FLAG_MEM_ALLOC_OUTSIDE: kennzeichnet, dass der Benutzer den Speicher für Modelleingaben, Ausgaben, Gewichte und Zwischentensoren vollständig selbst zuweist. Dies hat zwei Hauptzwecke:
1. Die vollständige Speicherzuweisung durch den Benutzer erleichtert die übergreifende Planung des gesamten Systemspeichers.
2. Wiederverwendung von Speicher, insbesondere bei sehr knappem Speicher wie auf RV1106/RV1103/RV1106B/RV1103B/RK2118.
Angenommen, die Modelle A und B werden nacheinander ausgeführt. Dann lässt sich der Speicher ihrer Zwischentensoren wiederverwenden. Beispielcode:
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: dient zur gemeinsamen Nutzung der Gewichte eines anderen Modells. Hauptzweck ist die Nachbildung variabler Eingabelängen; ab RKNPU Runtime 1.5.0 wird diese Funktion durch dynamische Formen ersetzt. Beispielsweise haben manche Sprachmodelle variable Eingabelängen, die NPU unterstützt diese jedoch nicht unmittelbar. Daher werden mehrere RKNN-Modelle unterschiedlicher Auflösung erzeugt. Nur eines enthält vollständige Gewichte, die anderen keine. Bei Initialisierung eines Modells ohne Gewichte erlaubt dieses Flag dem aktuellen Kontext, die Gewichte des vollständigen Modells mitzunutzen. Für zwei Modelle mit Auflösung A und B gilt folgender Ablauf:
1. Mit RKNN-Toolkit2 ein Modell der Auflösung A erzeugen.
2. Mit RKNN-Toolkit2 ein Modell der Auflösung B ohne Gewichte erzeugen: In rknn.config() remove_weight auf True setzen. Hauptzweck ist die Verringerung der Größe von Modell B.
3. Modell A auf dem Board normal initialisieren.
4. Modell B mit RKNN_FLAG_SHARE_WEIGHT_MEM initialisieren.
5. Die weitere Verwendung erfolgt wie gewohnt. Referenzcode für das Board:
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: initialisiert einen leeren Kontext. Darin lässt sich nur rknn_query zur Abfrage der Gesamtgrößen des Gewichtsspeichers und der Zwischentensoren aufrufen; Inferenz ist nicht möglich.
RKNN_FLAG_INTERNAL_ALLOC_OUTSIDE: Der Benutzer weist die Zwischentensoren des Modells zu. Dies wird häufig zur eigenen Verwaltung und Wiederverwendung des Zwischentensorspeichers mehrerer Modelle genutzt.
RKNN_FLAG_EXECUTE_FALLBACK_PRIOR_DEVICE_GPU: Alle von der NPU nicht unterstützten Schichten sollen bevorzugt auf der GPU laufen, ohne Garantie. Das tatsächliche Ausführungsgerät hängt von der Operatorunterstützung der Runtime ab.
RKNN_FLAG_ENABLE_SRAM: Zwischentensorspeicher wird nach Möglichkeit im SRAM zugewiesen.
RKNN_FLAG_SHARE_SRAM: Der aktuelle Kontext versucht, den SRAM-Adressraum eines anderen Kontexts mitzunutzen. Bei seiner Initialisierung muss RKNN_FLAG_ENABLE_SRAM aktiviert sein.
RKNN_FLAG_DISABLE_PROC_HIGH_PRIORITY: Der aktuelle Kontext verwendet die Standardprozesspriorität. Ohne dieses Flag beträgt der nice-Wert des Prozesses -19.
RKNN_FLAG_DISABLE_FLUSH_INPUT_MEM_CACHE: Die Runtime schreibt den Eingabetensor-Cache nicht zurück; der Benutzer muss dies vor rknn_run sicherstellen.
RKNN_FLAG_DISABLE_FLUSH_OUTPUT_MEM_CACHE: Die Runtime bereinigt den Ausgabetensor-Cache nicht aktiv. Direkter Benutzerzugriff auf output_mem->virt_addr kann dann Cache-Konsistenzprobleme verursachen. Vor der Nutzung von output_mem->virt_addr ist der Cache mit rknn_mem_sync(ctx, mem, RKNN_MEMORY_SYNC_FROM_DEVICE) zu aktualisieren. Das Flag wird typischerweise eingesetzt, wenn nicht die CPU, sondern etwa GPU oder RGA die NPU-Ausgabe liest.
RKNN_FLAG_MODEL_BUFFER_ZERO_COPY: Der an rknn_init übergebene Modellpuffer wurde durch rknn_create_mem oder rknn_create_mem2 zugewiesen. Die Runtime erstellt keine zusätzliche Pufferkopie und benötigt dadurch weniger Speicher. Der Benutzer muss den Modellspeicher bis zur Zerstörung des Kontexts gültig halten und danach freigeben. Bei der Initialisierung werden real_model_offset, real_model_size, model_buffer_fd und model_buffer_flags des Parameters rknn_init_extend von rknn_init anhand des von rknn_create_mem2 zurückgegebenen rknn_tensor_mem gesetzt.
RKNN_MEM_FLAG_ALLOC_NO_CONTEXT: erlaubt bei Speicherzuweisung über rknn_create_mem2 einen ctx-Wert von 0 oder NULL. So lässt sich vom NPU-Treiber zugewiesener Speicher bereits vor der Initialisierung eines Kontexts erhalten. Die zurückgegebene Speicherstruktur muss über rknn_destroy_mem freigegeben werden; dabei kann ein beliebiger Kontext übergeben werden. Beispielcode:
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
Die Funktion legt die auszuführenden NPU-Kerne fest. Im beschriebenen Stand funktioniert sie nur auf RK3588 und RK3576. Bei einer Plattform mit einkerniger NPU wird ein Fehlercode zurückgegeben.
| API | rknn_set_core_mask |
|---|---|
| Beschreibung | Legt die NPU-Kerne fest. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| rknn_core_mask core_mask: Auswahl der NPU-Kerne. RKNN_NPU_CORE_AUTO — automatische Auswahl eines freien Kerns; RKNN_NPU_CORE_0 — NPU0; RKNN_NPU_CORE_1 — NPU1; RKNN_NPU_CORE_2 — NPU2; RKNN_NPU_CORE_0_1 — NPU0 und NPU1 gleichzeitig; RKNN_NPU_CORE_0_1_2 — NPU0, NPU1 und NPU2 gleichzeitig; RKNN_NPU_CORE_ALL — alle NPU-Kerne der Plattform. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
rknn_context ctx;
rknn_core_mask core_mask = RKNN_NPU_CORE_0;
int ret = rknn_set_core_mask(ctx, core_mask);
In den Mehrkernmodi RKNN_NPU_CORE_0_1 und RKNN_NPU_CORE_0_1_2 profitieren Conv, DepthwiseConvolution, Add, Concat, Relu, Clip, Relu6, ThresholdedRelu, Prelu und LeakyRelu von besserer Beschleunigung. Andere Operatoren laufen weiter auf Core0. Die Quelle kündigt Pool und ConvTranpose für spätere Updates an; dies ist keine Bestätigung ihrer aktuellen Implementierung.
rknn_set_batch_core_num
rknn_set_batch_core_num legt die Anzahl der NPU-Kerne für ein Multi-Batch-RKNN-Modell fest, das in RKNN-Toolkit2 mit rknn_batch_size größer als 1 exportiert wurde. Unterstützt werden nur RK3588 und RK3576.
| API | rknn_set_batch_core_num |
|---|---|
| Beschreibung | Legt die NPU-Kernanzahl für ein Multi-Batch-RKNN-Modell fest. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| int core_num: Anzahl der auszuführenden Kerne. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
rknn_context ctx;
int ret = rknn_set_batch_core_num(ctx, 2);
rknn_dup_context
rknn_dup_context erstellt einen neuen Kontext für dasselbe Modell. Dies ermöglicht die Wiederverwendung der Modellgewichte bei Ausführung desselben Modells in mehreren Threads. Auf RV1106/RV1103/RV1106B/RV1103B/RK2118 nicht verfügbar.
| API | rknn_dup_context |
|---|---|
| Beschreibung | Erstellt einen neuen Kontext desselben Modells zur Wiederverwendung der Gewichte. |
| Parameter | rknn_context *context_in: Zeiger auf ein rknn_context-Objekt. Laut Quelle wird der Eingabekontext nach dem Aufruf initialisiert. |
| rknn_context *context_out: Zeiger auf ein rknn_context-Ausgabeobjekt mit den zurückgegebenen Informationen über das neu erstellte Objekt. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
rknn_context ctx_in;
rknn_context ctx_out;
int ret = rknn_dup_context(&ctx_in, &ctx_out);
rknn_destroy
Diese Funktion gibt rknn_context und zugehörige Ressourcen frei.
| API | rknn_destroy |
|---|---|
| Beschreibung | Zerstört rknn_context und zugehörige Ressourcen. |
| Parameter | rknn_context context: zu zerstörendes rknn_context-Objekt. |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
rknn_context ctx;
int ret = rknn_destroy(ctx);
rknn_query
rknn_query fragt Modell- und SDK-Informationen ab: Ein- und Ausgaben, schichtweise Laufzeiten, gesamte Inferenzzeit, SDK-Version, Speicherverbrauch, benutzerdefinierte Zeichenfolgen und weitere Informationen.
| API | rknn_query |
|---|---|
| Beschreibung | Fragt Modell- und SDK-Informationen ab. |
| Parameter | rknn_context context: rknn_contex-Objekt (Quellschreibweise). |
| rknn_query_cmd: Abfragebefehl. | |
| void* info: Strukturobjekt für das Abfrageergebnis. | |
| uint32_t size: Größe des info-Strukturobjekts. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Im beschriebenen Stand unterstützt das SDK folgende Abfragebefehle:
| Abfragebefehl | Ergebnisstruktur | Funktion |
|---|---|---|
| RKNN_QUERY_IN_OUT_NUM | rknn_input_output_num | Anzahl der Ein- und Ausgabetensoren. |
| RKNN_QUERY_INPUT_ATTR | rknn_tensor_attr | Eingabetensorattribute. |
| RKNN_QUERY_OUTPUT_ATTR | rknn_tensor_attr | Ausgabetensorattribute. |
| RKNN_QUERY_PERF_DETAIL | rknn_perf_detail | Laufzeit jeder Netzwerkschicht; nur mit über rknn_init gesetztem RKNN_FLAG_COLLECT_PERF_MASK. |
| RKNN_QUERY_PERF_RUN | rknn_perf_run | Gesamte Inferenzzeit in Mikrosekunden ohne das Setzen von Ein- und Ausgaben. |
| RKNN_QUERY_SDK_VERSION | rknn_sdk_version | SDK-Version. |
| RKNN_QUERY_MEM_SIZE | rknn_mem_size | Speichergröße der Gewichte und internen Netzwerktensoren. |
| RKNN_QUERY_CUSTOM_STRING | rknn_custom_string | Benutzerdefinierte Zeichenfolgen im RKNN-Modell. |
| RKNN_QUERY_NATIVE_INPUT_ATTR | rknn_tensor_attr | In der Zero-Copy-API: native Attribute der direkt von der NPU gelesenen Eingabe. |
| RKNN_QUERY_NATIVE_OUTPUT_ATTR | rknn_tensor_attr | In der Zero-Copy-API: native Attribute der direkt von der NPU stammenden Ausgabe. |
| RKNN_QUERY_NATIVE_NC1HWC2_INPUT_ATTR | rknn_tensor_attr | In der Zero-Copy-API: native Attribute der direkt von der NPU gelesenen Eingabe; gleichbedeutend mit RKNN_QUERY_NATIVE_INPUT_ATTR. |
| RKNN_QUERY_NATIVE_NC1HWC2_OUTPUT_ATTR | rknn_tensor_attr | In der Zero-Copy-API: native Ausgabeattribute; die Quelle bezeichnet sie anschließend als von der NPU gelesene Eingabeattribute. Gleichbedeutend mit RKNN_QUERY_NATIVE_OUTPUT_ATTR. Der Ein-/Ausgabewiderspruch bleibt erhalten. |
| RKNN_QUERY_NATIVE_NHWC_INPUT_ATTR | rknn_tensor_attr | In der Zero-Copy-API: native Attribute der direkt von der NPU gelesenen Eingabe. Die Quelle setzt den Befehl mit RKNN_QUERY_NATIVE_INPUT_ATTR gleich. |
| RKNN_QUERY_NATIVE_NHWC_OUTPUT_ATTR | rknn_tensor_attr | In der Zero-Copy-API: native NHWC-Ausgabetensorattribute; die Quelle bezeichnet sie anschließend als direkt von der NPU gelesene Eingabeattribute. |
| RKNN_QUERY_DEVICE_MEM_INFO | rknn_tensor_mem | Speichereigenschaften des Modellpuffers. |
| RKNN_QUERY_INPUT_DYNAMIC_RANGE | rknn_input_range | Bei dynamischen Formen: Anzahl und Liste unterstützter Eingabeformen, zugehöriges Datenlayout und Namen. |
| RKNN_QUERY_CURRENT_INPUT_ATTR | rknn_tensor_attr | Bei dynamischen Formen: Eingabeattribute der aktuellen Inferenz. |
| RKNN_QUERY_CURRENT_OUTPUT_ATTR | rknn_tensor_attr | Bei dynamischen Formen: Ausgabeattribute der aktuellen Inferenz. |
| RKNN_QUERY_CURRENT_NATIVE_INPUT_ATTR | rknn_tensor_attr | Bei dynamischen Formen: native NPU-Eingabeattribute der aktuellen Inferenz. |
| RKNN_QUERY_CURRENT_NATIVE_OUTPUT_ATTR | rknn_tensor_attr | Bei dynamischen Formen: native NPU-Ausgabeattribute der aktuellen Inferenz. |
Nachfolgend wird jeder Abfragebefehl erläutert.
1. SDK-Version abfragen
RKNN_QUERY_SDK_VERSION fragt die Version des RKNN SDK ab. Zunächst ist ein Objekt der Struktur rknn_sdk_version zu erstellen.
Beispielcode:
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. Anzahl der Ein- und Ausgabetensoren abfragen
RKNN_QUERY_IN_OUT_NUM fragt die Anzahl der Ein- und Ausgabetensoren des Modells ab. Zunächst ein Objekt der Struktur rknn_input_output_num erstellen.
Beispielcode:
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. Eingabetensorattribute abfragen (allgemeine API)
RKNN_QUERY_INPUT_ATTR fragt die Attribute des Modelleingabetensors ab. Zunächst ein Objekt der Struktur rknn_tensor_attr erstellen.
Hinweis: Auf RV1106/RV1103/RV1106B/RV1103B/RK2118 wird der ursprüngliche Eingabetensor im nativen Format abgefragt.
Beispielcode:
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. Ausgabetensorattribute abfragen (allgemeine API)
RKNN_QUERY_OUTPUT_ATTR fragt die Attribute des Modellausgabetensors ab. Zunächst ein Objekt der Struktur rknn_tensor_attr erstellen.
Beispielcode:
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. Schichtweise Inferenzzeit des Modells abfragen
Nach rknn_run fragt RKNN_QUERY_PERF_DETAIL die schichtweise Inferenzzeit in Mikrosekunden ab. Voraussetzung ist RKNN_FLAG_COLLECT_PERF_MASK im Parameter flag von rknn_init.
Beispielcode:
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. Gesamte Inferenzzeit des Modells abfragen
Nach rknn_run fragt RKNN_QUERY_PERF_RUN die Modellinferenzzeit in Mikrosekunden ohne das Setzen der Ein- und Ausgaben ab.
Beispielcode:
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. Speicherzuweisung des Modells abfragen
Nach rknn_init kann RKNN_QUERY_MEM_SIZE bei eigener Speicherzuweisung durch den Benutzer den Gewichtsspeicher und internen Netzwerkspeicher ohne Ein- und Ausgaben abfragen. Dazu muss der Parameter flag von rknn_init RKNN_FLAG_MEM_ALLOC_OUTSIDE enthalten.
Beispielcode:
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. Benutzerdefinierte Modellzeichenfolge abfragen
Nach rknn_init ruft RKNN_QUERY_CUSTOM_STRING eine bei der RKNN-Modellerzeugung hinzugefügte benutzerdefinierte Zeichenfolge ab. Beispielsweise kann “RGB” bei der Konvertierung kennzeichnen, dass die Eingabe ein dreikanaliges RGB- statt BGR-Bild ist. Zur Laufzeit werden die Daten anhand der abgefragten Information “RGB” in ein RGB-Bild konvertiert.
Beispielcode:
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. Native Eingabetensorattribute abfragen (Zero-Copy-API)
RKNN_QUERY_NATIVE_INPUT_ATTR, gleichbedeutend mit RKNN_QUERY_NATIVE_NC1HWC2_INPUT_ATTR, fragt native Attribute des Modelleingabetensors ab. Zunächst ein Objekt der Struktur rknn_tensor_attr erstellen.
Beispielcode:
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. Native Ausgabetensorattribute abfragen (Zero-Copy-API)
RKNN_QUERY_NATIVE_OUTPUT_ATTR, gleichbedeutend mit RKNN_QUERY_NATIVE_NC1HWC2_OUTPUT_ATTR, fragt native Attribute des Modellausgabetensors ab. Zunächst ein Objekt der Struktur rknn_tensor_attr erstellen.
Beispielcode:
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. Native Ausgabetensorattribute abfragen (Quellüberschrift; der folgende Text betrifft die Eingabe, Zero-Copy-API)
RKNN_QUERY_NATIVE_NHWC_INPUT_ATTR fragt NHWC-Attribute des Modelleingabetensors ab. Zunächst ein Objekt der Struktur rknn_tensor_attr erstellen.
Beispielcode:
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. Native Ausgabetensorattribute abfragen (Zero-Copy-API)
RKNN_QUERY_NATIVE_NHWC_OUTPUT_ATTR fragt NHWC-Attribute des Modellausgabetensors ab. Zunächst ein Objekt der Struktur rknn_tensor_attr erstellen.
Beispielcode:
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. Vom RKNN-Modell unterstützte dynamische Eingabeformen abfragen
Hinweis: RV1106/RV1103/RV1106B/RV1103B/RK2118 unterstützen diese Schnittstelle nicht.
Nach rknn_init mit RKNN_QUERY_INPUT_DYNAMIC_RANGE die unterstützten Eingabeformen abfragen, einschließlich Anzahl, Liste, Layout, Namen und weiterer Angaben. Zunächst ein Objekt der Struktur rknn_input_range erstellen.
Beispielcode:
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. Speicherinformationen des Modellpuffers abfragen (Hinweis für RV1106/RV1103/RV1106B/RV1103B/RK2118)
Die Quelle erklärt diese Plattformen als nicht unterstützt; dies ist mit der Hardware-Unterstützungstabelle abzugleichen.
Nach rknn_init fragt RKNN_QUERY_DEVICE_MEM_INFO Attribute des intern in der Runtime erstellten Modellpuffers ab, einschließlich fd und physischer Adresse.
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. Aktuell verwendete dynamische Eingabeform des RKNN-Modells abfragen
Nach rknn_set_input_shapes mit RKNN_QUERY_CURRENT_INPUT_ATTR die aktuell verwendeten Modelleingabeattribute abfragen. Zunächst die Struktur rknn_tensor_attr erstellen.
Hinweis: RV1106/RV1103/RV1103B/RV1106B/RK2118 unterstützen diesen Befehl nicht.
Beispielcode:
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. Aktuell verwendete dynamische Ausgabeform des RKNN-Modells abfragen
Nach rknn_set_input_shapes mit RKNN_QUERY_CURRENT_OUTPUT_ATTR die aktuell verwendeten Modellausgabeattribute abfragen. Zunächst die Struktur rknn_tensor_attr erstellen.
Hinweis: RV1106/RV1103/RV1103B/RV1106B/RK2118 unterstützen diesen Befehl nicht.
Beispielcode:
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. Aktuell verwendete native dynamische Eingabeform des RKNN-Modells abfragen
Nach rknn_set_input_shapes mit RKNN_QUERY_CURRENT_NATIVE_INPUT_ATTR die aktuell verwendeten nativen Modelleingabeattribute abfragen. Zunächst die Struktur rknn_tensor_attr erstellen.
Hinweis: RV1106/RV1103/RV1103B/RV1106B/RK2118 unterstützen diesen Befehl nicht.
Beispielcode:
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. Aktuell verwendete native dynamische Ausgabeform des RKNN-Modells abfragen
Nach rknn_set_input_shapes nennt die Quelle RKNN_QUERY_CURRENT_OUTPUT_ATTR für die aktuellen nativen Ausgabeattribute. Zunächst rknn_tensor_attr erstellen. Der Befehlsname bleibt quellengetreu; seine Zuordnung zur nativen Ausgabe ist zu prüfen.
Hinweis: RV1106/RV1103/RV1103B/RV1106B/RK2118 unterstützen diesen Befehl nicht.
Beispielcode:
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
rknn_inputs_set setzt die Modelleingabedaten. Mehrere Eingaben werden unterstützt, jeweils als rknn_input-Objekt. Deren Felder sind vor Übergabe an rknn_inputs_set zu setzen. Auf RV1106/RV1103/RV1103B/RV1106B/RK2118 nicht verfügbar.
| API | rknn_inputs_set |
|---|---|
| Beschreibung | Setzt die Modelleingabedaten. |
| Parameter | rknn_context context: rknn_contex-Objekt (Quellschreibweise). |
| uint32_t n_inputs: Anzahl der Eingaben. | |
| rknn_input inputs[]: Array von rknn_input. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
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
rknn_run führt eine Modellinferenz aus. Zuvor müssen die Eingabedaten über rknn_inputs_set oder die Zero-Copy-Schnittstelle konfiguriert werden.
| API | rknn_run |
|---|---|
| Beschreibung | Führt eine Modellinferenz aus. |
| Parameter | rknn_context context: rknn_contex-Objekt (Quellschreibweise). |
| rknn_run_extend* extend: für Erweiterungen reserviert; im beschriebenen Stand ungenutzt, nur NULL zulässig. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
ret = rknn_run(ctx, NULL);
rknn_outputs_get
rknn_outputs_get ruft Modellausgabedaten ab. Mehrere Ausgaben werden unterstützt, jeweils als vor dem Aufruf zu erstellendes und zu initialisierendes rknn_output-Objekt. RV1106/RV1103/RV1106B/RV1103B/RK2118 werden nicht unterstützt.
Es gibt zwei Möglichkeiten, Puffer für Ausgabedaten bereitzustellen:
1. Der Benutzer weist die Puffer selbst zu und gibt sie frei. Dann ist rknn_output.is_prealloc auf 1 zu setzen; rknn_output.buf zeigt auf den Benutzerpuffer.
2. rknn weist den Speicher zu. Dann ist rknn_output.is_prealloc auf 0 zu setzen. Nach Ausführung wird rknn_output.buf mit den Ausgabedaten erstellt.
| API | rknn_outputs_get |
|---|---|
| Beschreibung | Ruft die Inferenz-Ausgabedaten ab. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| uint32_t n_outputs: Anzahl der Ausgaben. | |
| rknn_output outputs[]: Array von rknn_output. | |
| rknn_run_extend* extend: für Erweiterungen reserviert; derzeit ungenutzt, nur NULL zulässig. Typ quellengetreu beibehalten. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
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
rknn_outputs_release gibt die Ressourcen des rknn_output-Objekts frei.
| API | rknn_outputs_release |
|---|---|
| Beschreibung | Gibt das rknn_output-Objekt frei. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| uint32_t n_outputs: Anzahl der Ausgaben. | |
| rknn_output outputs[]: Array der freizugebenden rknn_output. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
ret = rknn_outputs_release(ctx, io_num.n_output, outputs);
rknn_create_mem_from_phys
Zur Bereitstellung von NPU-Speicher erstellt rknn_create_mem_from_phys eine rknn_tensor_mem-Struktur und gibt deren Zeiger zurück. Physische und virtuelle Adresse, Größe und Informationen zum externen Speicher werden in die Struktur übernommen.
| API | rknn_create_mem_from_phys |
|---|---|
| Beschreibung | Erstellt rknn_tensor_mem und stellt Speicher über eine physische Adresse bereit. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| uint64_t phys_addr: physische Pufferadresse. | |
| void *virt_addr: virtuelle Pufferadresse, Anfangsadresse des zu fd gehörenden Speichers. | |
| uint32_t size: Puffergröße. | |
| Rückgabe | rknn_tensor_mem*: Zeiger auf die Tensorspeicher-Informationsstruktur. |
Beispielcode:
//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
Zur Bereitstellung von NPU-Speicher erstellt rknn_create_mem_from_fd eine rknn_tensor_mem-Struktur und gibt deren Zeiger zurück. Dateideskriptor, logische Adresse, Größe und Informationen zum externen Speicher werden in die Struktur übernommen.
| API | rknn_create_mem_from_fd |
|---|---|
| Beschreibung / Parameter | Erstellt rknn_tensor_mem und stellt Speicher über einen Dateideskriptor bereit. |
| rknn_context context: rknn_context-Objekt. | |
| int32_t fd: Dateideskriptor des Puffers. | |
| void *virt_addr: virtuelle Pufferadresse am Beginn von fd. | |
| uint32_t size: Puffergröße. | |
| int32_t offset: zum Dateideskriptor und zur virtuellen Adresse gehörender Offset. | |
| Rückgabe | rknn_tensor_mem*: Zeiger auf die Tensorspeicher-Informationsstruktur. |
Beispielcode:
//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
rknn_create_mem weist die vom Benutzer angegebene Größe direkt von der NPU nutzbaren Speichers zu und gibt eine rknn_tensor_mem-Struktur zurück.
| API | rknn_create_mem |
|---|---|
| Beschreibung | Erstellt intern in der Runtime rknn_tensor_mem und weist Speicher zu. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| uint32_t size: Puffergröße. | |
| Rückgabe | rknn_tensor_mem*: Zeiger auf die Tensorspeicher-Informationsstruktur. |
Beispielcode:
//suppose we have got buffer size
rknn_tensor_mem* input_mems [1];
input_mems[0] = rknn_create_mem(ctx, size);
rknn_create_mem2
rknn_create_mem2 weist direkt von der NPU nutzbaren Speicher mit benutzerdefinierter Größe und Art zu und gibt eine rknn_tensor_mem-Struktur zurück.
| API | rknn_create_mem2 |
|---|---|
| Beschreibung | Erstellt intern in der Runtime rknn_tensor_mem und weist Speicher zu. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| uint64_t size: Puffergröße. | |
| uint64_t alloc_flags: Cachefähigkeit des zugewiesenen Speichers. RKNN_FLAG_MEMORY_CACHEABLE — cachefähig; RKNN_FLAG_MEMORY_NON_CACHEABLE — nicht cachefähig; RKNN_FLAG_MEMORY_FLAGS_DEFAULT — wie RKNN_FLAG_MEMORY_CACHEABLE. | |
| Rückgabe | rknn_tensor_mem*: Zeiger auf die Tensorspeicher-Informationsstruktur. |
Der Hauptunterschied zwischen rknn_create_mem2 und rknn_create_mem ist alloc_flags, mit dem sich die Cachefähigkeit festlegen lässt. rknn_create_mem erlaubt diese Auswahl nicht und weist standardmäßig cachefähigen Speicher zu.
Beispielcode:
//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
rknn_destroy_mem zerstört die rknn_tensor_mem-Struktur. Vom Benutzer zugewiesener Speicher muss jedoch manuell freigegeben werden.
| API | rknn_destroy_mem |
|---|---|
| Beschreibung | Zerstört die rknn_tensor_mem-Struktur. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| rknn_tensor_mem*: Zeiger auf die Tensorspeicher-Informationsstruktur. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
rknn_tensor_mem* input_mems [1];
int ret = rknn_destroy_mem(ctx, input_mems[0]);
rknn_set_weight_mem
Hat der Benutzer Speicher für die Netzwerkgewichte zugewiesen, kann die NPU ihn nach Initialisierung der zugehörigen rknn_tensor_mem über rknn_set_weight_mem nutzen. Der Aufruf muss vor rknn_run erfolgen.
| API | rknn_set_weight_mem |
|---|---|
| Beschreibung | Setzt rknn_tensor_mem mit Informationen zum Gewichtsspeicher. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| rknn_tensor_mem*: Zeiger auf die Tensorspeicher-Informationsstruktur. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
rknn_tensor_mem* weight_mems [1];
int ret = rknn_set_weight_mem(ctx, weight_mems[0]);
rknn_set_internal_mem
Hat der Benutzer Speicher für interne Netzwerktensoren zugewiesen, kann die NPU ihn nach Initialisierung der zugehörigen rknn_tensor_mem über rknn_set_internal_mem nutzen. Der Aufruf muss vor rknn_run erfolgen.
| API | rknn_set_internal_mem |
|---|---|
| Beschreibung | Setzt rknn_tensor_mem mit Informationen zum Speicher interner Netzwerktensoren. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| rknn_tensor_mem*: Zeiger auf die Tensorspeicher-Informationsstruktur. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
rknn_tensor_mem* internal_tensor_mems [1];
int ret = rknn_set_internal_mem(ctx, internal_tensor_mems[0]);
rknn_set_io_mem
Hat der Benutzer Speicher für Ein-/Ausgabetensoren zugewiesen, kann die NPU ihn nach Initialisierung der zugehörigen rknn_tensor_mem über rknn_set_io_mem nutzen. Der Aufruf muss vor rknn_run erfolgen.
| API | rknn_set_io_mem |
|---|---|
| Beschreibung | Setzt rknn_tensor_mem mit Informationen zum Speicher der Ein-/Ausgabetensoren des Netzwerks. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| rknn_tensor_mem*: Zeiger auf die Tensorspeicher-Informationsstruktur. | |
| rknn_tensor_attr *: Attribute des Ein- oder Ausgabetensorpuffers. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
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 (veraltet)
Diese Schnittstelle ist veraltet. Eingabeformen sind mit rknn_set_input_shapes zu binden. In der aktuellen Version ist die alte Schnittstelle nicht verfügbar. Für ihre weitere Nutzung sind SDK 1.5.0 und dessen Anleitung erforderlich.
rknn_set_input_shapes
Bei RKNN-Modellen mit dynamischen Eingabeformen muss vor der Inferenz die aktuelle Form festgelegt werden. Übergeben werden die Eingabeanzahl und ein rknn_tensor_attr-Array mit Form und Datenlayout jeder Eingabe. In jedem rknn_tensor_attr sind index, name, dims und fmt auszufüllen; andere Felder müssen nicht gesetzt werden. Zuvor lassen sich Anzahl und Liste unterstützter dynamischer Formen über rknn_query abfragen. Die Eingabeform muss in dieser Liste enthalten sein. Die Schnittstelle ist beim ersten Lauf und bei jedem Formwechsel aufzurufen, sonst nicht erneut.
| API | rknn_set_input_shapes |
|---|---|
| Beschreibung | Setzt die aktuell verwendete Modelleingabeform. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| uint32_t n_inputs: Anzahl der Eingabetensoren. | |
| rknn_tensor_attr *: Zeiger auf das Attributarray sämtlicher Eingabeformen. Für jede Eingabe sind index, name, dims, fmt und n_dims zu setzen; weitere Felder sind nicht erforderlich. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
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
Von rknn_create_mem erzeugter Speicher ist standardmäßig cachefähig. Bei gleichzeitiger Nutzung durch CPU und NPU kann das Cacheverhalten zu inkonsistenten Daten führen. Diese Schnittstelle synchronisiert cachefähigen Speicher, damit CPU und NPU konsistente Daten sehen.
| API | rknn_mem_sync |
|---|---|
| Beschreibung | Synchronisiert CPU-Cache- und DDR-Daten. |
| Parameter | rknn_context context: rknn_context-Objekt. |
| rknn_tensor_mem* mem: Zeiger auf die Tensorspeicher-Informationsstruktur. | |
| rknn_mem_sync_mode mode: Aktualisierungsmodus für CPU-Cache und DDR. RKNN_MEMORY_SYNC_TO_DEVICE — schreibt CPU-Cache-Daten in DDR zurück, üblicherweise nach CPU-Schreiben und vor NPU-Zugriff auf denselben Speicher. RKNN_MEMORY_SYNC_FROM_DEVICE — synchronisiert DDR mit dem CPU-Cache, üblicherweise nach NPU-Schreiben: invalidiert den Cache, damit die CPU beim nächsten Zugriff DDR neu liest. RKNN_MEMORY_SYNC_BIDIRECTIONAL — schreibt CPU-Cache-Daten in DDR zurück und lässt die CPU DDR neu lesen. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
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 Datenstrukturen der Matrixmultiplikation
rknn_matmul_info
rknn_matmul_info beschreibt die Spezifikation der Matrixmultiplikation: Dimensionen, Datentyp und Speicherlayout der Ein- und Ausgabematrizen. Die Strukturdefinition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| M | int32_t | Zeilenanzahl von A. |
| K | int32_t | Spaltenanzahl von A. |
| N | int32_t | Spaltenanzahl von B. |
| type | rknn_matmul_type | Datentypen der Ein- und Ausgabematrizen: RKNN_FLOAT16_MM_FLOAT16_TO_FLOAT32: A/B — float16, C — float; RKNN_INT8_MM_INT8_TO_INT32: A/B — int8, C — int32; RKNN_INT8_MM_INT8_TO_INT8: A/B/C — int8; RKNN_FLOAT16_MM_FLOAT16_TO_FLOAT16: A/B/C — float16; RKNN_FLOAT16_MM_INT8_TO_FLOAT32: A — float16, B — int8, C — float; RKNN_FLOAT16_MM_INT8_TO_FLOAT16: A — float16, B — int8, C — float16; RKNN_FLOAT16_MM_INT4_TO_FLOAT32: A — float16, B — int4, C — float; RKNN_FLOAT16_MM_INT4_TO_FLOAT16: A — float16, B — int4, C — float16; RKNN_INT8_MM_INT8_TO_FLOAT32: A/B — int8, C — float; RKNN_INT4_MM_INT4_TO_INT16: A/B — int4, C — int16; RKNN_INT8_MM_INT4_TO_INT32: A — int8, B — int4, C — int32. |
| B_layout | int16_t | Speicherlayout von B. 0 bezeichnet [K,N]. RKNN_MM_LAYOUT_NORM — ursprüngliche Form KxN; RKNN_MM_LAYOUT_NATIVE — leistungsoptimiertes Layout; RKNN_MM_LAYOUT_TP_NORM — transponierte Form NxK. |
| B_quant_type | int16_t | Quantisierung von B: RKNN_QUANT_TYPE_PER_LAYER_SYM — symmetrisch pro Schicht; RKNN_QUANT_TYPE_PER_LAYER_ASYM — asymmetrisch pro Schicht; RKNN_QUANT_TYPE_PER_CHANNEL_SYM — symmetrisch pro Kanal; RKNN_QUANT_TYPE_PER_CHANNEL_ASYM — asymmetrisch pro Kanal; RKNN_QUANT_TYPE_PER_GROUP_SYM — symmetrisch pro Gruppe; RKNN_QUANT_TYPE_PER_GROUP_ASYM — asymmetrisch pro Gruppe. |
| AC_layout | int16_t | Datenlayout von A und C: RKNN_MM_LAYOUT_NORM — ursprüngliche Formen; RKNN_MM_LAYOUT_NATIVE — leistungsoptimierte Formen. |
| AC_quant_type | int16_t | Quantisierung von A und C: RKNN_QUANT_TYPE_PER_LAYER_SYM — symmetrisch pro Schicht; RKNN_QUANT_TYPE_PER_LAYER_ASYM — asymmetrisch pro Schicht. |
| iommu_domain_id | int32_t | Index der IOMMU-Adressraumdomäne des Matrixkontexts. Adressraum und Kontext sind einander eindeutig zugeordnet; jeder Adressraum umfasst 4 GB. Der Parameter wird hauptsächlich für große A/B/C verwendet, wenn nach mehr als 4 GB NPU-Speicherzuweisung in einer Domäne ein Wechsel in eine andere nötig ist. |
| group_size | int16_t | Elementanzahl je Gruppe; nur bei aktivierter Gruppenquantisierung wirksam. |
| reserved | int8_t[] | Reserviertes Feld. |
rknn_matmul_tensor_attr
rknn_matmul_tensor_attr beschreibt die Tensorattribute jeder Matrix: Name, Form, Größe und Datentyp. Die Strukturdefinition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| name | char[] | Matrixname. |
| n_dims | uint32_t | Anzahl der Matrixdimensionen. |
| dims | uint32_t[] | Matrixform. |
| size | uint32_t | Matrixgröße. |
| type | rknn_tensor_type | Matrixdatentyp. |
rknn_matmul_io_attr
rknn_matmul_io_attr beschreibt alle Ein- und Ausgabetensoren der Matrixoperation, einschließlich der Attribute von A, B und C. Die Strukturdefinition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| A | rknn_matmul_tensor_attr | Tensorattribute der Matrix A. |
| B | rknn_matmul_tensor_attr | Tensorattribute der Matrix B. |
| C | rknn_matmul_tensor_attr | Tensorattribute der Matrix C. |
rknn_quant_params
rknn_quant_params beschreibt die Quantisierungsparameter einer Matrix: Name sowie Zeiger und Längen der Arrays scale und zero_point. name kennzeichnet die Matrix und lässt sich aus der bei Kontextinitialisierung erhaltenen rknn_matmul_io_attr entnehmen. Die Strukturdefinition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| name | char[] | Matrixname. |
| scale | float* | Zeiger auf das scale-Array der Matrix. |
| scale_len | int32_t | Länge des scale-Arrays der Matrix. |
| zp | int32_t* | Zeiger auf das zero_point-Array der Matrix. |
| zp_len | int32_t | Länge des zero_point-Arrays der Matrix. |
rknn_matmul_shape
rknn_matmul_shape beschreibt M, K und N einer bestimmten Matrixmultiplikationsform. Bei Initialisierung eines Kontexts mit dynamischen Formen sind die Formenanzahl und ein rknn_matmul_shape-Array sämtlicher Eingabeformen anzugeben. Die Strukturdefinition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| M | int32_t | Zeilenanzahl von A. |
| K | int32_t | Spaltenanzahl von A. |
| N | int32_t | Spaltenanzahl von C. |
4.5 Matrixmultiplikations-API
rknn_matmul_create
Die Funktion initialisiert den Matrixmultiplikationskontext anhand der übergebenen Spezifikation und weiterer Informationen. Sie gibt Form, Größe, Datentyp und weitere Attribute der Ein- und Ausgabetensoren zurück. Der Zeiger rknn_matmul_ctx und rknn_context haben hier dieselbe Datenstruktur.
| API | rknn_matmul_create |
|---|---|
| Beschreibung | Initialisiert den Matrixmultiplikationskontext. |
| Parameter | rknn_matmul_ctx* ctx: Zeiger auf den Matrixmultiplikationskontext. |
| rknn_matmul_info* info: Zeiger auf die Spezifikationsstruktur der Matrixmultiplikation. | |
| rknn_matmul_io_attr* io_attr: Zeiger auf die Attributstruktur der Ein-/Ausgabetensoren der Matrixmultiplikation. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
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
Die Funktion setzt den Ein-/Ausgabespeicher der Matrixmultiplikation. Zunächst über rknn_create_mem einen rknn_tensor_mem-Zeiger erstellen, dann gemeinsam mit dem von rknn_matmul_create erhaltenen rknn_matmul_tensor_attr-Zeiger für A, B oder C übergeben. Dadurch wird der Speicher im Operationskontext gebunden. Zuvor müssen die Daten von A und B gemäß dem in rknn_matmul_info konfigurierten Speicherlayout vorbereitet werden.
| API | rknn_matmul_set_io_mem |
|---|---|
| Beschreibung | Setzt den Ein-/Ausgabespeicher für Matrixmultiplikation. |
| Parameter | rknn_matmul_ctx ctx: Matrixmultiplikationskontext. |
| rknn_tensor_mem* mem: Zeiger auf die Tensorspeicher-Informationsstruktur. | |
| rknn_matmul_tensor_attr* attr: Zeiger auf die Attributstruktur der Ein-/Ausgabetensoren der Matrixmultiplikation. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
// 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
Die Funktion legt die verfügbaren NPU-Kerne für Matrixmultiplikation fest; nur RK3588 und RK3576 werden unterstützt. Zuvor den Kontext mit rknn_matmul_create initialisieren. Der Maskenwert wählt die verwendeten Kerne zur Verbesserung von Leistung und Effizienz der Matrixmultiplikation.
| API | rknn_matmul_set_core_mask |
|---|---|
| Beschreibung | Setzt die NPU-Kernmaske für Matrixmultiplikation. |
| Parameter | rknn_matmul_ctx ctx: Matrixmultiplikationskontext. |
| rknn_core_mask core_mask: Maske verfügbarer NPU-Kerne für Matrixmultiplikation. Jedes Bit bezeichnet einen Kern: 1 bedeutet verfügbar, sonst nicht verfügbar. Details siehe Parameter von rknn_set_core_mask. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
rknn_matmul_set_core_mask(ctx, RKNN_NPU_CORE_AUTO);
rknn_matmul_set_quant_params
rknn_matmul_set_quant_params setzt die Quantisierungsparameter jeder Matrix für Per-Channel oder Per-Layer. Bei Per-Channel haben scale und zp in rknn_quant_params die Länge N, bei Per-Layer die Länge 1. Die Parameter aller Matrizen sind vor rknn_matmul_run zu setzen. Ohne diesen Aufruf gilt Per-Layer mit scale=1.0 und zero_point=0.
| API | rknn_matmul_set_quant_params |
|---|---|
| Beschreibung | Setzt die Quantisierungsparameter der Matrix. |
| Parameter | rknn_matmul_ctx ctx: Matrixmultiplikationskontext. |
| rknn_quant_params* params: Quantisierungsparameter der Matrix. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
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);
rknn_matmul_get_quant_params
rknn_matmul_get_quant_params wird bei rknn_matmul_type=RKNN_INT8_MM_INT8_TO_INT32 und Per-Channel-Quantisierung verwendet, um die normalisierten scale-Werte aller Kanäle von B zu erhalten. Der erhaltene Wert multipliziert mit dem ursprünglichen scale von A ergibt scale von C. Damit lässt sich scale von C näherungsweise bestimmen, wenn kein tatsächlicher Wert vorliegt.
| API | rknn_matmul_get_quant_params |
|---|---|
| Beschreibung | Ruft die Quantisierungsparameter von Matrix B ab. |
| Parameter | rknn_matmul_ctx ctx: Matrixmultiplikationskontext. |
| rknn_quant_params* params: Quantisierungsparameter von Matrix B. | |
| float* scale: Zeiger auf scale von Matrix B. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
float b_scale;
rknn_matmul_get_quant_params(ctx, ¶ms_b, &b_scale);
rknn_matmul_create_dynamic_shape
rknn_matmul_create_dynamic_shape erstellt einen Matrixmultiplikationskontext mit dynamischen Formen. Übergeben werden rknn_matmul_info, Formenanzahl und ein entsprechendes Array mehrerer M-, K- und N-Werte. Nach erfolgreicher Initialisierung wird ein rknn_matmul_io_attr-Array mit Form, Größe und Datentyp aller Ein- und Ausgabematrizen zurückgegeben. Im beschriebenen Stand lassen sich mehrere unterschiedliche M, K und N festlegen.
| API | rknn_matmul_create_dynamic_shape |
|---|---|
| Beschreibung | Initialisiert den Matrixmultiplikationskontext mit dynamischen Formen. |
| Parameter | rknn_matmul_ctx *ctx: Zeiger auf den Matrixmultiplikationskontext. |
| rknn_matmul_info* info: Zeiger auf die Spezifikationsstruktur der Matrixmultiplikation. M, K und N müssen nicht gesetzt werden. | |
| int shape_num: Anzahl der vom Kontext unterstützten Formen. | |
| rknn_matmul_shape dynamic_shapes[]: Array der vom Kontext unterstützten Formen. | |
| rknn_matmul_io_attr io_attrs[]: Array der Attributstrukturen der Ein-/Ausgabetensoren der Matrixmultiplikation. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
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 (veraltet)
Diese Schnittstelle ist veraltet und durch rknn_matmul_create_dynamic_shape ersetzt.
rknn_matmul_set_dynamic_shape
rknn_matmul_set_dynamic_shape wählt eine bestimmte Form für die Matrixmultiplikation. Nach Erstellung des Kontexts für dynamische Formen eine der rknn_matmul_shape-Strukturen übergeben, um die Form der Operation festzulegen.
| API | rknn_matmul_set_dynamic_shape |
|---|---|
| Beschreibung | Setzt die Matrixmultiplikationsform. |
| Parameter | rknn_matmul_ctx ctx: Matrixmultiplikationskontext. |
| rknn_matmul_shape* shape: für die Matrixmultiplikation verwendete Form. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
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 konvertiert die Daten von B aus dem ursprünglichen Layout (KxN) in ein leistungsoptimiertes Datenlayout.
| API | rknn_B_normal_layout_to_native_layout |
|---|---|
| Beschreibung | Konvertiert das Datenlayout von B aus der ursprünglichen in eine leistungsoptimierte Form. |
| Parameter | void* B_input: Zeiger auf die Daten von B im ursprünglichen Layout. |
| void* B_output: Zeiger auf die Daten von B im leistungsoptimierten Layout. | |
| int K: Zeilenanzahl von B. | |
| int N: Spaltenanzahl von B. | |
| int subN: entspricht B.dims[2] in rknn_matmul_io_attr. | |
| int subK: entspricht B.dims[3] in rknn_matmul_io_attr. | |
| rknn_matmul_info* info: Zeiger auf die Informationsstruktur zur Matrixmultiplikation. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
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
Die Funktion führt die Matrixmultiplikation aus und speichert das Ergebnis in C. Zuvor A und B vorbereiten und ihre Eingabepuffer über rknn_matmul_set_io_mem setzen. Auch der Ausgabepuffer von C wird über rknn_matmul_set_io_mem gesetzt; die Ausgabetensorattribute stammen aus rknn_matmul_create.
| API | rknn_matmul_run |
|---|---|
| Beschreibung | Führt eine Matrixmultiplikation aus. |
| Parameter | rknn_matmul_ctx ctx: Matrixmultiplikationskontext. |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
int ret = rknn_matmul_run(ctx);
rknn_matmul_destroy
Die Funktion zerstört den Matrixmultiplikationskontext und gibt zugehörige Ressourcen frei. Nach Verwendung des durch rknn_matmul_create erstellten Zeigers ist diese Funktion zur Zerstörung aufzurufen.
| API | rknn_matmul_destroy |
|---|---|
| Beschreibung | Zerstört den Matrixmultiplikationskontext. |
| Parameter | rknn_matmul_ctx ctx: Matrixmultiplikationskontext. |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
int ret = rknn_matmul_destroy(ctx);
4.6 Datenstrukturen benutzerdefinierter Operatoren
rknn_gpu_op_context
rknn_gpu_op_context enthält den Kontext eines auf der angegebenen GPU ausgeführten benutzerdefinierten Operators. Die Strukturdefinition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| cl_context | void* | OpenCL-Objekt cl_context; bei Verwendung explizit in cl_context umwandeln. |
| cl_command_queue | void* | OpenCL-Objekt cl_command_queue; bei Verwendung explizit in cl_command_queue umwandeln. |
| cl_kernel | void* | OpenCL-Objekt cl_kernel; bei Verwendung explizit in cl_kernel umwandeln. |
rknn_custom_op_context
rknn_custom_op_context enthält die Kontextinformationen eines benutzerdefinierten Operators. Die Strukturdefinition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| target | rknn_target_type | Ausführungsgerät benutzerdefinierter Operatoren: RKNN_TARGET_TYPE_CPU: CPU; RKNN_TARGET_TYPE_CPU: GPU. Die doppelte CPU-Konstante für GPU steht so in der Quelle und ist zu prüfen. |
| internal_ctx | rknn_custom_op_interal_context | Privater Kontext innerhalb des Operators. |
| gpu_ctx | rknn_gpu_op_context | OpenCL-Kontextinformationen des benutzerdefinierten Operators. Bei GPU-Ausführung erhält der Callback OpenCL-Objekte wie cl_context aus dieser Struktur. |
| priv_data | void* | Datenzeiger, deren Verwaltung dem Entwickler überlassen bleibt. |
rknn_custom_op_tensor
rknn_custom_op_tensor beschreibt den Ein-/Ausgabetensor eines benutzerdefinierten Operators. Die Strukturdefinition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| attr | rknn_tensor_attr | Name, Form, Größe und weitere Tensorinformationen. |
| mem | rknn_tensor_mem | Tensorspeicheradresse, fd, Offset gültiger Daten und weitere Informationen. |
rknn_custom_op_attr
rknn_custom_op_attr beschreibt Parameter oder Attribute eines benutzerdefinierten Operators. Die Strukturdefinition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| name | char[] | Parametername des benutzerdefinierten Operators. |
| dtype | rknn_tensor_type | Datentyp jedes Elements. |
| n_elems | uint32_t | Elementanzahl. |
| data | void* | Virtuelle Adresse des Parameterspeicherbereichs. |
rknn_custom_op
rknn_custom_op enthält die Registrierungsinformationen eines benutzerdefinierten Operators. Die Strukturdefinition folgt in der Tabelle:
| Feld | Typ | Bedeutung |
|---|---|---|
| version | uint32_t | Versionsnummer des benutzerdefinierten Operators. |
| target | rknn_target_type | Ausführungs-Backendtyp des Operators. |
| op_type | char[] | Typ des benutzerdefinierten Operators. |
| cl_kernel_name | char[] | Name der OpenCL-Kernelfunktion. |
| cl_kernel_source | char* | OpenCL-Ressource: bei cl_source_size=0 ein absoluter Dateipfad; bei cl_source_size>0 eine Zeichenfolge mit Kernelfunktionscode. |
| cl_source_size | uint64_t | Ist cl_kernel_source eine Zeichenfolge, deren Länge; bei einem Dateipfad 0. |
| cl_build_options | char[] | Kompilieroptionen des OpenCL-Kernels. |
| 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); |
Zeiger auf den Initialisierungs-Callback des Operators. Einmal bei Registrierung aufgerufen; bei Nichtbedarf NULL zulässig. |
| 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); |
Zeiger auf den Vorverarbeitungs-Callback. Einmal während rknn_run aufgerufen; bei Nichtbedarf NULL zulässig. |
| 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); |
Zeiger auf den Berechnungs-Callback des benutzerdefinierten Operators. Einmal während rknn_run aufgerufen; NULL unzulässig. |
| 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); |
Zeiger auf den leistungsoptimierten Berechnungs-Callback. Unterschied zu compute ist das Format der Ein-/Ausgabetensoren. Noch nicht unterstützt; auf NULL setzen. |
| destroy | int ()(rknn_custom_op_context op_ctx); |
Zeiger auf den Callback zum Freigeben von Ressourcen. Einmal während rknn_destroy aufgerufen. |
4.7 API benutzerdefinierter Operatoren
rknn_register_custom_ops
Nach erfolgreicher Kontextinitialisierung registriert die Funktion mehrere benutzerdefinierte Operatoren: Typen, Ausführungs-Backends, OpenCL-Kernelinformationen und Callback-Zeiger. Nach erfolgreicher Registrierung ruft rknn_run während der Inferenz die vom Entwickler implementierten Callbacks auf.
| API | rknn_register_custom_ops |
|---|---|
| Beschreibung | Registriert mehrere benutzerdefinierte Operatoren im Kontext. |
| Parameter | rknn_context *context: rknn_context-Zeiger. Der Kontext muss vor dem Aufruf erfolgreich initialisiert sein. |
| rknn_custom_op* op: Array der Operatorinformationen; jedes Element ist ein rknn_custom_op-Strukturobjekt. | |
| uint32_t custom_op_num: Länge des Operatorinformationsarrays. | |
| Rückgabe | int: Fehlercode (siehe RKNN-Fehlercodes). |
Beispielcode:
// 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
Die Funktion liest Parameter eines benutzerdefinierten Operators innerhalb dessen Callback aus, etwa axis bei Softmax. Übergeben werden der Feldname des Parameters und ein Zeiger auf rknn_custom_op_attr. Nach dem Aufruf steht der Wert im Feld data. Der Entwickler wandelt den Zeiger gemäß dtype der zurückgegebenen Struktur in den Anfang eines Arrays des entsprechenden C-Datentyps um und liest anhand der Elementanzahl den vollständigen Parameterwert.
| API | rknn_custom_op_get_op_attr |
|---|---|
| Beschreibung | Ruft Parameter oder Attribute eines benutzerdefinierten Operators ab. |
| Parameter | rknn_custom_op_context* op_ctx: Zeiger auf den Operatorkontext. |
| const char* attr_name: Feldname des Operatorparameters. | |
| rknn_custom_op_attr* op_attr: Struktur für den Wert des Operatorparameters. | |
| Rückgabe | Kein Wert. |
Beispielcode:
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-Fehlercodes
Die Rückgabecodes der RKNN-API-Funktionen sind in der folgenden Tabelle definiert.
| Fehlercode | Meldung |
|---|---|
| RKNN_SUCC(0) | Erfolgreiche Ausführung. |
| RKNN_ERR_FAIL (-1) | Ausführungsfehler. |
| RKNN_ERR_TIMEOUT (-2) | Ausführungs-Timeout. |
| RKNN_ERR_DEVICE_UNAVAILABLE (-3) | NPU-Gerät nicht verfügbar. |
| RKNN_ERR_MALLOC_FAIL (-4) | Speicherzuweisung fehlgeschlagen. |
| RKNN_ERR_PARAM_INVALID (-5) | Parameterfehler. |
| RKNN_ERR_MODEL_INVALID (-6) | Ungültiges RKNN-Modell. |
| RKNN_ERR_CTX_INVALID (-7) | Ungültiger rknn_context. |
| RKNN_ERR_INPUT_INVALID (-8) | Ungültiges rknn_input-Objekt. |
| RKNN_ERR_OUTPUT_INVALID (-9) | Ungültiges rknn_output-Objekt. |
| RKNN_ERR_DEVICE_UNMATCH (-10) | Versionen stimmen nicht überein. |
| RKNN_ERR_INCOMPATILE_OPTIMIZATION_LEVEL_VERSION (-12) |
Das RKNN-Modell verwendet einen Optimierungsstufenmodus, der zum aktuellen Treiber inkompatibel ist. |
| RKNN_ERR_TARGET_PLATFORM_UNMATCH (-13) | Das RKNN-Modell ist mit der aktuellen Plattform inkompatibel. |
