供應商額外資訊

Neural Networks API (NNAPI) 供應商擴充功能, Android 10, 一組供應商定義的作業和資料類型。在搭載 NN HAL 1.2 以上版本的裝置上,驅動程式可以支援相應的供應商擴充功能,提供自訂硬體加速作業。供應商額外資訊不會修改 現有作業的行為。

供應商擴充功能提供更有條理的替代方案,可取代已在 Android 10 中淘汰的 OEM 作業和資料類型。若需更多資訊,請參閲 原始設備製造商 (OEM) 作業和資料類型

擴充功能用量許可清單

供應商擴充功能只能由明確指定的 Android 應用程式和 /product/vendor/odm/data 分區上的原生二進位檔。 位於「/system」分區的應用程式和原生二進位檔無法使用廠商 。

/vendor/etc/nnapi_extensions_app_allowlist 會儲存可使用 NNAPI 供應商擴充功能的 Android 應用程式和二進位檔清單。檔案中的每一行都包含一個新項目。項目可以是前置字串為 斜線 (/),例如 /data/foo 或 Android 應用程式套件的名稱 例如:com.foo.bar

系統會強制執行 NNAPI 執行階段共用資料庫的許可清單。這個程式庫可防止意外使用,但無法防止應用程式刻意規避直接使用 NNAPI 驅動程式 HAL 介面。

供應商擴充功能定義

供應商會建立並維護含有擴充功能定義的標頭檔案。A 罩杯 您可前往以下網址,取得擴充功能定義的完整範例: example/fibonacci/FibonacciExtension.h

每個擴充功能的名稱都必須以反向網域名稱開頭 即可。

const char EXAMPLE_EXTENSION_NAME[] = "com.example.my_extension";

這個名稱會做為作業和資料類型的命名空間。NNAPI 會使用這個名稱來區分供應商擴充功能。

作業和資料類型的宣告方式與 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,
};

擴充功能作業可以使用任何運算元類型,包括非擴充功能運算元 類型,以及運算元型別。使用其他擴充功能的運算元項類型時,驅動程式必須支援該擴充功能。

擴充功能也可以宣告自訂結構,以便搭配擴充功能運算元。

/**
 * Quantization parameters for {@link EXAMPLE_TENSOR}.
 */
typedef struct ExampleTensorParams {
    double scale;
    int64_t zeroPoint;
} ExampleTensorParams;

在 NNAPI 用戶端中使用擴充功能

runtime/include/NeuralNetworksExtensions.h (C API) 檔案提供執行階段擴充功能支援。本節將介紹 C API 簡介

如要檢查裝置是否支援擴充功能,請使用 ANeuralNetworksDevice_getExtensionSupport

bool isExtensionSupported;
CHECK_EQ(ANeuralNetworksDevice_getExtensionSupport(device, EXAMPLE_EXTENSION_NAME,
                                                   &isExtensionSupported),
         ANEURALNETWORKS_NO_ERROR);
if (isExtensionSupported) {
    // The device supports the extension.
    ...
}

如要建構含有擴充運算元的模型,請使用 ANeuralNetworksModel_getExtensionOperandType 取得運算元類型,然後呼叫 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);

您可以選擇使用 ANeuralNetworksModel_setOperandExtensionData,將其他資料與擴充運算元建立關聯。

ExampleTensorParams params{
        .scale = 0.5,
        .zeroPoint = 128,
};
CHECK_EQ(ANeuralNetworksModel_setOperandExtensionData(model, operandIndex, &params, sizeof(params)),
         ANEURALNETWORKS_NO_ERROR);

如要建構具有擴充功能作業的模型,請使用 ANeuralNetworksModel_getExtensionOperationType 才能取得作業類型並呼叫 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);

為 NNAPI 驅動程式新增擴充功能支援

駕駛人會透過 IDevice::getSupportedExtensions 方法。傳回的清單必須包含描述每個支援擴充功能的項目。

Extension {
    .name = EXAMPLE_EXTENSION_NAME,
    .operandTypes = {
        {
            .type = EXAMPLE_SCALAR,
            .isTensor = false,
            .byteSize = 8,
        },
        {
            .type = EXAMPLE_TENSOR,
            .isTensor = true,
            .byteSize = 8,
        },
    },
}

在用於識別類型和運算的 32 位元中,高分 Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX 位元是副檔名 prefix 和 Low Model::ExtensionTypeEncoding::LOW_BITS_TYPE 位元代表類型或作業 。

處理作業或運算元類型時,驅動程式必須檢查擴充功能 前置字串。如果擴充內容前置字串的值不是零,代表作業或運算元 則是擴充功能類型如果值為 0,表示運算或運算元類型不是擴充功能類型。

如要將前置字串對應至擴充功能名稱,請前往 model.extensionNameToPrefix。 前置字串與擴充功能名稱的對應,是一對一通訊 (注射) 模型。不同前置字串值可能對應至不同型式的相同擴充功能名稱。

由於 NNAPI 執行階段無法驗證特定的擴充作業和資料類型,因此驅動程式必須驗證這些項目。

擴充功能運算元可在 operand.extraParams.extension、 執行階段會視為任意大小的原始資料 blob。

OEM 作業和資料類型

NNAPI 提供 OEM 作業和 OEM 資料類型,讓裝置製造商提供自訂的驅動程式專屬功能。這些運算和資料類型僅供原始設備製造商 (OEM) 應用程式使用。OEM 作業和資料類型的語意會因 OEM 而異,且隨時可能變更。OEM 作業和資料類型會使用 OperationType::OEM_OPERATIONOperandType::OEMOperandType::TENSOR_OEM_BYTE 編碼。