Satıcı uzantıları

Android 10'da kullanıma sunulan Neural Networks API (NNAPI) tedarikçi firma uzantıları, tedarikçi firma tarafından tanımlanan işlem ve veri türlerinden oluşan koleksiyonlardır. NN HAL 1.2 veya sonraki sürümleri çalıştıran cihazlarda sürücüler, ilgili tedarikçi firma uzantılarını destekleyerek donanım hızlandırmalı özel işlemler sağlayabilir. Tedarikçi firma uzantıları, mevcut işlemlerin davranışını değiştirmez.

Tedarikçi firma uzantıları, Android 10'da desteği sonlandırılan OEM işlem ve veri türlerine alternatif olarak daha yapılandırılmış bir alternatif sunar. Daha fazla bilgi için OEM işlem ve veri türleri bölümüne bakın.

Uzantı kullanımı izin verilenler listesi

Tedarikçi firma uzantıları yalnızca /product, /vendor, /odm ve /data bölümlerindeki açıkça belirtilen Android uygulamaları ve yerel ikili programlar tarafından kullanılabilir. /system bölümünde bulunan uygulamalar ve yerel ikili programlar tedarikçi firma uzantılarını kullanamaz.

NNAPI tedarikçi firma uzantılarını kullanmasına izin verilen Android uygulamalarının ve ikili programların bir listesi /vendor/etc/nnapi_extensions_app_allowlist içinde depolanır. Dosyanın her satırında yeni bir giriş bulunur. Giriş, önünde eğik çizgi (/) bulunan bir yerel ikili yol (ör. /data/foo) veya bir Android uygulama paketinin adı (ör. com.foo.bar) olabilir.

İzin verilenler listesi, NNAPI çalışma zamanı paylaşılan kitaplığından zorunlu kılını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ı bir şekilde boşluklardan yararlanmasına karşı koruma sağlamaz.

Tedarikçi firma uzantısı tanımı

Tedarikçi firma, uzantı tanımına sahip bir başlık dosyası oluşturur ve bu dosyayı sürdürür. Uzantı tanımının tam bir örneğini example/fibonacci/FibonacciExtension.h adresinde bulabilirsiniz.

Her uzantı, satıcının ters alan adıyla başlayan benzersiz bir ada sahip 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, tedarikçi firma uzantılarını birbirinden ayırt etmek için bu adı kullanır.

İşlemler ve veri türleri, runtime/include/NeuralNetworks.h'tekine benzer şekilde tanımlanır.

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 uzantı işlemi, uzantı olmayan işlem gören türleri ve diğer uzantılardaki işlem gören türleri dahil olmak üzere herhangi bir işlem gören türünü kullanabilir. Başka bir uzantıdan işlenen bir türü kullanırken sürücünün diğer uzantıyı desteklemesi gerekir.

Uzantılar, uzantı işlenenlerine eşlik edecek özel yapılar da tanımlayabilir.

/**
 * 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 işlevini 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şlenenine sahip bir model oluşturmak için ANeuralNetworksModel_getExtensionOperandType kullanarak işlem gören türünü alın ve ANeuralNetworksModel_addOperand çağrısı yapı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şlenenle 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şlemiyle bir model oluşturmak için ANeuralNetworksModel_getExtensionOperationType kullanarak işlem türünü alın ve ANeuralNetworksModel_addOperation çağrısı yapı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 üzerinden 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 bit arasından yüksek Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX bitleri uzantı ön eki, düşük Model::ExtensionTypeEncoding::LOW_BITS_TYPE bitleri ise uzantının türünü veya işlemini temsil eder.

Sürücü, bir işlemi veya işlenen türünü işlerken uzantı ön ekini kontrol etmelidir. Uzantı öneki sıfır dışında bir değere sahipse 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şlemek için model.extensionNameToPrefix içinde arayın. Ön ekten uzantı adına eşleme, belirli bir model için bire bir yazışmadır (bijeksiyon). Farklı önek değerleri, farklı modellerde aynı uzantı adına karşılık gelebilir.

NNAPI çalışma zamanı belirli uzantı işlemlerini ve veri türlerini doğrulayamadığından sürücü, uzantı işlemlerini ve veri türlerini doğrulamalıdır.

Uzantı işlenenleri, operand.extraParams.extension içinde ilişkili verilere sahip olabilir. Bu verileri, çalışma zamanı rastgele boyuttaki ham veri blobu olarak değerlendirir.

OEM çalışma ve veri türleri

NNAPI, cihaz üreticilerinin sürücüye özgü özel işlevler sunmasına olanak tanımak için bir OEM işlemine ve OEM veri türlerine sahiptir. Bu işlemler ve veri türleri yalnızca OEM uygulamaları tarafından kullanılır. OEM işleminin ve veri türlerinin anlamı, 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.