Ekstensi vendor Neural Networks API (NNAPI), diperkenalkan di Android 10, kumpulan operasi yang ditentukan vendor dan tipe data. Di perangkat yang menjalankan NN HAL 1.2 atau lebih tinggi, {i>driver<i} dapat menyediakan operasi khusus yang dipercepat perangkat keras dengan yang mendukung ekstensi vendor yang sesuai. Ekstensi vendor tidak mengubah perilaku operasional yang ada.
Ekstensi vendor memberikan alternatif yang lebih terstruktur untuk operasi OEM dan tipe data yang tidak digunakan lagi di Android 10. Untuk informasi selengkapnya, lihat Jenis data dan operasi OEM.
Daftar penggunaan ekstensi yang diizinkan
Ekstensi vendor hanya dapat digunakan oleh aplikasi Android yang ditentukan secara eksplisit dan
biner native pada partisi /product
, /vendor
, /odm
, dan /data
.
Aplikasi dan biner native yang berada di partisi /system
tidak dapat menggunakan vendor
ekstensi.
Daftar aplikasi dan biner Android yang diizinkan untuk menggunakan ekstensi vendor NNAPI adalah
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, untuk
contoh, com.foo.bar
.
Daftar yang diizinkan diterapkan dari library bersama runtime NNAPI. Library ini melindungi dari penggunaan yang tidak disengaja tetapi tidak dari pengelakan yang disengaja dengan aplikasi secara langsung menggunakan antarmuka HAL driver NNAPI.
Definisi ekstensi vendor
Vendor membuat dan mengelola file header dengan definisi ekstensi. J
contoh lengkap dari definisi ekstensi dapat ditemukan di
example/fibonacci/FibonacciExtension.h
Setiap ekstensi harus memiliki nama unik yang diawali dengan nama domain terbalik dari vendor.
const char EXAMPLE_EXTENSION_NAME[] = "com.example.my_extension";
Nama berfungsi sebagai namespace untuk operasi dan jenis data. NNAPI menggunakan ini untuk membedakan di antara ekstensi vendor.
Operasi dan jenis data dideklarasikan dengan cara yang mirip 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 operand nonekstensi dan jenis operand dari ekstensi lain. Saat menggunakan jenis operand dari ekstensi lainnya, {i>driver<i} harus mendukung ekstensi lainnya.
Ekstensi juga dapat mendeklarasikan struktur kustom untuk menyertai operand ekstensi.
/**
* Quantization parameters for {@link EXAMPLE_TENSOR}.
*/
typedef struct ExampleTensorParams {
double scale;
int64_t zeroPoint;
} ExampleTensorParams;
Menggunakan ekstensi dalam klien NNAPI
Tujuan
runtime/include/NeuralNetworksExtensions.h
File (C API) menyediakan dukungan ekstensi runtime. Bagian ini menyediakan
tentang 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 membangun model dengan operand ekstensi, gunakan
ANeuralNetworksModel_getExtensionOperandType
untuk mendapatkan jenis operand dan memanggil
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);
Atau, gunakan
ANeuralNetworksModel_setOperandExtensionData
untuk mengaitkan data tambahan dengan operand ekstensi.
ExampleTensorParams params{
.scale = 0.5,
.zeroPoint = 128,
};
CHECK_EQ(ANeuralNetworksModel_setOperandExtensionData(model, operandIndex, ¶ms, sizeof(params)),
ANEURALNETWORKS_NO_ERROR);
Untuk mem-build 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
Pengemudi melaporkan ekstensi yang didukung melalui
IDevice::getSupportedExtensions
. Daftar yang ditampilkan harus berisi entri yang menjelaskan setiap elemen 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
tipe dan operasi, tingginya
Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX
bit adalah ekstensi
awalan dan nilai rendah
Model::ExtensionTypeEncoding::LOW_BITS_TYPE
bit mewakili jenis atau operasi
ekstensi.
Saat menangani jenis operasi atau operand, driver harus memeriksa ekstensi
. Jika awalan ekstensi memiliki nilai bukan nol, operasi atau operand
adalah jenis ekstensi. Jika nilainya 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 one-to-one
(bijeksi) untuk model tertentu. Nilai awalan yang berbeda mungkin sesuai dengan
nama ekstensi yang sama
di model yang berbeda.
Driver harus memvalidasi operasi ekstensi dan jenis data karena NNAPI runtime tidak dapat memvalidasi operasi ekstensi dan jenis data tertentu.
Operand ekstensi dapat memiliki data terkait di
operand.extraParams.extension
,
yang diperlakukan oleh runtime sebagai
blob data mentah dengan ukuran arbitrer.
Operasi dan jenis data OEM
NNAPI memiliki operasi OEM dan jenis data OEM yang memungkinkan
produsen perangkat untuk menyediakan
fungsi khusus bagi {i>driver<i}. Ini
operasi dan jenis data hanya
digunakan oleh aplikasi OEM. Semantik OEM
jenis data dan operasi bersifat khusus OEM dan dapat berubah kapan saja. OEM
operasi dan jenis data dienkode menggunakan OperationType::OEM_OPERATION
,
OperandType::OEM
, dan OperandType::TENSOR_OEM_BYTE
.