امتدادات البائعين

ملحقات موردي واجهة برمجة تطبيقات الشبكات العصبية (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 . التعيين من البادئة إلى اسم الامتداد عبارة عن مراسلات فردية (bijection) لنموذج معين. قد تتوافق قيم البادئات المختلفة مع نفس اسم الامتداد في نماذج مختلفة.

يجب أن يقوم برنامج التشغيل بالتحقق من صحة عمليات الامتداد وأنواع البيانات لأن وقت تشغيل NNAPI لا يمكنه التحقق من صحة عمليات الامتداد وأنواع البيانات المحددة.

يمكن أن تحتوي معاملات الامتداد على بيانات مرتبطة في operand.extraParams.extension ، والتي يعاملها وقت التشغيل كنقطة بيانات أولية ذات حجم عشوائي.

تشغيل OEM وأنواع البيانات

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