Google is committed to advancing racial equity for Black communities. See how.
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

供應商擴展

Android 10中引入的神經網絡API(NNAPI)供應商擴展是供應商定義的操作和數據類型的集合。在運行NN HAL 1.2或更高版本的設備上,驅動程序可以通過支持相應的供應商擴展來提供自定義的硬件加速操作。供應商擴展不會修改現有操作的行為。

供應商擴展提供了OEM操作和數據類型的更結構化的替代,而Android 10中已棄用。有關更多信息,請參閱OEM操作和數據類型

擴展程序使用許可列表

供應商擴展只能由/product/vendor/odm/data分區上明確指定的Android應用和本機二進製文件使用。 /system分區上的應用程序和本機二進製文件不能使用供應商擴展。

允許使用NNAPI供應商擴展的Android應用和二進製文件列表存儲在/vendor/etc/nnapi_extensions_app_allowlist 。文件的每一行都包含一個新條目。條目可以是帶有斜杠(/)的本機二進制路徑,例如/data/foo ,也可以是Android應用程序包的名稱,例如com.foo.bar

允許列表是從NNAPI運行時共享庫強制實施的。該庫可防止意外使用,但不能防止應用程序直接使用NNAPI驅動程序HAL接口進行故意規避。

供應商擴展定義

供應商創建並維護帶有擴展名定義的頭文件。擴展定義的完整示例可以在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位是擴展名前綴,低位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