Satıcı uzantıları

Android 10'da tanıtılan Sinir Ağları API'si (NNAPI) satıcı uzantıları, satıcı tarafından tanımlanan işlemler ve veri türlerinin koleksiyonlarıdır. NN HAL 1.2 veya üstünü çalıştıran cihazlarda sürücüler, ilgili satıcı uzantılarını destekleyerek özel donanım hızlandırmalı işlemler sağlayabilir. Satıcı uzantıları mevcut operasyonların davranışını değiştirmez.

Satıcı uzantıları, Android 10'da kullanımdan kaldırılan OEM işlemine ve veri türlerine daha yapılandırılmış bir alternatif sağlar. Daha fazla bilgi için bkz. OEM işlemi ve veri türleri .

Uzantı kullanımına izin verilenler listesi

Satıcı uzantıları yalnızca /product , /vendor , /odm ve /data bölümlerinde açıkça belirtilen Android uygulamaları ve yerel ikili dosyalar tarafından kullanılabilir. /system bölümünde bulunan uygulamalar ve yerel ikili dosyalar, satıcı uzantılarını kullanamaz.

NNAPI satıcı uzantılarını kullanmasına izin verilen Android uygulamalarının ve ikili dosyalarının listesi /vendor/etc/nnapi_extensions_app_allowlist dosyasında saklanır. Dosyanın her satırı yeni bir giriş içerir. Bir giriş, önüne eğik çizgi (/) eklenmiş yerel bir ikili yol (örneğin, /data/foo ) veya bir Android uygulama paketinin adı (örneğin, com.foo.bar olabilir.

İzin verilenler listesi, NNAPI çalışma zamanı paylaşılan kitaplığından uygulanır. Bu kitaplık, yanlışlıkla kullanıma karşı koruma sağlar ancak doğrudan NNAPI sürücüsü HAL arayüzünü kullanan bir uygulamanın kasıtlı olarak atlamasına karşı koruma sağlamaz.

Satıcı uzantısı tanımı

Satıcı, uzantı tanımına sahip bir başlık dosyası oluşturur ve korur. Uzantı tanımının tam bir örneğini example/fibonacci/FibonacciExtension.h dosyasında bulabilirsiniz.

Her uzantının, satıcının ters alan adıyla başlayan benzersiz bir adı olmalıdır.

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

Ad, işlemler ve veri türleri için ad alanı görevi görür. NNAPI, satıcı uzantılarını ayırt etmek için bu adı kullanır.

İşlemler ve veri türleri runtime/include/NeuralNetworks.h dosyasındakilere benzer şekilde bildirilir.

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,
};

Bir genişletme işlemi, uzantı olmayan işlenen türleri ve diğer uzantılardan alınan işlenen türleri de dahil olmak üzere herhangi bir işlenen türünü kullanabilir. Başka bir uzantının işlenen türünü kullanırken, sürücünün diğer uzantıyı desteklemesi gerekir.

Uzantılar ayrıca uzantı işlenenlerine eşlik edecek özel yapılar da bildirebilir.

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

NNAPI istemcilerinde uzantıları kullanma

runtime/include/NeuralNetworksExtensions.h (C API) dosyası, çalışma zamanı uzantısı desteği sağlar. Bu bölümde C API'ye genel bir bakış sunulmaktadır.

Bir cihazın bir uzantıyı destekleyip desteklemediğini kontrol etmek için ANeuralNetworksDevice_getExtensionSupport kullanın.

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

Uzantı işleneniyle bir model oluşturmak için işlenen türünü elde etmek üzere ANeuralNetworksModel_getExtensionOperandType kullanın ve ANeuralNetworksModel_addOperand çağırın.

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);

İsteğe bağlı olarak, ek verileri bir uzantı işleneniyle ilişkilendirmek için ANeuralNetworksModel_setOperandExtensionData kullanın.

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

Uzantı işlemine sahip bir model oluşturmak için, işlem türünü elde etmek üzere ANeuralNetworksModel_getExtensionOperationType kullanın ve ANeuralNetworksModel_addOperation çağırın.

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 sürücüsüne uzantı desteği ekleme

Sürücüler desteklenen uzantıları IDevice::getSupportedExtensions yöntemi aracılığıyla bildirir. Döndürülen liste, desteklenen her uzantıyı açıklayan bir giriş içermelidir.

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

Türleri ve işlemleri tanımlamak için kullanılan 32 bitten yüksek Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX bitleri uzantı önekidir ve düşük Model::ExtensionTypeEncoding::LOW_BITS_TYPE bitleri uzantının türünü veya işlemini temsil eder.

Bir işlemi veya işlenen türünü işlerken sürücünün uzantı önekini kontrol etmesi gerekir. Uzantı önekinin sıfır dışında bir değeri varsa, işlem veya işlenen türü bir uzantı türüdür. Değer 0 ise işlem veya işlenen türü bir uzantı türü değildir.

Ön eki bir uzantı adıyla eşleştirmek için model.extensionNameToPrefix dosyasında arayın. Ön ekten uzantı adına eşleme, belirli bir model için bire bir yazışmadır (bijeksiyon). Farklı modellerde farklı önek değerleri aynı uzantı adına karşılık gelebilir.

NNAPI çalışma zamanı belirli uzantı işlemlerini ve veri türlerini doğrulayamadığı için sürücünün uzantı işlemlerini ve veri türlerini doğrulaması gerekir.

Uzantı işlenenleri, çalışma zamanının isteğe bağlı boyutta bir ham veri blobu olarak ele aldığı operand.extraParams.extension dosyasında ilişkili verilere sahip olabilir.

OEM işlemi ve veri türleri

NNAPI, cihaz üreticilerinin özel, sürücüye özgü işlevsellik sağlamasına olanak tanıyan bir OEM işlemine ve OEM veri türlerine sahiptir. Bu işlem ve veri türleri yalnızca OEM uygulamaları tarafından kullanılır. OEM işleminin ve veri türlerinin semantiği OEM'e özeldir ve herhangi bir zamanda değişebilir. OEM işlemi ve veri türleri OperationType::OEM_OPERATION , OperandType::OEM ve OperandType::TENSOR_OEM_BYTE kullanılarak kodlanır.