إضافات المورّدين

إضافات Neural Networks API (NNAPI) الخاصة بالمورّدين، والتي تم طرحها في الإصدار Android 10، هي مجموعات من العمليات وأنواع البيانات التي يحدّدها المورّد. على الأجهزة التي تعمل بـ NN HAL 1.2 أو إصدار أحدث، يمكن لبرامج التشغيل توفير عمليات مخصصة لتسريع الأجهزة من خلال دعم إضافات البائعين المقابلة. لا تعدّل إضافات المورّدين سلوك العمليات الحالية.

توفّر إضافات المورّدين بديلاً أكثر تنظيماً لعمليات المصنّعين الأصليين للأجهزة وأنواع البيانات التي تم إيقافها نهائيًا في Android 10. لمزيد من المعلومات، يُرجى الاطّلاع على مقالة عملية المصنّع الأصلي للجهاز وأنواع البيانات.

القائمة المسموح بها لاستخدام الإضافات

لا يمكن استخدام إضافات المورّدين إلا من خلال تطبيقات Android المحدّدة بوضوح وملفّات ثنائية برمجية أصلية على أقسام /product و/vendor و/odm و/data. لا يمكن للتطبيقات والبرامج الثنائية الأصلية المتوفرة في قسم /system استخدام المورِّد الإضافات.

يتم تخزين قائمة بتطبيقات Android والبرامج الثنائيّة المسموح لها باستخدام إضافات موفّري NNAPI في /vendor/etc/nnapi_extensions_app_allowlist. يحتوي كل سطر من الملف على إدخال جديد. يمكن أن يكون الإدخال مسارًا ثنائيًا أصليًا يبدأ بـ شرطة مائلة (/)، على سبيل المثال، /data/foo أو اسم حزمة تطبيق Android، على سبيل المثال، com.foo.bar.

يتم فرض القائمة المسموح بها من المكتبة المشتركة لوقت تشغيل NNAPI. توفِّر هذه المكتبة الحماية من الاستخدام غير المقصود، ولكن ليس من التحايل المتعمد من خلال تطبيق يستخدم واجهة HAL الخاصة ببرنامج تشغيل NNAPI مباشرةً.

تعريف إضافة المورّدين

ينشئ المورّد ملفًا للرأس مع تعريف الإضافة ويحافظ عليه. حاسمة يمكن العثور على مثال كامل لتعريف الإضافة في 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، التي يتعامل معها وقت التشغيل كمجموعة بيانات أولية بحجم عشوائي.

أنواع البيانات وعمليات المصنّع الأصلي للجهاز

تضم NNAPI عملية للمصنّع الأصلي للجهاز وأنواع بيانات المصنّع الأصلي للجهاز للسماح الشركات المصنعة للأجهزة إلى توفير وظائف مخصصة خاصة بالسائق. ولا يتم استخدام أنواع العمليات والبيانات هذه إلا من خلال تطبيقات المصنّعين الأصليّين للأجهزة. دلالات المصنّع الأصلي للجهاز والعمليات وأنواع البيانات الخاصة بالمُصنّع الأصلي ويمكن أن تتغير في أي وقت. المصنّع الأصلي للجهاز العملية وأنواع البيانات باستخدام OperationType::OEM_OPERATION، OperandType::OEM وOperandType::TENSOR_OEM_BYTE