Ekstensi vendor Neural Networks API (NNAPI), yang diperkenalkan di Android 10, adalah kumpulan operasi dan jenis data yang ditentukan vendor. Pada perangkat yang menjalankan NN HAL 1.2 atau yang lebih tinggi, driver dapat menyediakan operasi dengan akselerasi hardware kustom dengan mendukung ekstensi vendor yang sesuai. Ekstensi vendor tidak mengubah perilaku operasi yang ada.
Ekstensi vendor memberikan alternatif yang lebih terstruktur untuk operasi OEM dan jenis data, yang tidak digunakan lagi di Android 10. Untuk mengetahui informasi selengkapnya, lihat Jenis data dan operasi OEM.
Daftar yang diizinkan untuk penggunaan ekstensi
Ekstensi vendor hanya dapat digunakan oleh aplikasi Android dan biner native yang ditentukan secara eksplisit di partisi /product
, /vendor
, /odm
, dan /data
.
Aplikasi dan biner native yang berada di partisi /system
tidak dapat menggunakan ekstensi vendor.
Daftar aplikasi dan biner Android yang diizinkan untuk menggunakan ekstensi vendor NNAPI disimpan di /vendor/etc/nnapi_extensions_app_allowlist
. Setiap baris file
berisi entri baru. Entri dapat berupa jalur biner native yang diawali dengan
garis miring (/), misalnya, /data/foo
, atau nama paket aplikasi Android, misalnya, com.foo.bar
.
Daftar yang diizinkan diterapkan dari library bersama runtime NNAPI. Library ini melindungi dari penggunaan yang tidak disengaja, tetapi tidak melindungi dari penghindaran yang disengaja oleh aplikasi yang langsung menggunakan antarmuka HAL driver NNAPI.
Definisi ekstensi vendor
Vendor membuat dan mengelola file header dengan definisi ekstensi. Contoh lengkap definisi ekstensi dapat ditemukan di
example/fibonacci/FibonacciExtension.h
.
Setiap ekstensi harus memiliki nama unik yang dimulai dengan nama domain terbalik vendor.
const char EXAMPLE_EXTENSION_NAME[] = "com.example.my_extension";
Nama ini berfungsi sebagai namespace untuk operasi dan jenis data. NNAPI menggunakan nama ini untuk membedakan ekstensi vendor.
Operasi dan jenis data dideklarasikan dengan cara yang serupa dengan yang ada di
runtime/include/NeuralNetworks.h
.
enum {
/**
* A custom scalar type.
*/
EXAMPLE_SCALAR = 0,
/**
* A custom tensor type.
*
* Attached to this tensor is {@link ExampleTensorParams}.
*/
EXAMPLE_TENSOR = 1,
};
enum {
/**
* Computes example function.
*
* Inputs:
* * 0: A scalar of {@link EXAMPLE_SCALAR}.
*
* Outputs:
* * 0: A tensor of {@link EXAMPLE_TENSOR}.
*/
EXAMPLE_FUNCTION = 0,
};
Operasi ekstensi dapat menggunakan jenis operand apa pun, termasuk jenis operand non-ekstensi dan jenis operand dari ekstensi lain. Saat menggunakan jenis operand dari ekstensi lain, driver harus mendukung ekstensi lain tersebut.
Ekstensi juga dapat mendeklarasikan struktur kustom untuk menyertai operan ekstensi.
/**
* Quantization parameters for {@link EXAMPLE_TENSOR}.
*/
typedef struct ExampleTensorParams {
double scale;
int64_t zeroPoint;
} ExampleTensorParams;
Menggunakan ekstensi di klien NNAPI
File
runtime/include/NeuralNetworksExtensions.h
(C API) menyediakan dukungan ekstensi runtime. Bagian ini memberikan
ringkasan C API.
Untuk memeriksa apakah perangkat mendukung ekstensi, gunakan
ANeuralNetworksDevice_getExtensionSupport
.
bool isExtensionSupported;
CHECK_EQ(ANeuralNetworksDevice_getExtensionSupport(device, EXAMPLE_EXTENSION_NAME,
&isExtensionSupported),
ANEURALNETWORKS_NO_ERROR);
if (isExtensionSupported) {
// The device supports the extension.
...
}
Untuk membuat model dengan operan ekstensi, gunakan
ANeuralNetworksModel_getExtensionOperandType
untuk mendapatkan jenis operan dan panggil
ANeuralNetworksModel_addOperand
.
int32_t type;
CHECK_EQ(ANeuralNetworksModel_getExtensionOperandType(model, EXAMPLE_EXTENSION_NAME, EXAMPLE_TENSOR, &type),
ANEURALNETWORKS_NO_ERROR);
ANeuralNetworksOperandType operandType{
.type = type,
.dimensionCount = dimensionCount,
.dimensions = dimensions,
};
CHECK_EQ(ANeuralNetworksModel_addOperand(model, &operandType), ANEURALNETWORKS_NO_ERROR);
Secara opsional, gunakan
ANeuralNetworksModel_setOperandExtensionData
untuk mengaitkan data tambahan dengan operan ekstensi.
ExampleTensorParams params{
.scale = 0.5,
.zeroPoint = 128,
};
CHECK_EQ(ANeuralNetworksModel_setOperandExtensionData(model, operandIndex, ¶ms, sizeof(params)),
ANEURALNETWORKS_NO_ERROR);
Untuk membuat model dengan operasi ekstensi, gunakan
ANeuralNetworksModel_getExtensionOperationType
untuk mendapatkan jenis operasi dan panggil
ANeuralNetworksModel_addOperation
.
ANeuralNetworksOperationType type;
CHECK_EQ(ANeuralNetworksModel_getExtensionOperationType(model, EXAMPLE_EXTENSION_NAME, EXAMPLE_FUNCTION,
&type),
ANEURALNETWORKS_NO_ERROR);
CHECK_EQ(ANeuralNetworksModel_addOperation(model, type, inputCount, inputs, outputCount, outputs),
ANEURALNETWORKS_NO_ERROR);
Menambahkan dukungan ekstensi ke driver NNAPI
Driver melaporkan ekstensi yang didukung melalui metode
IDevice::getSupportedExtensions
. Daftar yang ditampilkan harus berisi entri yang menjelaskan setiap ekstensi yang didukung.
Extension {
.name = EXAMPLE_EXTENSION_NAME,
.operandTypes = {
{
.type = EXAMPLE_SCALAR,
.isTensor = false,
.byteSize = 8,
},
{
.type = EXAMPLE_TENSOR,
.isTensor = true,
.byteSize = 8,
},
},
}
Dari 32 bit yang digunakan untuk mengidentifikasi jenis dan operasi, bit
Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX
tinggi adalah
awalan ekstensi dan bit
Model::ExtensionTypeEncoding::LOW_BITS_TYPE
rendah mewakili jenis atau operasi
ekstensi.
Saat menangani jenis operasi atau operand, driver harus memeriksa awalan
ekstensi. Jika awalan ekstensi memiliki nilai bukan nol, jenis operasi atau operandanya adalah jenis ekstensi. Jika nilainya adalah 0
, jenis operasi atau operand
bukan jenis ekstensi.
Untuk memetakan awalan ke nama ekstensi, cari di
model.extensionNameToPrefix
.
Pemetaan dari awalan ke nama ekstensi adalah korespondensi satu-ke-satu
(bijeksi) untuk model tertentu. Nilai awalan yang berbeda mungkin sesuai dengan nama ekstensi yang sama dalam model yang berbeda.
Driver harus memvalidasi operasi dan jenis data ekstensi karena runtime NNAPI tidak dapat memvalidasi operasi dan jenis data ekstensi tertentu.
Operand ekstensi dapat memiliki data terkait di
operand.extraParams.extension
,
yang diperlakukan runtime sebagai blob data mentah berukuran arbitrer.
Jenis data dan operasi OEM
NNAPI memiliki operasi OEM dan jenis data OEM untuk memungkinkan produsen perangkat menyediakan fungsi khusus driver yang kustom. Jenis operasi dan data ini hanya digunakan oleh aplikasi OEM. Semantik operasi dan jenis data OEM bersifat khusus untuk OEM dan dapat berubah kapan saja. Jenis data dan operasi OEM dienkode menggunakan OperationType::OEM_OPERATION
, OperandType::OEM
, dan OperandType::TENSOR_OEM_BYTE
.